2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 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
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSGeneric.cpp
39 #include "AFSCommon.h"
42 // Function: AFSExceptionFilter
46 // This function is the exception handler
50 // A status is returned for the function
54 AFSExceptionFilter( IN CHAR *FunctionString,
56 IN PEXCEPTION_POINTERS ExceptPtrs)
59 UNREFERENCED_PARAMETER(Code);
60 PEXCEPTION_RECORD ExceptRec;
66 ExceptRec = ExceptPtrs->ExceptionRecord;
68 Context = ExceptPtrs->ContextRecord;
72 "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
76 ExceptRec->ExceptionCode,
77 ExceptRec->ExceptionAddress,
78 (void *)AFSExceptionFilter);
80 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
82 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
83 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
85 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
87 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
90 KeBugCheck( (ULONG)-2);
98 __except( EXCEPTION_EXECUTE_HANDLER)
104 return EXCEPTION_EXECUTE_HANDLER;
108 // Function: AFSLibExAllocatePoolWithTag()
110 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
111 // is configured on, then bugcheck the system if
112 // a memory allocation fails. The routine should be
113 // used for all memory allocations that are to be freed
114 // when the library is unloaded. Memory allocations that
115 // are to survive library unload and reload should be
116 // performed using AFSExAllocatePoolWithTag() which is
117 // provided by the AFS Framework.
120 // POOL_TYPE PoolType - Paged or NonPaged
121 // SIZE_T NumberOfBytes - requested allocation size
122 // ULONG Tag - Pool Allocation Tag to be applied for tracking
125 // void * - the memory allocation
129 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
130 IN SIZE_T NumberOfBytes,
134 void *pBuffer = NULL;
136 pBuffer = ExAllocatePoolWithTag( PoolType,
143 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
146 KeBugCheck( (ULONG)-2);
153 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
157 PsGetCurrentThread());
167 // Function: AFSAcquireExcl()
169 // Purpose: Called to acquire a resource exclusive with optional wait
172 // PERESOURCE Resource - Resource to acquire
173 // BOOLEAN Wait - Whether to block
176 // BOOLEAN - Whether the mask was acquired
180 AFSAcquireExcl( IN PERESOURCE Resource,
184 BOOLEAN bStatus = FALSE;
187 // Normal kernel APCs must be disabled before calling
188 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
191 KeEnterCriticalRegion();
193 bStatus = ExAcquireResourceExclusiveLite( Resource,
199 KeLeaveCriticalRegion();
206 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
210 BOOLEAN bStatus = FALSE;
212 KeEnterCriticalRegion();
214 bStatus = ExAcquireSharedStarveExclusive( Resource,
220 KeLeaveCriticalRegion();
227 // Function: AFSAcquireShared()
229 // Purpose: Called to acquire a resource shared with optional wait
232 // PERESOURCE Resource - Resource to acquire
233 // BOOLEAN Wait - Whether to block
236 // BOOLEAN - Whether the mask was acquired
240 AFSAcquireShared( IN PERESOURCE Resource,
244 BOOLEAN bStatus = FALSE;
246 KeEnterCriticalRegion();
248 bStatus = ExAcquireResourceSharedLite( Resource,
254 KeLeaveCriticalRegion();
261 // Function: AFSReleaseResource()
263 // Purpose: Called to release a resource
266 // PERESOURCE Resource - Resource to release
273 AFSReleaseResource( IN PERESOURCE Resource)
276 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
277 AFS_TRACE_LEVEL_VERBOSE,
278 "AFSReleaseResource Releasing lock %p Thread %08lX\n",
280 PsGetCurrentThread());
282 ExReleaseResourceLite( Resource);
284 KeLeaveCriticalRegion();
290 AFSConvertToShared( IN PERESOURCE Resource)
293 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
294 AFS_TRACE_LEVEL_VERBOSE,
295 "AFSConvertToShared Converting lock %p Thread %08lX\n",
297 PsGetCurrentThread());
299 ExConvertExclusiveToSharedLite( Resource);
305 // Function: AFSCompleteRequest
309 // This function completes irps
313 // A status is returned for the function
317 AFSCompleteRequest( IN PIRP Irp,
321 Irp->IoStatus.Status = Status;
323 IoCompleteRequest( Irp,
330 // Function: AFSGenerateCRC
334 // Given a device and filename this function generates a CRC
338 // A status is returned for the function
342 AFSGenerateCRC( IN PUNICODE_STRING FileName,
343 IN BOOLEAN UpperCaseName)
347 NTSTATUS ntStatus = STATUS_SUCCESS;
349 ntStatus = RtlHashUnicodeString( FileName,
351 HASH_STRING_ALGORITHM_DEFAULT,
354 if( !NT_SUCCESS( ntStatus))
363 AFSLockSystemBuffer( IN PIRP Irp,
367 void *pAddress = NULL;
369 if( Irp->MdlAddress != NULL)
372 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
375 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
378 pAddress = Irp->AssociatedIrp.SystemBuffer;
380 else if( Irp->UserBuffer != NULL)
383 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
389 if( Irp->MdlAddress != NULL)
393 // Lock the new Mdl in memory.
398 PIO_STACK_LOCATION pIoStack;
399 pIoStack = IoGetCurrentIrpStackLocation( Irp);
402 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
403 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
405 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
408 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
411 AFSDumpTraceFilesFnc();
413 IoFreeMdl( Irp->MdlAddress );
414 Irp->MdlAddress = NULL;
424 AFSLockUserBuffer( IN void *UserBuffer,
425 IN ULONG BufferLength,
429 NTSTATUS ntStatus = STATUS_SUCCESS;
430 void *pAddress = NULL;
436 pMdl = IoAllocateMdl( UserBuffer,
445 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
449 // Lock the new Mdl in memory.
455 MmProbeAndLockPages( pMdl,
459 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
462 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
465 AFSDumpTraceFilesFnc();
487 AFSMapToService( IN PIRP Irp,
491 NTSTATUS ntStatus = STATUS_SUCCESS;
492 void *pMappedBuffer = NULL;
493 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
499 if( pDevExt->Specific.Control.ServiceProcess == NULL)
502 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
505 if( Irp->MdlAddress == NULL)
508 if( AFSLockSystemBuffer( Irp,
512 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
517 // Attach to the service process for mapping
520 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
521 (PRKAPC_STATE)&stApcState);
523 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
530 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
537 return pMappedBuffer;
541 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
545 NTSTATUS ntStatus = STATUS_SUCCESS;
546 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
552 if( pDevExt->Specific.Control.ServiceProcess == NULL)
555 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
562 // Attach to the service process for mapping
565 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
566 (PRKAPC_STATE)&stApcState);
568 MmUnmapLockedPages( MappedBuffer,
571 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
583 AFSInitializeLibraryDevice()
586 NTSTATUS ntStatus = STATUS_SUCCESS;
587 AFSDeviceExt *pDeviceExt = NULL;
592 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
595 // The PIOCtl file name
598 RtlInitUnicodeString( &AFSPIOCtlName,
599 AFS_PIOCTL_FILE_INTERFACE_NAME);
602 // And the global root share name
605 RtlInitUnicodeString( &AFSGlobalRootName,
606 AFS_GLOBAL_ROOT_SHARE_NAME);
614 AFSRemoveLibraryDevice()
617 NTSTATUS ntStatus = STATUS_SUCCESS;
628 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
632 UNREFERENCED_PARAMETER(DeviceObject);
633 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
635 AFSCompleteRequest( Irp,
642 AFSInitializeGlobalDirectoryEntries()
645 NTSTATUS ntStatus = STATUS_SUCCESS;
646 AFSDirectoryCB *pDirNode = NULL;
647 ULONG ulEntryLength = 0;
648 AFSObjectInfoCB *pObjectInfoCB = NULL;
649 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
656 // Initialize the global . entry
659 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
662 if( pObjectInfoCB == NULL)
665 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
666 AFS_TRACE_LEVEL_ERROR,
667 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
670 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
673 lCount = AFSObjectInfoIncrement( pObjectInfoCB);
675 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
676 AFS_TRACE_LEVEL_VERBOSE,
677 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
681 ntStatus = STATUS_SUCCESS;
683 ulEntryLength = sizeof( AFSDirectoryCB) +
686 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
690 if( pDirNode == NULL)
693 AFSDeleteObjectInfo( pObjectInfoCB);
695 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
696 AFS_TRACE_LEVEL_ERROR,
697 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
699 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
702 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
703 sizeof( AFSNonPagedDirectoryCB),
704 AFS_DIR_ENTRY_NP_TAG);
706 if( pNonPagedDirEntry == NULL)
709 ExFreePool( pDirNode);
711 AFSDeleteObjectInfo( pObjectInfoCB);
713 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
714 AFS_TRACE_LEVEL_ERROR,
715 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
717 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
720 RtlZeroMemory( pDirNode,
723 RtlZeroMemory( pNonPagedDirEntry,
724 sizeof( AFSNonPagedDirectoryCB));
726 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
728 pDirNode->NonPaged = pNonPagedDirEntry;
730 pDirNode->ObjectInformation = pObjectInfoCB;
736 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
738 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
741 // Setup the names in the entry
744 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
746 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
748 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
750 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
753 // Populate the rest of the data
756 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
758 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
760 AFSGlobalDotDirEntry = pDirNode;
766 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
769 if( pObjectInfoCB == NULL)
772 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
773 AFS_TRACE_LEVEL_ERROR,
774 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
777 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
780 lCount = AFSObjectInfoIncrement( pObjectInfoCB);
782 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
783 AFS_TRACE_LEVEL_VERBOSE,
784 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
788 ntStatus = STATUS_SUCCESS;
790 ulEntryLength = sizeof( AFSDirectoryCB) +
791 ( 2 * sizeof( WCHAR));
793 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
797 if( pDirNode == NULL)
800 AFSDeleteObjectInfo( pObjectInfoCB);
802 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
805 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
806 sizeof( AFSNonPagedDirectoryCB),
807 AFS_DIR_ENTRY_NP_TAG);
809 if( pNonPagedDirEntry == NULL)
812 ExFreePool( pDirNode);
814 AFSDeleteObjectInfo( pObjectInfoCB);
816 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
819 RtlZeroMemory( pDirNode,
822 RtlZeroMemory( pNonPagedDirEntry,
823 sizeof( AFSNonPagedDirectoryCB));
825 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
827 pDirNode->NonPaged = pNonPagedDirEntry;
829 pDirNode->ObjectInformation = pObjectInfoCB;
835 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
837 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
840 // Setup the names in the entry
843 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
845 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
847 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
849 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
851 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
854 // Populate the rest of the data
857 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
859 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
861 AFSGlobalDotDotDirEntry = pDirNode;
865 if( !NT_SUCCESS( ntStatus))
868 if( AFSGlobalDotDirEntry != NULL)
871 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
873 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
875 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
877 ExFreePool( AFSGlobalDotDirEntry);
879 AFSGlobalDotDirEntry = NULL;
882 if( AFSGlobalDotDotDirEntry != NULL)
885 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
887 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
889 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
891 ExFreePool( AFSGlobalDotDotDirEntry);
893 AFSGlobalDotDotDirEntry = NULL;
902 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
903 IN PUNICODE_STRING FileName,
904 IN PUNICODE_STRING TargetName,
905 IN AFSDirEnumEntry *DirEnumEntry,
909 AFSDirectoryCB *pDirNode = NULL;
910 NTSTATUS ntStatus = STATUS_SUCCESS;
911 ULONG ulEntryLength = 0;
912 AFSObjectInfoCB *pObjectInfoCB = NULL;
913 BOOLEAN bAllocatedObjectCB = FALSE;
914 ULONGLONG ullIndex = 0;
915 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
921 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
922 AFS_TRACE_LEVEL_VERBOSE,
923 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
925 ParentObjectInfo->FileId.Cell,
926 ParentObjectInfo->FileId.Volume,
927 ParentObjectInfo->FileId.Vnode,
928 ParentObjectInfo->FileId.Unique);
931 // First thing is to locate/create our object information block
935 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
938 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
940 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
942 (AFSBTreeEntry **)&pObjectInfoCB);
944 if( !NT_SUCCESS( ntStatus) ||
945 pObjectInfoCB == NULL)
949 // Allocate our object info cb
952 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
955 if( pObjectInfoCB == NULL)
958 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
960 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
963 bAllocatedObjectCB = TRUE;
965 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
966 AFS_TRACE_LEVEL_VERBOSE,
967 "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
973 lCount = AFSObjectInfoIncrement( pObjectInfoCB);
975 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
976 AFS_TRACE_LEVEL_VERBOSE,
977 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
981 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
983 ntStatus = STATUS_SUCCESS;
985 ulEntryLength = sizeof( AFSDirectoryCB) +
988 if( TargetName != NULL)
991 ulEntryLength += TargetName->Length;
994 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
998 if( pDirNode == NULL)
1001 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1004 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1005 sizeof( AFSNonPagedDirectoryCB),
1006 AFS_DIR_ENTRY_NP_TAG);
1008 if( pNonPagedDirEntry == NULL)
1011 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1014 RtlZeroMemory( pDirNode,
1017 RtlZeroMemory( pNonPagedDirEntry,
1018 sizeof( AFSNonPagedDirectoryCB));
1020 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1022 pDirNode->NonPaged = pNonPagedDirEntry;
1024 pDirNode->ObjectInformation = pObjectInfoCB;
1027 // Set valid entry and NOT_IN_PARENT flag
1030 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1032 pDirNode->FileIndex = FileIndex;
1035 // Setup the names in the entry
1038 if( FileName->Length > 0)
1041 pDirNode->NameInformation.FileName.Length = FileName->Length;
1043 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1045 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1047 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1049 pDirNode->NameInformation.FileName.Length);
1052 // Create a CRC for the file
1055 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1058 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1062 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1063 AFS_TRACE_LEVEL_VERBOSE,
1064 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1067 ParentObjectInfo->FileId.Cell,
1068 ParentObjectInfo->FileId.Volume,
1069 ParentObjectInfo->FileId.Vnode,
1070 ParentObjectInfo->FileId.Unique);
1072 if( TargetName != NULL &&
1073 TargetName->Length > 0)
1076 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1078 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1080 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1081 sizeof( AFSDirectoryCB) +
1082 pDirNode->NameInformation.FileName.Length);
1084 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1086 pDirNode->NameInformation.TargetName.Length);
1090 // If we allocated the object information cb then update the information
1093 if( bAllocatedObjectCB)
1097 // Populate the rest of the data
1100 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1102 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1104 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1106 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1108 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1110 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1112 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1114 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1116 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1118 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1120 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1123 pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1126 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1127 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1130 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1133 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1136 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1137 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1141 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1142 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1143 pObjectInfoCB->TargetFileId.Unique == 0 &&
1144 pDirNode->NameInformation.TargetName.Length == 0)
1148 // This will ensure we perform a validation on the node
1151 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1154 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1157 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1162 // Object specific information
1165 pObjectInfoCB->Links = DirEnumEntry->Links;
1167 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1169 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1173 if( !NT_SUCCESS( ntStatus))
1176 if( pNonPagedDirEntry != NULL)
1179 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1181 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1184 if( pDirNode != NULL)
1187 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1193 // Dereference our object info block if we have one
1196 if( pObjectInfoCB != NULL)
1199 lCount = AFSObjectInfoDecrement( pObjectInfoCB);
1201 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1202 AFS_TRACE_LEVEL_VERBOSE,
1203 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1207 if( bAllocatedObjectCB)
1210 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1212 AFSDeleteObjectInfo( pObjectInfoCB);
1222 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1223 IN BOOLEAN DirectoryEntry)
1226 BOOLEAN bReturn = TRUE;
1227 ACCESS_MASK stAccessMask = 0;
1230 // Get rid of anything we don't know about
1233 DesiredAccess = (DesiredAccess &
1239 ACCESS_SYSTEM_SECURITY |
1243 FILE_READ_ATTRIBUTES |
1244 FILE_WRITE_ATTRIBUTES |
1245 FILE_LIST_DIRECTORY |
1251 // Our 'read only' access mask. These are the accesses we will
1252 // allow for a read only file
1255 stAccessMask = DELETE |
1260 ACCESS_SYSTEM_SECURITY |
1264 FILE_READ_ATTRIBUTES |
1265 FILE_WRITE_ATTRIBUTES |
1267 FILE_LIST_DIRECTORY |
1271 // For a directory, add in the directory specific accesses
1277 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1282 if( FlagOn( DesiredAccess, ~stAccessMask))
1286 // A write access is set ...
1296 AFSEvaluateNode( IN GUID *AuthGroup,
1297 IN AFSDirectoryCB *DirEntry)
1300 NTSTATUS ntStatus = STATUS_SUCCESS;
1301 AFSDirEnumEntry *pDirEntry = NULL;
1302 UNICODE_STRING uniTargetName;
1307 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1312 if( !NT_SUCCESS( ntStatus))
1315 try_return( ntStatus);
1318 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1320 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1322 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1324 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1326 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1328 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1330 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1332 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1334 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1336 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1338 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1340 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1343 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1346 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1347 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1350 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1353 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1355 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1358 // If we have a target name then see if it needs updating ...
1361 if( pDirEntry->TargetNameLength > 0)
1365 // Update the target name information if needed
1368 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1370 uniTargetName.MaximumLength = uniTargetName.Length;
1372 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1374 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1377 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1378 RtlCompareUnicodeString( &uniTargetName,
1379 &DirEntry->NameInformation.TargetName,
1384 // Update the target name
1387 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1389 uniTargetName.Buffer,
1390 uniTargetName.Length);
1392 if( !NT_SUCCESS( ntStatus))
1395 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1397 try_return( ntStatus);
1401 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1406 if( pDirEntry != NULL)
1409 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1417 AFSValidateSymLink( IN GUID *AuthGroup,
1418 IN AFSDirectoryCB *DirEntry)
1421 NTSTATUS ntStatus = STATUS_SUCCESS;
1422 AFSDirEnumEntry *pDirEntry = NULL;
1423 UNICODE_STRING uniTargetName;
1428 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1433 if( !NT_SUCCESS( ntStatus))
1436 try_return( ntStatus);
1439 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1440 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1443 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1446 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1448 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1450 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1453 // Update the target name information if needed
1456 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1458 uniTargetName.MaximumLength = uniTargetName.Length;
1460 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1462 if( uniTargetName.Length > 0)
1465 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1468 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1469 RtlCompareUnicodeString( &uniTargetName,
1470 &DirEntry->NameInformation.TargetName,
1475 // Update the target name
1478 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1480 uniTargetName.Buffer,
1481 uniTargetName.Length);
1483 if( !NT_SUCCESS( ntStatus))
1486 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1488 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1492 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1496 // If the FileType is the same then nothing to do since it IS
1500 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1503 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1505 try_return( ntStatus = STATUS_SUCCESS);
1508 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1510 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1512 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1514 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1516 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1518 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1520 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1522 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1524 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1527 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1530 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1531 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1534 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1537 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1539 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1543 if( pDirEntry != NULL)
1546 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1554 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1558 NTSTATUS ntStatus = STATUS_SUCCESS;
1559 IO_STATUS_BLOCK stIoStatus;
1562 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1563 AFS_TRACE_LEVEL_VERBOSE,
1564 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1565 (*ppObjectInfo)->FileType,
1566 (*ppObjectInfo)->FileId.Cell,
1567 (*ppObjectInfo)->FileId.Volume,
1568 (*ppObjectInfo)->FileId.Vnode,
1569 (*ppObjectInfo)->FileId.Unique,
1572 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1573 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1574 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1577 // We only act on the mount point itself, not the target. If the
1578 // node has been deleted then mark it as such otherwise indicate
1579 // it requires verification
1582 if( Reason == AFS_INVALIDATE_DELETED)
1584 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1589 if( Reason == AFS_INVALIDATE_FLUSHED)
1592 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1594 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1597 (*ppObjectInfo)->Expiration.QuadPart = 0;
1599 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1601 (*ppObjectInfo)->TargetFileId.Unique = 0;
1603 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1604 AFS_TRACE_LEVEL_VERBOSE,
1605 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1606 (*ppObjectInfo)->FileId.Cell,
1607 (*ppObjectInfo)->FileId.Volume,
1608 (*ppObjectInfo)->FileId.Vnode,
1609 (*ppObjectInfo)->FileId.Unique);
1611 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1614 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1616 if( Reason == AFS_INVALIDATE_CREDS)
1618 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1621 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1622 Reason == AFS_INVALIDATE_FLUSHED)
1624 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1628 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1631 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1634 FILE_ACTION_MODIFIED);
1636 try_return( ntStatus);
1640 // Depending on the reason for invalidation then perform work on the node
1646 case AFS_INVALIDATE_DELETED:
1650 // Mark this node as invalid
1653 (*ppObjectInfo)->Links = 0;
1655 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1657 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1658 AFS_TRACE_LEVEL_VERBOSE,
1659 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1660 (*ppObjectInfo)->FileId.Cell,
1661 (*ppObjectInfo)->FileId.Volume,
1662 (*ppObjectInfo)->FileId.Vnode,
1663 (*ppObjectInfo)->FileId.Unique);
1665 if( (*ppObjectInfo)->ParentObjectInformation != NULL)
1668 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1669 AFS_TRACE_LEVEL_VERBOSE,
1670 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1671 (*ppObjectInfo)->ParentObjectInformation->FileId.Cell,
1672 (*ppObjectInfo)->ParentObjectInformation->FileId.Volume,
1673 (*ppObjectInfo)->ParentObjectInformation->FileId.Vnode,
1674 (*ppObjectInfo)->ParentObjectInformation->FileId.Unique);
1676 SetFlag( (*ppObjectInfo)->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1678 (*ppObjectInfo)->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1680 (*ppObjectInfo)->ParentObjectInformation->Expiration.QuadPart = 0;
1683 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1685 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1689 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1692 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1695 FILE_ACTION_REMOVED);
1697 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1700 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1706 case AFS_INVALIDATE_FLUSHED:
1709 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1710 (*ppObjectInfo)->Fcb != NULL)
1713 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1714 AFS_TRACE_LEVEL_VERBOSE,
1715 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1716 (*ppObjectInfo)->FileId.Cell,
1717 (*ppObjectInfo)->FileId.Volume,
1718 (*ppObjectInfo)->FileId.Vnode,
1719 (*ppObjectInfo)->FileId.Unique);
1721 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1727 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1732 if( !NT_SUCCESS( stIoStatus.Status))
1735 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1736 AFS_TRACE_LEVEL_ERROR,
1737 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1738 (*ppObjectInfo)->FileId.Cell,
1739 (*ppObjectInfo)->FileId.Volume,
1740 (*ppObjectInfo)->FileId.Vnode,
1741 (*ppObjectInfo)->FileId.Unique,
1743 stIoStatus.Information);
1745 ntStatus = stIoStatus.Status;
1749 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1752 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1758 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1759 AFS_TRACE_LEVEL_WARNING,
1760 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1761 (*ppObjectInfo)->FileId.Cell,
1762 (*ppObjectInfo)->FileId.Volume,
1763 (*ppObjectInfo)->FileId.Vnode,
1764 (*ppObjectInfo)->FileId.Unique);
1766 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1770 __except( EXCEPTION_EXECUTE_HANDLER)
1773 ntStatus = GetExceptionCode();
1777 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1778 (*ppObjectInfo)->FileId.Cell,
1779 (*ppObjectInfo)->FileId.Volume,
1780 (*ppObjectInfo)->FileId.Vnode,
1781 (*ppObjectInfo)->FileId.Unique,
1784 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1787 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1790 // Clear out the extents
1791 // Get rid of them (note this involves waiting
1792 // for any writes or reads to the cache to complete)
1795 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1799 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1802 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1805 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1806 AFS_TRACE_LEVEL_VERBOSE,
1807 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1808 (*ppObjectInfo)->FileId.Cell,
1809 (*ppObjectInfo)->FileId.Volume,
1810 (*ppObjectInfo)->FileId.Vnode,
1811 (*ppObjectInfo)->FileId.Unique);
1813 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1816 // Fall through to the default processing
1822 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1824 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1828 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1831 if( Reason == AFS_INVALIDATE_CREDS)
1833 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1836 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1838 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1842 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1845 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1848 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1851 FILE_ACTION_MODIFIED);
1856 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1859 FILE_ACTION_MODIFIED);
1863 // Indicate this node requires re-evaluation for the remaining reasons
1866 (*ppObjectInfo)->Expiration.QuadPart = 0;
1868 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1869 AFS_TRACE_LEVEL_VERBOSE,
1870 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1871 (*ppObjectInfo)->FileId.Cell,
1872 (*ppObjectInfo)->FileId.Volume,
1873 (*ppObjectInfo)->FileId.Vnode,
1874 (*ppObjectInfo)->FileId.Unique);
1876 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1878 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1879 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1880 ( Reason == AFS_INVALIDATE_CALLBACK ||
1881 Reason == AFS_INVALIDATE_EXPIRED))
1883 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1884 AFS_INVALIDATE_DATA_VERSION)))
1887 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1901 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1904 NTSTATUS ntStatus = STATUS_SUCCESS;
1905 AFSVolumeCB *pVolumeCB = NULL;
1906 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1907 ULONGLONG ullIndex = 0;
1908 AFSObjectInfoCB *pObjectInfo = NULL;
1914 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1915 AFS_TRACE_LEVEL_VERBOSE,
1916 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1917 InvalidateCB->FileID.Cell,
1918 InvalidateCB->FileID.Volume,
1919 InvalidateCB->FileID.Vnode,
1920 InvalidateCB->FileID.Unique,
1921 InvalidateCB->FileType,
1922 InvalidateCB->WholeVolume,
1923 InvalidateCB->Reason);
1926 // Need to locate the Fcb for the directory to purge
1929 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1930 AFS_TRACE_LEVEL_VERBOSE,
1931 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
1932 &pDevExt->Specific.RDR.VolumeTreeLock,
1933 PsGetCurrentThread());
1936 // Starve any exclusive waiters on this paticular call
1939 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1942 // Locate the volume node
1945 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1947 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1949 (AFSBTreeEntry **)&pVolumeCB);
1951 if( pVolumeCB != NULL)
1954 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1956 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1957 AFS_TRACE_LEVEL_VERBOSE,
1958 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
1963 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1965 if( !NT_SUCCESS( ntStatus) ||
1969 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1970 AFS_TRACE_LEVEL_WARNING,
1971 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1972 InvalidateCB->FileID.Cell,
1973 InvalidateCB->FileID.Volume,
1974 InvalidateCB->FileID.Vnode,
1975 InvalidateCB->FileID.Unique,
1978 try_return( ntStatus = STATUS_SUCCESS);
1982 // If this is a whole volume invalidation then go do it now
1985 if( InvalidateCB->WholeVolume)
1988 ntStatus = AFSInvalidateVolume( pVolumeCB,
1989 InvalidateCB->Reason);
1991 try_return( ntStatus);
1994 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1997 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2000 pObjectInfo = &pVolumeCB->ObjectInformation;
2005 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2007 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2009 (AFSBTreeEntry **)&pObjectInfo);
2012 if( pObjectInfo != NULL)
2016 // Reference the node so it won't be torn down
2019 lCount = AFSObjectInfoIncrement( pObjectInfo);
2021 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2022 AFS_TRACE_LEVEL_VERBOSE,
2023 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2028 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2030 if( !NT_SUCCESS( ntStatus) ||
2031 pObjectInfo == NULL)
2034 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2035 AFS_TRACE_LEVEL_VERBOSE,
2036 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2037 InvalidateCB->FileID.Cell,
2038 InvalidateCB->FileID.Volume,
2039 InvalidateCB->FileID.Vnode,
2040 InvalidateCB->FileID.Unique,
2043 try_return( ntStatus = STATUS_SUCCESS);
2046 AFSInvalidateObject( &pObjectInfo,
2047 InvalidateCB->Reason);
2051 if( pObjectInfo != NULL)
2054 lCount = AFSObjectInfoDecrement( pObjectInfo);
2056 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2057 AFS_TRACE_LEVEL_VERBOSE,
2058 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2063 if ( pVolumeCB != NULL)
2066 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2068 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2069 AFS_TRACE_LEVEL_VERBOSE,
2070 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2080 AFSIsChildOfParent( IN AFSFcb *Dcb,
2084 BOOLEAN bIsChild = FALSE;
2085 AFSFcb *pCurrentFcb = Fcb;
2087 while( pCurrentFcb != NULL)
2090 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2098 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2106 AFSCreateHighIndex( IN AFSFileID *FileID)
2109 ULONGLONG ullIndex = 0;
2111 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2118 AFSCreateLowIndex( IN AFSFileID *FileID)
2121 ULONGLONG ullIndex = 0;
2123 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2129 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2130 IN ACCESS_MASK GrantedAccess,
2131 IN BOOLEAN DirectoryEntry)
2134 BOOLEAN bAccessGranted = TRUE;
2137 // Check if we are asking for read/write and granted only read only
2138 // NOTE: There will be more checks here
2141 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2143 AFSCheckForReadOnlyAccess( GrantedAccess,
2147 bAccessGranted = FALSE;
2150 return bAccessGranted;
2154 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2157 NTSTATUS ntStatus = STATUS_SUCCESS;
2158 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2164 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2166 if( AFSGlobalRoot == NULL)
2173 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2176 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2183 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2190 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2191 IN UNICODE_STRING *SubstituteName,
2192 IN ULONG StringIndex)
2195 NTSTATUS ntStatus = STATUS_SUCCESS;
2196 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2197 AFSSysNameCB *pSysName = NULL;
2198 ERESOURCE *pSysNameLock = NULL;
2201 UNICODE_STRING uniSysName;
2208 if( IoIs32bitProcess( NULL))
2211 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2213 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2218 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2220 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2224 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2226 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2230 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2231 AFS_TRACE_LEVEL_VERBOSE,
2232 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2234 PsGetCurrentThread());
2236 AFSAcquireShared( pSysNameLock,
2240 // Find where we are in the list
2243 while( pSysName != NULL &&
2244 ulIndex < StringIndex)
2247 pSysName = pSysName->fLink;
2252 if( pSysName == NULL)
2255 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2258 RtlInitUnicodeString( &uniSysName,
2261 // If it is a full component of @SYS then just substitue the
2265 if( RtlCompareUnicodeString( &uniSysName,
2270 SubstituteName->Length = pSysName->SysName.Length;
2271 SubstituteName->MaximumLength = SubstituteName->Length;
2273 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2274 SubstituteName->Length,
2275 AFS_SUBST_BUFFER_TAG);
2277 if( SubstituteName->Buffer == NULL)
2280 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2283 RtlCopyMemory( SubstituteName->Buffer,
2284 pSysName->SysName.Buffer,
2285 pSysName->SysName.Length);
2292 while( ComponentName->Buffer[ usIndex] != L'@')
2298 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2299 SubstituteName->MaximumLength = SubstituteName->Length;
2301 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2302 SubstituteName->Length,
2303 AFS_SUBST_BUFFER_TAG);
2305 if( SubstituteName->Buffer == NULL)
2308 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2311 RtlCopyMemory( SubstituteName->Buffer,
2312 ComponentName->Buffer,
2313 usIndex * sizeof( WCHAR));
2315 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2316 pSysName->SysName.Buffer,
2317 pSysName->SysName.Length);
2322 AFSReleaseResource( pSysNameLock);
2329 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2330 IN OUT UNICODE_STRING *ComponentName,
2331 IN UNICODE_STRING *SubstituteName,
2332 IN OUT UNICODE_STRING *RemainingPath,
2333 IN BOOLEAN FreePathName)
2336 NTSTATUS ntStatus = STATUS_SUCCESS;
2337 UNICODE_STRING uniPathName;
2338 USHORT usPrefixNameLen = 0;
2339 SHORT sNameLenDelta = 0;
2345 // If the passed in name can handle the additional length
2346 // then just moves things around
2349 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2351 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2353 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2356 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2359 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2360 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2361 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2364 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2365 SubstituteName->Buffer,
2366 SubstituteName->Length);
2368 FullPathName->Length += sNameLenDelta;
2370 ComponentName->Length += sNameLenDelta;
2372 ComponentName->MaximumLength = ComponentName->Length;
2374 if ( RemainingPath->Buffer)
2377 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2380 try_return( ntStatus);
2384 // Need to re-allocate the buffer
2387 uniPathName.Length = FullPathName->Length -
2388 ComponentName->Length +
2389 SubstituteName->Length;
2391 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2393 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2394 uniPathName.MaximumLength,
2395 AFS_NAME_BUFFER_FOUR_TAG);
2397 if( uniPathName.Buffer == NULL)
2400 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2403 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2405 usPrefixNameLen *= sizeof( WCHAR);
2407 RtlZeroMemory( uniPathName.Buffer,
2408 uniPathName.MaximumLength);
2410 RtlCopyMemory( uniPathName.Buffer,
2411 FullPathName->Buffer,
2414 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2415 SubstituteName->Buffer,
2416 SubstituteName->Length);
2418 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2421 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2422 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2423 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2426 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2428 ComponentName->Length += sNameLenDelta;
2430 ComponentName->MaximumLength = ComponentName->Length;
2432 if ( RemainingPath->Buffer)
2435 RemainingPath->Buffer = uniPathName.Buffer
2436 + (RemainingPath->Buffer - FullPathName->Buffer)
2437 + sNameLenDelta/sizeof( WCHAR);
2442 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2445 *FullPathName = uniPathName;
2456 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2460 NTSTATUS ntStatus = STATUS_SUCCESS;
2461 AFSObjectInfoCB *pCurrentObject = NULL;
2462 AFSObjectInfoCB *pNextObject = NULL;
2468 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2469 AFS_TRACE_LEVEL_VERBOSE,
2470 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2471 VolumeCB->ObjectInformation.FileId.Cell,
2472 VolumeCB->ObjectInformation.FileId.Volume,
2473 VolumeCB->ObjectInformation.FileId.Vnode,
2474 VolumeCB->ObjectInformation.FileId.Unique,
2478 // Depending on the reason for invalidation then perform work on the node
2484 case AFS_INVALIDATE_DELETED:
2488 // Mark this volume as invalid
2491 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2493 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2500 // Invalidate the volume root directory
2503 pCurrentObject = &VolumeCB->ObjectInformation;
2505 if ( pCurrentObject )
2508 lCount = AFSObjectInfoIncrement( pCurrentObject);
2510 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2511 AFS_TRACE_LEVEL_VERBOSE,
2512 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2516 AFSInvalidateObject( &pCurrentObject,
2519 if ( pCurrentObject)
2522 lCount = AFSObjectInfoDecrement( pCurrentObject);
2524 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2525 AFS_TRACE_LEVEL_VERBOSE,
2526 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2533 // Apply invalidation to all other volume objects
2536 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2539 pCurrentObject = VolumeCB->ObjectInfoListHead;
2541 if ( pCurrentObject)
2545 // Reference the node so it won't be torn down
2548 lCount = AFSObjectInfoIncrement( pCurrentObject);
2550 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2551 AFS_TRACE_LEVEL_VERBOSE,
2552 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2557 while( pCurrentObject != NULL)
2560 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2566 // Reference the node so it won't be torn down
2569 lCount = AFSObjectInfoIncrement( pNextObject);
2571 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2572 AFS_TRACE_LEVEL_VERBOSE,
2573 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2578 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2580 AFSInvalidateObject( &pCurrentObject,
2583 if ( pCurrentObject )
2586 lCount = AFSObjectInfoDecrement( pCurrentObject);
2588 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2589 AFS_TRACE_LEVEL_VERBOSE,
2590 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2595 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2598 pCurrentObject = pNextObject;
2601 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2608 AFSInvalidateAllVolumes( VOID)
2610 AFSVolumeCB *pVolumeCB = NULL;
2611 AFSVolumeCB *pNextVolumeCB = NULL;
2612 AFSDeviceExt *pRDRDeviceExt = NULL;
2615 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2617 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2618 AFS_TRACE_LEVEL_VERBOSE,
2619 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2620 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2621 PsGetCurrentThread());
2623 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2626 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2631 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2632 AFS_TRACE_LEVEL_VERBOSE,
2633 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2634 pVolumeCB->ObjectInfoTree.TreeLock,
2635 PsGetCurrentThread());
2637 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
2639 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2640 AFS_TRACE_LEVEL_VERBOSE,
2641 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2646 while( pVolumeCB != NULL)
2649 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2654 lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
2656 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2657 AFS_TRACE_LEVEL_VERBOSE,
2658 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2663 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2665 // do I need to hold the volume lock here?
2667 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2669 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2672 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2674 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2675 AFS_TRACE_LEVEL_VERBOSE,
2676 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2680 pVolumeCB = pNextVolumeCB;
2683 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2687 AFSVerifyEntry( IN GUID *AuthGroup,
2688 IN AFSDirectoryCB *DirEntry)
2691 NTSTATUS ntStatus = STATUS_SUCCESS;
2692 AFSDirEnumEntry *pDirEnumEntry = NULL;
2693 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2694 IO_STATUS_BLOCK stIoStatus;
2699 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2700 AFS_TRACE_LEVEL_VERBOSE_2,
2701 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2702 &DirEntry->NameInformation.FileName,
2703 pObjectInfo->FileId.Cell,
2704 pObjectInfo->FileId.Volume,
2705 pObjectInfo->FileId.Vnode,
2706 pObjectInfo->FileId.Unique);
2708 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2713 if( !NT_SUCCESS( ntStatus))
2716 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2717 AFS_TRACE_LEVEL_ERROR,
2718 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2719 &DirEntry->NameInformation.FileName,
2720 pObjectInfo->FileId.Cell,
2721 pObjectInfo->FileId.Volume,
2722 pObjectInfo->FileId.Vnode,
2723 pObjectInfo->FileId.Unique,
2726 try_return( ntStatus);
2730 // Check the data version of the file
2733 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2735 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2738 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2739 AFS_TRACE_LEVEL_VERBOSE,
2740 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2741 pObjectInfo->DataVersion.QuadPart,
2742 &DirEntry->NameInformation.FileName,
2743 pObjectInfo->FileId.Cell,
2744 pObjectInfo->FileId.Volume,
2745 pObjectInfo->FileId.Vnode,
2746 pObjectInfo->FileId.Unique);
2749 // We are ok, just get out
2752 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2754 try_return( ntStatus = STATUS_SUCCESS);
2759 // New data version so we will need to process the node based on the type
2762 switch( pDirEnumEntry->FileType)
2765 case AFS_FILE_TYPE_MOUNTPOINT:
2769 // For a mount point we need to ensure the target is the same
2772 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2773 &pDirEnumEntry->TargetFileId))
2779 // Update the metadata for the entry
2782 ntStatus = AFSUpdateMetaData( DirEntry,
2785 if( NT_SUCCESS( ntStatus))
2788 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2794 case AFS_FILE_TYPE_SYMLINK:
2798 // Update the metadata for the entry
2801 ntStatus = AFSUpdateMetaData( DirEntry,
2804 if( NT_SUCCESS( ntStatus))
2807 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2813 case AFS_FILE_TYPE_FILE:
2815 FILE_OBJECT * pCCFileObject = NULL;
2816 BOOLEAN bPurgeExtents = FALSE;
2818 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
2821 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2822 AFS_TRACE_LEVEL_VERBOSE,
2823 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
2824 &DirEntry->NameInformation.FileName,
2825 pObjectInfo->FileId.Cell,
2826 pObjectInfo->FileId.Volume,
2827 pObjectInfo->FileId.Vnode,
2828 pObjectInfo->FileId.Unique,
2829 pObjectInfo->DataVersion.LowPart,
2830 pDirEnumEntry->DataVersion.LowPart
2833 bPurgeExtents = TRUE;
2836 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2839 bPurgeExtents = TRUE;
2841 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2842 AFS_TRACE_LEVEL_VERBOSE,
2843 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2844 &DirEntry->NameInformation.FileName,
2845 pObjectInfo->FileId.Cell,
2846 pObjectInfo->FileId.Volume,
2847 pObjectInfo->FileId.Vnode,
2848 pObjectInfo->FileId.Unique);
2850 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2853 if( pObjectInfo->Fcb != NULL)
2856 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2857 AFS_TRACE_LEVEL_VERBOSE,
2858 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2859 &DirEntry->NameInformation.FileName,
2860 pObjectInfo->FileId.Cell,
2861 pObjectInfo->FileId.Volume,
2862 pObjectInfo->FileId.Vnode,
2863 pObjectInfo->FileId.Unique);
2865 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2871 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2876 if( !NT_SUCCESS( stIoStatus.Status))
2879 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2880 AFS_TRACE_LEVEL_ERROR,
2881 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2882 &DirEntry->NameInformation.FileName,
2883 pObjectInfo->FileId.Cell,
2884 pObjectInfo->FileId.Volume,
2885 pObjectInfo->FileId.Vnode,
2886 pObjectInfo->FileId.Unique,
2888 stIoStatus.Information);
2890 ntStatus = stIoStatus.Status;
2893 if ( bPurgeExtents &&
2894 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2897 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2903 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2904 AFS_TRACE_LEVEL_WARNING,
2905 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2906 &DirEntry->NameInformation.FileName,
2907 pObjectInfo->FileId.Cell,
2908 pObjectInfo->FileId.Volume,
2909 pObjectInfo->FileId.Vnode,
2910 pObjectInfo->FileId.Unique);
2912 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2916 __except( EXCEPTION_EXECUTE_HANDLER)
2918 ntStatus = GetExceptionCode();
2922 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2923 &DirEntry->NameInformation.FileName,
2924 pObjectInfo->FileId.Cell,
2925 pObjectInfo->FileId.Volume,
2926 pObjectInfo->FileId.Vnode,
2927 pObjectInfo->FileId.Unique,
2930 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2933 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
2937 AFSFlushExtents( pObjectInfo->Fcb,
2942 // Reacquire the Fcb to purge the cache
2945 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2946 AFS_TRACE_LEVEL_VERBOSE,
2947 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
2948 &pObjectInfo->Fcb->NPFcb->Resource,
2949 PsGetCurrentThread());
2951 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2955 // Update the metadata for the entry
2958 ntStatus = AFSUpdateMetaData( DirEntry,
2961 if( !NT_SUCCESS( ntStatus))
2964 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2965 AFS_TRACE_LEVEL_ERROR,
2966 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2967 &DirEntry->NameInformation.FileName,
2968 pObjectInfo->FileId.Cell,
2969 pObjectInfo->FileId.Volume,
2970 pObjectInfo->FileId.Vnode,
2971 pObjectInfo->FileId.Unique,
2978 // Update file sizes
2981 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2982 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2983 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2985 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2986 AFS_TRACE_LEVEL_VERBOSE,
2987 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2988 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2989 PsGetCurrentThread());
2991 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2994 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2996 if ( pCCFileObject != NULL)
2998 CcSetFileSizes( pCCFileObject,
2999 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3002 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3003 AFS_TRACE_LEVEL_VERBOSE,
3004 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3005 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3006 PsGetCurrentThread());
3008 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3010 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3016 // Update the metadata for the entry
3019 ntStatus = AFSUpdateMetaData( DirEntry,
3022 if( !NT_SUCCESS( ntStatus))
3025 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3026 AFS_TRACE_LEVEL_ERROR,
3027 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3028 &DirEntry->NameInformation.FileName,
3029 pObjectInfo->FileId.Cell,
3030 pObjectInfo->FileId.Volume,
3031 pObjectInfo->FileId.Vnode,
3032 pObjectInfo->FileId.Unique,
3038 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3039 AFS_TRACE_LEVEL_WARNING,
3040 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3041 &DirEntry->NameInformation.FileName,
3042 pObjectInfo->FileId.Cell,
3043 pObjectInfo->FileId.Volume,
3044 pObjectInfo->FileId.Vnode,
3045 pObjectInfo->FileId.Unique);
3048 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3053 case AFS_FILE_TYPE_DIRECTORY:
3057 // For a directory or root entry flush the content of
3058 // the directory enumeration.
3061 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3064 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3065 AFS_TRACE_LEVEL_VERBOSE_2,
3066 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3067 &DirEntry->NameInformation.FileName,
3068 pObjectInfo->FileId.Cell,
3069 pObjectInfo->FileId.Volume,
3070 pObjectInfo->FileId.Vnode,
3071 pObjectInfo->FileId.Unique);
3073 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3076 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3079 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3081 if ( !NT_SUCCESS( ntStatus))
3084 try_return( ntStatus);
3089 // Update the metadata for the entry
3092 ntStatus = AFSUpdateMetaData( DirEntry,
3095 if( NT_SUCCESS( ntStatus))
3098 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3104 case AFS_FILE_TYPE_DFSLINK:
3107 UNICODE_STRING uniTargetName;
3110 // For a DFS link need to check the target name has not changed
3113 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3115 uniTargetName.MaximumLength = uniTargetName.Length;
3117 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3119 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3122 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3123 RtlCompareUnicodeString( &uniTargetName,
3124 &DirEntry->NameInformation.TargetName,
3129 // Update the target name
3132 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3134 uniTargetName.Buffer,
3135 uniTargetName.Length);
3137 if( !NT_SUCCESS( ntStatus))
3140 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3146 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3149 // Update the metadata for the entry
3152 ntStatus = AFSUpdateMetaData( DirEntry,
3155 if( NT_SUCCESS( ntStatus))
3158 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3166 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3167 AFS_TRACE_LEVEL_WARNING,
3168 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3169 pObjectInfo->FileType,
3170 &DirEntry->NameInformation.FileName,
3171 pObjectInfo->FileId.Cell,
3172 pObjectInfo->FileId.Volume,
3173 pObjectInfo->FileId.Vnode,
3174 pObjectInfo->FileId.Unique);
3181 if( pDirEnumEntry != NULL)
3184 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3192 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3195 NTSTATUS ntStatus = STATUS_SUCCESS;
3196 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3197 ULONGLONG ullIndex = 0;
3198 AFSVolumeCB *pVolumeCB = NULL;
3204 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3205 AFS_TRACE_LEVEL_VERBOSE,
3206 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3207 VolumeStatus->Online,
3208 VolumeStatus->FileID.Cell,
3209 VolumeStatus->FileID.Volume);
3212 // Need to locate the Fcb for the directory to purge
3215 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3216 AFS_TRACE_LEVEL_VERBOSE,
3217 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3218 &pDevExt->Specific.RDR.VolumeTreeLock,
3219 PsGetCurrentThread());
3221 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3224 // Locate the volume node
3227 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3229 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3231 (AFSBTreeEntry **)&pVolumeCB);
3233 if( pVolumeCB != NULL)
3236 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3238 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3239 AFS_TRACE_LEVEL_VERBOSE,
3240 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3244 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3247 // Set the volume state accordingly
3250 if( VolumeStatus->Online)
3253 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3258 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3267 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3270 NTSTATUS ntStatus = STATUS_SUCCESS;
3275 if( AFSGlobalRoot == NULL)
3278 try_return( ntStatus);
3281 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3285 // Set the network state according to the information
3288 if( NetworkStatus->Online)
3291 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3296 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3299 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3310 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3314 NTSTATUS ntStatus = STATUS_SUCCESS;
3315 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3316 BOOLEAN bAcquiredLock = FALSE;
3317 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3322 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3323 AFS_TRACE_LEVEL_VERBOSE,
3324 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3325 ObjectInfo->FileId.Cell,
3326 ObjectInfo->FileId.Volume,
3327 ObjectInfo->FileId.Vnode,
3328 ObjectInfo->FileId.Unique);
3330 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3333 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3334 AFS_TRACE_LEVEL_VERBOSE,
3335 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3336 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3337 PsGetCurrentThread());
3339 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3342 bAcquiredLock = TRUE;
3346 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3349 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3350 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3353 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3354 AFS_TRACE_LEVEL_ERROR,
3355 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3356 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3357 ObjectInfo->FileId.Cell,
3358 ObjectInfo->FileId.Volume,
3359 ObjectInfo->FileId.Vnode,
3360 ObjectInfo->FileId.Unique);
3364 // Reset the directory list information by clearing all valid entries
3367 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3369 while( pCurrentDirEntry != NULL)
3372 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3374 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3378 // If this entry has been deleted then process it here
3381 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3382 pCurrentDirEntry->DirOpenReferenceCount <= 0)
3385 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3386 AFS_TRACE_LEVEL_VERBOSE,
3387 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3389 &pCurrentDirEntry->NameInformation.FileName);
3391 AFSDeleteDirEntry( ObjectInfo,
3397 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3399 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3400 AFS_TRACE_LEVEL_VERBOSE,
3401 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3403 pCurrentDirEntry->DirOpenReferenceCount);
3406 // We pull the short name from the parent tree since it could change below
3409 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3412 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3413 AFS_TRACE_LEVEL_VERBOSE,
3414 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3416 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3417 &pCurrentDirEntry->NameInformation.FileName);
3419 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3422 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3427 pCurrentDirEntry = pNextDirEntry;
3431 // Reget the directory contents
3434 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3437 if ( !NT_SUCCESS( ntStatus))
3439 try_return( ntStatus);
3443 // Now start again and tear down any entries not valid
3446 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3448 while( pCurrentDirEntry != NULL)
3451 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3453 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3456 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3457 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3458 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3461 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3464 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3466 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3467 AFS_TRACE_LEVEL_VERBOSE,
3468 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3470 &pCurrentDirEntry->NameInformation.FileName);
3472 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3477 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3480 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3481 AFS_TRACE_LEVEL_VERBOSE,
3482 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3484 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3485 &pCurrentDirEntry->NameInformation.FileName);
3489 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3491 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3492 AFS_TRACE_LEVEL_VERBOSE,
3493 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3495 &pCurrentDirEntry->NameInformation.FileName);
3500 pCurrentDirEntry = pNextDirEntry;
3505 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3506 AFS_TRACE_LEVEL_VERBOSE,
3507 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3509 pCurrentDirEntry->DirOpenReferenceCount);
3511 if( pCurrentDirEntry->DirOpenReferenceCount <= 0)
3514 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3515 AFS_TRACE_LEVEL_VERBOSE,
3516 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3517 &pCurrentDirEntry->NameInformation.FileName,
3518 ObjectInfo->FileId.Cell,
3519 ObjectInfo->FileId.Volume,
3520 ObjectInfo->FileId.Vnode,
3521 ObjectInfo->FileId.Unique);
3523 AFSDeleteDirEntry( ObjectInfo,
3529 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3530 AFS_TRACE_LEVEL_VERBOSE,
3531 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3533 &pCurrentDirEntry->NameInformation.FileName,
3534 ObjectInfo->FileId.Cell,
3535 ObjectInfo->FileId.Volume,
3536 ObjectInfo->FileId.Vnode,
3537 ObjectInfo->FileId.Unique);
3539 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3541 AFSRemoveNameEntry( ObjectInfo,
3545 pCurrentDirEntry = pNextDirEntry;
3549 if( !AFSValidateDirList( ObjectInfo))
3552 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3561 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3569 AFSIsVolumeFID( IN AFSFileID *FileID)
3572 BOOLEAN bIsVolume = FALSE;
3574 if( FileID->Vnode == 1 &&
3575 FileID->Unique == 1)
3585 AFSIsFinalNode( IN AFSFcb *Fcb)
3588 BOOLEAN bIsFinalNode = FALSE;
3590 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3591 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3592 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3593 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3594 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3597 bIsFinalNode = TRUE;
3602 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3603 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3606 return bIsFinalNode;
3610 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3611 IN AFSDirEnumEntry *DirEnumEntry)
3614 NTSTATUS ntStatus = STATUS_SUCCESS;
3615 UNICODE_STRING uniTargetName;
3616 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3621 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3623 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3625 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3627 pObjectInfo->FileType = DirEnumEntry->FileType;
3629 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3631 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3633 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3635 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3637 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3639 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3641 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3643 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3646 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3649 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3650 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3653 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3656 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3658 pObjectInfo->Links = DirEnumEntry->Links;
3660 if( DirEnumEntry->TargetNameLength > 0 &&
3661 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3662 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3666 // Update the target name information if needed
3669 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3671 uniTargetName.MaximumLength = uniTargetName.Length;
3673 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3675 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3678 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3679 RtlCompareUnicodeString( &uniTargetName,
3680 &DirEntry->NameInformation.TargetName,
3685 // Update the target name
3688 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3690 uniTargetName.Buffer,
3691 uniTargetName.Length);
3693 if( !NT_SUCCESS( ntStatus))
3696 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3698 try_return( ntStatus);
3702 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3704 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3705 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3708 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3711 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3712 DirEntry->NameInformation.TargetName.Buffer != NULL)
3714 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3717 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3719 DirEntry->NameInformation.TargetName.Length = 0;
3720 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3721 DirEntry->NameInformation.TargetName.Buffer = NULL;
3723 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3735 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3737 IN BOOLEAN FastCall,
3738 IN BOOLEAN bSafeToPurge)
3741 NTSTATUS ntStatus = STATUS_SUCCESS;
3742 LARGE_INTEGER liSystemTime;
3743 AFSDirEnumEntry *pDirEnumEntry = NULL;
3744 AFSFcb *pCurrentFcb = NULL;
3745 BOOLEAN bReleaseFcb = FALSE;
3746 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3752 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3756 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3757 AFS_TRACE_LEVEL_VERBOSE_2,
3758 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3759 &DirEntry->NameInformation.FileName,
3760 pObjectInfo->FileId.Cell,
3761 pObjectInfo->FileId.Volume,
3762 pObjectInfo->FileId.Vnode,
3763 pObjectInfo->FileId.Unique,
3767 // If this is a fake node then bail since the service knows nothing about it
3770 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3773 try_return( ntStatus);
3777 // This routine ensures that the current entry is valid by:
3779 // 1) Checking that the expiration time is non-zero and after where we
3783 KeQuerySystemTime( &liSystemTime);
3785 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3786 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3787 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3788 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3791 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3792 AFS_TRACE_LEVEL_VERBOSE_2,
3793 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3794 &DirEntry->NameInformation.FileName,
3795 pObjectInfo->FileId.Cell,
3796 pObjectInfo->FileId.Volume,
3797 pObjectInfo->FileId.Vnode,
3798 pObjectInfo->FileId.Unique);
3800 try_return( ntStatus);
3804 // This node requires updating
3807 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3812 if( !NT_SUCCESS( ntStatus))
3815 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3816 AFS_TRACE_LEVEL_ERROR,
3817 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3819 &DirEntry->NameInformation.FileName,
3820 pObjectInfo->FileId.Cell,
3821 pObjectInfo->FileId.Volume,
3822 pObjectInfo->FileId.Vnode,
3823 pObjectInfo->FileId.Unique,
3827 // Failed validation of node so return access-denied
3830 try_return( ntStatus);
3833 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3834 AFS_TRACE_LEVEL_VERBOSE,
3835 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3837 &DirEntry->NameInformation.FileName,
3838 pObjectInfo->FileId.Cell,
3839 pObjectInfo->FileId.Volume,
3840 pObjectInfo->FileId.Vnode,
3841 pObjectInfo->FileId.Unique,
3842 pObjectInfo->DataVersion.QuadPart,
3843 pDirEnumEntry->DataVersion.QuadPart,
3844 pDirEnumEntry->FileType);
3848 // Based on the file type, process the node
3851 switch( pDirEnumEntry->FileType)
3854 case AFS_FILE_TYPE_MOUNTPOINT:
3858 // Update the metadata for the entry
3861 ntStatus = AFSUpdateMetaData( DirEntry,
3864 if( NT_SUCCESS( ntStatus))
3867 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3873 case AFS_FILE_TYPE_SYMLINK:
3874 case AFS_FILE_TYPE_DFSLINK:
3878 // Update the metadata for the entry
3881 ntStatus = AFSUpdateMetaData( DirEntry,
3884 if( NT_SUCCESS( ntStatus))
3887 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3893 case AFS_FILE_TYPE_FILE:
3896 BOOLEAN bPurgeExtents = FALSE;
3899 // For a file where the data version has become invalid we need to
3900 // fail any current extent requests and purge the cache for the file
3901 // Can't hold the Fcb resource while doing this
3904 if( pObjectInfo->Fcb != NULL &&
3905 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3906 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3909 pCurrentFcb = pObjectInfo->Fcb;
3911 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3914 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3915 AFS_TRACE_LEVEL_VERBOSE,
3916 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
3917 &pCurrentFcb->NPFcb->Resource,
3918 PsGetCurrentThread());
3920 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3926 if( pCurrentFcb != NULL)
3929 IO_STATUS_BLOCK stIoStatus;
3931 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3932 AFS_TRACE_LEVEL_VERBOSE_2,
3933 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3934 &DirEntry->NameInformation.FileName,
3935 pObjectInfo->FileId.Cell,
3936 pObjectInfo->FileId.Volume,
3937 pObjectInfo->FileId.Vnode,
3938 pObjectInfo->FileId.Unique);
3940 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3943 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3944 AFS_TRACE_LEVEL_VERBOSE,
3945 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
3946 &DirEntry->NameInformation.FileName,
3947 pObjectInfo->FileId.Cell,
3948 pObjectInfo->FileId.Volume,
3949 pObjectInfo->FileId.Vnode,
3950 pObjectInfo->FileId.Unique,
3951 pObjectInfo->DataVersion.LowPart,
3952 pDirEnumEntry->DataVersion.LowPart
3955 bPurgeExtents = TRUE;
3961 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3963 bPurgeExtents = TRUE;
3965 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3966 AFS_TRACE_LEVEL_VERBOSE,
3967 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3968 &DirEntry->NameInformation.FileName,
3969 pObjectInfo->FileId.Cell,
3970 pObjectInfo->FileId.Volume,
3971 pObjectInfo->FileId.Vnode,
3972 pObjectInfo->FileId.Unique);
3974 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3977 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3978 AFS_TRACE_LEVEL_VERBOSE,
3979 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3980 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3981 PsGetCurrentThread());
3983 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3987 // Release Fcb->Resource to avoid Trend Micro deadlock
3990 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3995 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4000 if( !NT_SUCCESS( stIoStatus.Status))
4003 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4004 AFS_TRACE_LEVEL_ERROR,
4005 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4006 &DirEntry->NameInformation.FileName,
4007 pObjectInfo->FileId.Cell,
4008 pObjectInfo->FileId.Volume,
4009 pObjectInfo->FileId.Vnode,
4010 pObjectInfo->FileId.Unique,
4012 stIoStatus.Information);
4014 ntStatus = stIoStatus.Status;
4017 if ( bPurgeExtents &&
4018 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4021 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4027 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4028 AFS_TRACE_LEVEL_WARNING,
4029 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4030 &DirEntry->NameInformation.FileName,
4031 pObjectInfo->FileId.Cell,
4032 pObjectInfo->FileId.Volume,
4033 pObjectInfo->FileId.Vnode,
4034 pObjectInfo->FileId.Unique);
4036 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4040 __except( EXCEPTION_EXECUTE_HANDLER)
4042 ntStatus = GetExceptionCode();
4046 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4047 &DirEntry->NameInformation.FileName,
4048 pObjectInfo->FileId.Cell,
4049 pObjectInfo->FileId.Volume,
4050 pObjectInfo->FileId.Vnode,
4051 pObjectInfo->FileId.Unique,
4054 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4057 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4058 AFS_TRACE_LEVEL_VERBOSE,
4059 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4060 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4061 PsGetCurrentThread());
4063 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4065 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4074 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4079 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4081 bReleaseFcb = FALSE;
4083 if ( bPurgeExtents &&
4086 AFSFlushExtents( pCurrentFcb,
4093 // Update the metadata for the entry but only if it is safe to do so.
4094 // If it was determined that a data version change has occurred or
4095 // that a pending data verification was required, do not update the
4096 // ObjectInfo meta data or the FileObject size information. That
4097 // way it is consistent for the next time that the data is verified
4101 if ( !(bPurgeExtents && bSafeToPurge))
4104 ntStatus = AFSUpdateMetaData( DirEntry,
4107 if( !NT_SUCCESS( ntStatus))
4110 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4111 AFS_TRACE_LEVEL_ERROR,
4112 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4113 &DirEntry->NameInformation.FileName,
4114 pObjectInfo->FileId.Cell,
4115 pObjectInfo->FileId.Volume,
4116 pObjectInfo->FileId.Vnode,
4117 pObjectInfo->FileId.Unique,
4123 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4126 // Update file sizes
4129 if( pObjectInfo->Fcb != NULL)
4131 FILE_OBJECT *pCCFileObject;
4133 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4134 AFS_TRACE_LEVEL_VERBOSE,
4135 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4136 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4137 PsGetCurrentThread());
4139 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4142 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4144 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4145 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4146 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4148 if ( pCCFileObject != NULL)
4150 CcSetFileSizes( pCCFileObject,
4151 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4154 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4155 AFS_TRACE_LEVEL_VERBOSE,
4156 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4157 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4158 PsGetCurrentThread());
4160 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4166 case AFS_FILE_TYPE_DIRECTORY:
4169 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4173 // For a directory or root entry flush the content of
4174 // the directory enumeration.
4177 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4178 AFS_TRACE_LEVEL_VERBOSE,
4179 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4180 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4181 PsGetCurrentThread());
4183 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4186 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4187 AFS_TRACE_LEVEL_VERBOSE_2,
4188 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4189 &DirEntry->NameInformation.FileName,
4190 pObjectInfo->FileId.Cell,
4191 pObjectInfo->FileId.Volume,
4192 pObjectInfo->FileId.Vnode,
4193 pObjectInfo->FileId.Unique);
4195 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4198 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4201 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4204 if( !NT_SUCCESS( ntStatus))
4207 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4208 AFS_TRACE_LEVEL_ERROR,
4209 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4210 &DirEntry->NameInformation.FileName,
4211 pObjectInfo->FileId.Cell,
4212 pObjectInfo->FileId.Volume,
4213 pObjectInfo->FileId.Vnode,
4214 pObjectInfo->FileId.Unique,
4222 // Update the metadata for the entry
4225 ntStatus = AFSUpdateMetaData( DirEntry,
4228 if( NT_SUCCESS( ntStatus))
4231 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4239 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4240 AFS_TRACE_LEVEL_WARNING,
4241 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4242 pObjectInfo->FileType,
4244 &DirEntry->NameInformation.FileName,
4245 pObjectInfo->FileId.Cell,
4246 pObjectInfo->FileId.Volume,
4247 pObjectInfo->FileId.Vnode,
4248 pObjectInfo->FileId.Unique);
4258 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4261 if( pDirEnumEntry != NULL)
4264 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4272 AFSInitializeSpecialShareNameList()
4275 NTSTATUS ntStatus = STATUS_SUCCESS;
4276 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4277 AFSObjectInfoCB *pObjectInfoCB = NULL;
4278 UNICODE_STRING uniShareName;
4279 ULONG ulEntryLength = 0;
4280 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4285 RtlInitUnicodeString( &uniShareName,
4288 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4291 if( pObjectInfoCB == NULL)
4294 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4297 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4298 AFS_TRACE_LEVEL_VERBOSE,
4299 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %p\n",
4302 pObjectInfoCB->ObjectReferenceCount = 1;
4304 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4306 ulEntryLength = sizeof( AFSDirectoryCB) +
4307 uniShareName.Length;
4309 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4313 if( pDirNode == NULL)
4316 AFSDeleteObjectInfo( pObjectInfoCB);
4318 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4321 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4322 sizeof( AFSNonPagedDirectoryCB),
4323 AFS_DIR_ENTRY_NP_TAG);
4325 if( pNonPagedDirEntry == NULL)
4328 ExFreePool( pDirNode);
4330 AFSDeleteObjectInfo( pObjectInfoCB);
4332 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4335 RtlZeroMemory( pDirNode,
4338 RtlZeroMemory( pNonPagedDirEntry,
4339 sizeof( AFSNonPagedDirectoryCB));
4341 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4343 pDirNode->NonPaged = pNonPagedDirEntry;
4345 pDirNode->ObjectInformation = pObjectInfoCB;
4351 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4353 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4355 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4357 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4359 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4360 uniShareName.Buffer,
4361 pDirNode->NameInformation.FileName.Length);
4363 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4366 AFSSpecialShareNames = pDirNode;
4368 pLastDirNode = pDirNode;
4371 RtlInitUnicodeString( &uniShareName,
4374 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4377 if( pObjectInfoCB == NULL)
4380 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4383 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4384 AFS_TRACE_LEVEL_VERBOSE,
4385 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %p\n",
4388 pObjectInfoCB->ObjectReferenceCount = 1;
4390 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4392 ulEntryLength = sizeof( AFSDirectoryCB) +
4393 uniShareName.Length;
4395 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4399 if( pDirNode == NULL)
4402 AFSDeleteObjectInfo( pObjectInfoCB);
4404 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4407 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4408 sizeof( AFSNonPagedDirectoryCB),
4409 AFS_DIR_ENTRY_NP_TAG);
4411 if( pNonPagedDirEntry == NULL)
4414 ExFreePool( pDirNode);
4416 AFSDeleteObjectInfo( pObjectInfoCB);
4418 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4421 RtlZeroMemory( pDirNode,
4424 RtlZeroMemory( pNonPagedDirEntry,
4425 sizeof( AFSNonPagedDirectoryCB));
4427 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4429 pDirNode->NonPaged = pNonPagedDirEntry;
4431 pDirNode->ObjectInformation = pObjectInfoCB;
4437 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4439 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4441 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4443 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4445 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4446 uniShareName.Buffer,
4447 pDirNode->NameInformation.FileName.Length);
4449 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4452 pLastDirNode->ListEntry.fLink = pDirNode;
4454 pDirNode->ListEntry.bLink = pLastDirNode;
4458 if( !NT_SUCCESS( ntStatus))
4461 if( AFSSpecialShareNames != NULL)
4464 pDirNode = AFSSpecialShareNames;
4466 while( pDirNode != NULL)
4469 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4471 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4473 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4475 ExFreePool( pDirNode->NonPaged);
4477 ExFreePool( pDirNode);
4479 pDirNode = pLastDirNode;
4482 AFSSpecialShareNames = NULL;
4491 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4492 IN UNICODE_STRING *SecondaryName)
4495 AFSDirectoryCB *pDirectoryCB = NULL;
4496 ULONGLONG ullHash = 0;
4497 UNICODE_STRING uniFullShareName;
4503 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4504 AFS_TRACE_LEVEL_VERBOSE_2,
4505 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4509 uniFullShareName = *ShareName;
4512 // Generate our hash value
4515 ullHash = AFSGenerateCRC( &uniFullShareName,
4519 // Loop through our special share names to see if this is one of them
4522 pDirectoryCB = AFSSpecialShareNames;
4524 while( pDirectoryCB != NULL)
4527 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4533 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4537 return pDirectoryCB;
4541 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4545 // Block on the queue flush event
4548 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4558 AFSWaitOnQueuedReleases()
4561 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4564 // Block on the queue flush event
4567 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4577 AFSIsEqualFID( IN AFSFileID *FileId1,
4578 IN AFSFileID *FileId2)
4581 BOOLEAN bIsEqual = FALSE;
4583 if( FileId1->Hash == FileId2->Hash &&
4584 FileId1->Unique == FileId2->Unique &&
4585 FileId1->Vnode == FileId2->Vnode &&
4586 FileId1->Volume == FileId2->Volume &&
4587 FileId1->Cell == FileId2->Cell)
4597 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4600 NTSTATUS ntStatus = STATUS_SUCCESS;
4601 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4606 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4609 // Reset the directory list information
4612 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4614 while( pCurrentDirEntry != NULL)
4617 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4619 if( pCurrentDirEntry->DirOpenReferenceCount <= 0)
4622 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4623 AFS_TRACE_LEVEL_VERBOSE,
4624 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4626 &pCurrentDirEntry->NameInformation.FileName);
4628 AFSDeleteDirEntry( ObjectInfoCB,
4634 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4635 AFS_TRACE_LEVEL_VERBOSE,
4636 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4638 &pCurrentDirEntry->NameInformation.FileName);
4640 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4642 AFSRemoveNameEntry( ObjectInfoCB,
4646 pCurrentDirEntry = pNextDirEntry;
4649 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4651 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4653 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4655 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4657 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4659 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4661 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4662 AFS_TRACE_LEVEL_VERBOSE,
4663 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4664 ObjectInfoCB->FileId.Cell,
4665 ObjectInfoCB->FileId.Volume,
4666 ObjectInfoCB->FileId.Vnode,
4667 ObjectInfoCB->FileId.Unique);
4674 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4677 NTSTATUS ntStatus = STATUS_SUCCESS;
4678 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4679 UNICODE_STRING uniFullName;
4684 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4685 AFS_TRACE_LEVEL_VERBOSE,
4686 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4687 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4688 PsGetCurrentThread());
4690 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4693 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4696 try_return( ntStatus);
4700 // Initialize the root information
4703 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4706 // Enumerate the shares in the volume
4709 ntStatus = AFSEnumerateDirectory( AuthGroup,
4710 &AFSGlobalRoot->ObjectInformation,
4713 if( !NT_SUCCESS( ntStatus))
4716 try_return( ntStatus);
4719 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4722 // Indicate the node is initialized
4725 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4727 uniFullName.MaximumLength = PAGE_SIZE;
4728 uniFullName.Length = 0;
4730 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4731 uniFullName.MaximumLength,
4732 AFS_GENERIC_MEMORY_12_TAG);
4734 if( uniFullName.Buffer == NULL)
4738 // Reset the directory content
4741 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4743 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4745 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4749 // Populate our list of entries in the NP enumeration list
4752 while( pDirGlobalDirNode != NULL)
4755 uniFullName.Buffer[ 0] = L'\\';
4756 uniFullName.Buffer[ 1] = L'\\';
4758 uniFullName.Length = 2 * sizeof( WCHAR);
4760 RtlCopyMemory( &uniFullName.Buffer[ 2],
4761 AFSServerName.Buffer,
4762 AFSServerName.Length);
4764 uniFullName.Length += AFSServerName.Length;
4766 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4768 uniFullName.Length += sizeof( WCHAR);
4770 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4771 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4772 pDirGlobalDirNode->NameInformation.FileName.Length);
4774 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4776 AFSAddConnectionEx( &uniFullName,
4777 RESOURCEDISPLAYTYPE_SHARE,
4780 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4783 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
4787 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4794 AFSIsRelativeName( IN UNICODE_STRING *Name)
4797 BOOLEAN bIsRelative = FALSE;
4799 if( Name->Length > 0 &&
4800 Name->Buffer[ 0] != L'\\')
4810 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
4812 UNICODE_STRING uniTempName;
4813 BOOLEAN bIsAbsolute = FALSE;
4816 // An absolute AFS path must begin with \afs\... or equivalent
4819 if ( Name->Length == 0 ||
4820 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
4821 Name->Buffer[ 0] != L'\\' ||
4822 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
4828 uniTempName.Length = AFSMountRootName.Length;
4829 uniTempName.MaximumLength = AFSMountRootName.Length;
4831 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4832 uniTempName.MaximumLength,
4833 AFS_NAME_BUFFER_TWO_TAG);
4835 if( uniTempName.Buffer == NULL)
4841 RtlCopyMemory( uniTempName.Buffer,
4843 AFSMountRootName.Length);
4845 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
4849 AFSExFreePoolWithTag( uniTempName.Buffer,
4850 AFS_NAME_BUFFER_TWO_TAG);
4857 AFSUpdateName( IN UNICODE_STRING *Name)
4862 while( usIndex < Name->Length/sizeof( WCHAR))
4865 if( Name->Buffer[ usIndex] == L'/')
4868 Name->Buffer[ usIndex] = L'\\';
4878 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4879 IN OUT ULONG *Flags,
4880 IN WCHAR *NameBuffer,
4881 IN USHORT NameLength)
4884 NTSTATUS ntStatus = STATUS_SUCCESS;
4885 WCHAR *pTmpBuffer = NULL;
4891 // If we have enough space then just move in the name otherwise
4892 // allocate a new buffer
4895 if( TargetName->Length < NameLength)
4898 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4900 AFS_NAME_BUFFER_FIVE_TAG);
4902 if( pTmpBuffer == NULL)
4905 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4908 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4911 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
4914 TargetName->MaximumLength = NameLength;
4916 TargetName->Buffer = pTmpBuffer;
4918 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4921 TargetName->Length = NameLength;
4923 RtlCopyMemory( TargetName->Buffer,
4925 TargetName->Length);
4928 // Update the name in the buffer
4931 AFSUpdateName( TargetName);
4942 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4943 IN ULONG InitialElementCount)
4946 AFSNameArrayHdr *pNameArray = NULL;
4947 AFSNameArrayCB *pCurrentElement = NULL;
4948 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4954 if( InitialElementCount == 0)
4957 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
4960 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
4961 sizeof( AFSNameArrayHdr) +
4962 (InitialElementCount * sizeof( AFSNameArrayCB)),
4963 AFS_NAME_ARRAY_TAG);
4965 if( pNameArray == NULL)
4968 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
4969 AFS_TRACE_LEVEL_ERROR,
4970 "AFSInitNameArray Failed to allocate name array\n");
4972 try_return( pNameArray);
4975 RtlZeroMemory( pNameArray,
4976 sizeof( AFSNameArrayHdr) +
4977 (InitialElementCount * sizeof( AFSNameArrayCB)));
4979 pNameArray->MaxElementCount = InitialElementCount;
4981 if( DirectoryCB != NULL)
4984 pCurrentElement = &pNameArray->ElementArray[ 0];
4986 pNameArray->CurrentEntry = pCurrentElement;
4988 pNameArray->Count = 1;
4990 pNameArray->LinkCount = 0;
4992 lCount = InterlockedIncrement( &DirectoryCB->DirOpenReferenceCount);
4994 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4995 AFS_TRACE_LEVEL_VERBOSE,
4996 "AFSInitNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
4998 &DirectoryCB->NameInformation.FileName,
5002 pCurrentElement->DirectoryCB = DirectoryCB;
5004 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5006 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5008 if( pCurrentElement->FileId.Vnode == 1)
5011 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5014 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5015 AFS_TRACE_LEVEL_VERBOSE,
5016 "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5018 pCurrentElement->DirectoryCB,
5019 pCurrentElement->FileId.Cell,
5020 pCurrentElement->FileId.Volume,
5021 pCurrentElement->FileId.Vnode,
5022 pCurrentElement->FileId.Unique,
5023 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5024 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5036 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
5037 IN UNICODE_STRING *Path,
5038 IN AFSDirectoryCB *DirectoryCB)
5041 NTSTATUS ntStatus = STATUS_SUCCESS;
5042 AFSNameArrayCB *pCurrentElement = NULL;
5048 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5049 AFS_TRACE_LEVEL_VERBOSE,
5050 "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5054 DirectoryCB->ObjectInformation->FileId.Cell,
5055 DirectoryCB->ObjectInformation->FileId.Volume,
5056 DirectoryCB->ObjectInformation->FileId.Vnode,
5057 DirectoryCB->ObjectInformation->FileId.Unique,
5058 &DirectoryCB->NameInformation.FileName,
5059 DirectoryCB->ObjectInformation->FileType);
5062 // Init some info in the header
5065 pCurrentElement = &NameArray->ElementArray[ 0];
5067 NameArray->CurrentEntry = pCurrentElement;
5070 // The first entry points at the root
5073 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
5075 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->DirOpenReferenceCount);
5077 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5078 AFS_TRACE_LEVEL_VERBOSE,
5079 "AFSPopulateNameArray [NA:%p] Increment count on volume %wZ DE %p Cnt %d\n",
5081 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5082 pCurrentElement->DirectoryCB,
5085 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
5087 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
5089 pCurrentElement->Flags = 0;
5091 if( pCurrentElement->FileId.Vnode == 1)
5094 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5097 NameArray->Count = 1;
5099 NameArray->LinkCount = 0;
5101 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5102 AFS_TRACE_LEVEL_VERBOSE,
5103 "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5105 pCurrentElement->DirectoryCB,
5106 pCurrentElement->FileId.Cell,
5107 pCurrentElement->FileId.Volume,
5108 pCurrentElement->FileId.Vnode,
5109 pCurrentElement->FileId.Unique,
5110 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5111 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5114 // If the root is the parent then we are done ...
5117 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
5119 try_return( ntStatus);
5131 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
5132 IN AFSNameArrayHdr *RelatedNameArray,
5133 IN AFSDirectoryCB *DirectoryCB)
5136 NTSTATUS ntStatus = STATUS_SUCCESS;
5137 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
5143 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5144 AFS_TRACE_LEVEL_VERBOSE,
5145 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5149 DirectoryCB->ObjectInformation->FileId.Cell,
5150 DirectoryCB->ObjectInformation->FileId.Volume,
5151 DirectoryCB->ObjectInformation->FileId.Vnode,
5152 DirectoryCB->ObjectInformation->FileId.Unique,
5153 &DirectoryCB->NameInformation.FileName,
5154 DirectoryCB->ObjectInformation->FileType);
5157 // Init some info in the header
5160 pCurrentElement = &NameArray->ElementArray[ 0];
5162 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5164 NameArray->Count = 0;
5166 NameArray->LinkCount = RelatedNameArray->LinkCount;
5169 // Populate the name array with the data from the related array
5175 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5177 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5179 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5181 pCurrentElement->Flags = 0;
5183 if( pCurrentElement->FileId.Vnode == 1)
5186 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5189 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->DirOpenReferenceCount);
5191 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5192 AFS_TRACE_LEVEL_VERBOSE,
5193 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5195 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5196 pCurrentElement->DirectoryCB,
5199 lCount = InterlockedIncrement( &NameArray->Count);
5201 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5202 AFS_TRACE_LEVEL_VERBOSE,
5203 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5206 pCurrentElement->DirectoryCB,
5207 pCurrentElement->FileId.Cell,
5208 pCurrentElement->FileId.Volume,
5209 pCurrentElement->FileId.Vnode,
5210 pCurrentElement->FileId.Unique,
5211 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5212 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5214 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5215 NameArray->Count == RelatedNameArray->Count)
5227 pCurrentRelatedElement++;
5230 NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
5237 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5240 NTSTATUS ntStatus = STATUS_SUCCESS;
5241 AFSNameArrayCB *pCurrentElement = NULL;
5242 LONG lCount, lElement;
5247 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5248 AFS_TRACE_LEVEL_VERBOSE,
5249 "AFSFreeNameArray [NA:%p]\n",
5252 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5255 pCurrentElement = &NameArray->ElementArray[ lElement];
5257 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->DirOpenReferenceCount);
5259 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5260 AFS_TRACE_LEVEL_VERBOSE,
5261 "AFSFreeNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5263 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5264 pCurrentElement->DirectoryCB,
5267 ASSERT( lCount >= 0);
5270 AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
5277 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5278 IN AFSDirectoryCB *DirectoryCB)
5281 NTSTATUS ntStatus = STATUS_SUCCESS;
5282 AFSNameArrayCB *pCurrentElement = NULL;
5288 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5289 AFS_TRACE_LEVEL_VERBOSE,
5290 "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5293 DirectoryCB->ObjectInformation->FileId.Cell,
5294 DirectoryCB->ObjectInformation->FileId.Volume,
5295 DirectoryCB->ObjectInformation->FileId.Vnode,
5296 DirectoryCB->ObjectInformation->FileId.Unique,
5297 &DirectoryCB->NameInformation.FileName,
5298 DirectoryCB->ObjectInformation->FileType);
5300 if( NameArray->Count == (LONG) NameArray->MaxElementCount)
5303 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5304 AFS_TRACE_LEVEL_ERROR,
5305 "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
5308 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5311 for ( lCount = 0; lCount < NameArray->Count; lCount++)
5314 if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
5315 &DirectoryCB->ObjectInformation->FileId) )
5318 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5319 AFS_TRACE_LEVEL_WARNING,
5320 "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
5323 STATUS_ACCESS_DENIED);
5325 try_return( ntStatus = STATUS_ACCESS_DENIED);
5329 if( NameArray->Count > 0)
5332 NameArray->CurrentEntry++;
5336 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5339 pCurrentElement = NameArray->CurrentEntry;
5341 lCount = InterlockedIncrement( &NameArray->Count);
5343 lCount = InterlockedIncrement( &DirectoryCB->DirOpenReferenceCount);
5345 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5346 AFS_TRACE_LEVEL_VERBOSE,
5347 "AFSInsertNextElement [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5349 &DirectoryCB->NameInformation.FileName,
5353 ASSERT( lCount >= 2);
5355 pCurrentElement->DirectoryCB = DirectoryCB;
5357 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5359 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5361 pCurrentElement->Flags = 0;
5363 if( pCurrentElement->FileId.Vnode == 1)
5366 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5369 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5370 AFS_TRACE_LEVEL_VERBOSE,
5371 "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5373 NameArray->Count - 1,
5374 pCurrentElement->DirectoryCB,
5375 pCurrentElement->FileId.Cell,
5376 pCurrentElement->FileId.Volume,
5377 pCurrentElement->FileId.Vnode,
5378 pCurrentElement->FileId.Unique,
5379 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5380 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5391 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5394 AFSDirectoryCB *pDirectoryCB = NULL;
5395 AFSNameArrayCB *pCurrentElement = NULL;
5396 BOOLEAN bVolumeRoot = FALSE;
5402 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5403 AFS_TRACE_LEVEL_VERBOSE,
5404 "AFSBackupEntry [NA:%p]\n",
5407 if( NameArray->Count == 0)
5410 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5411 AFS_TRACE_LEVEL_ERROR,
5412 "AFSBackupEntry [NA:%p] No more entries\n",
5415 try_return( pCurrentElement);
5418 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->DirOpenReferenceCount);
5420 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5421 AFS_TRACE_LEVEL_VERBOSE,
5422 "AFSBackupEntry [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5424 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5425 NameArray->CurrentEntry->DirectoryCB,
5428 ASSERT( lCount >= 0);
5430 NameArray->CurrentEntry->DirectoryCB = NULL;
5432 lCount = InterlockedDecrement( &NameArray->Count);
5436 NameArray->CurrentEntry = NULL;
5438 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5439 AFS_TRACE_LEVEL_ERROR,
5440 "AFSBackupEntry [NA:%p] No more entries\n",
5446 bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5448 NameArray->CurrentEntry--;
5450 pCurrentElement = NameArray->CurrentEntry;
5452 pDirectoryCB = pCurrentElement->DirectoryCB;
5454 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5455 AFS_TRACE_LEVEL_VERBOSE,
5456 "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5458 NameArray->Count - 1,
5459 pCurrentElement->DirectoryCB,
5460 pCurrentElement->FileId.Cell,
5461 pCurrentElement->FileId.Volume,
5462 pCurrentElement->FileId.Vnode,
5463 pCurrentElement->FileId.Unique,
5464 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5465 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5468 // If the entry we are removing is a volume root,
5469 // we must remove the mount point entry as well.
5470 // If the NameArray was constructed by checking the
5471 // share name via the service, the name array can
5472 // contain two volume roots in sequence without a
5473 // mount point separating them.
5477 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
5480 pDirectoryCB = AFSBackupEntry( NameArray);
5490 return pDirectoryCB;
5494 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5497 AFSDirectoryCB *pDirEntry = NULL;
5498 AFSNameArrayCB *pElement = NULL;
5503 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5504 AFS_TRACE_LEVEL_VERBOSE,
5505 "AFSGetParentEntry [NA:%p]\n",
5508 if( NameArray->Count == 0 ||
5509 NameArray->Count == 1)
5512 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5513 AFS_TRACE_LEVEL_ERROR,
5514 "AFSGetParentEntry [NA:%p] No more entries\n",
5517 try_return( pDirEntry = NULL);
5520 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5522 pDirEntry = pElement->DirectoryCB;
5524 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5525 AFS_TRACE_LEVEL_VERBOSE,
5526 "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5528 NameArray->Count - 2,
5529 pElement->DirectoryCB,
5530 pElement->FileId.Cell,
5531 pElement->FileId.Volume,
5532 pElement->FileId.Vnode,
5533 pElement->FileId.Unique,
5534 &pElement->DirectoryCB->NameInformation.FileName,
5535 pElement->DirectoryCB->ObjectInformation->FileType);
5546 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5547 IN AFSDirectoryCB *DirectoryCB)
5550 AFSNameArrayCB *pCurrentElement = NULL;
5551 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5552 LONG lCount, lElement;
5557 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5558 AFS_TRACE_LEVEL_VERBOSE,
5559 "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5562 DirectoryCB->ObjectInformation->FileId.Cell,
5563 DirectoryCB->ObjectInformation->FileId.Volume,
5564 DirectoryCB->ObjectInformation->FileId.Vnode,
5565 DirectoryCB->ObjectInformation->FileId.Unique,
5566 &DirectoryCB->NameInformation.FileName,
5567 DirectoryCB->ObjectInformation->FileType);
5569 // Dereference previous name array contents
5572 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5575 pCurrentElement = &NameArray->ElementArray[ lElement];
5577 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->DirOpenReferenceCount);
5579 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5580 AFS_TRACE_LEVEL_VERBOSE,
5581 "AFSResetNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5583 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5584 pCurrentElement->DirectoryCB,
5587 ASSERT( lCount >= 0);
5590 RtlZeroMemory( NameArray,
5591 sizeof( AFSNameArrayHdr) +
5592 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5594 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5596 if( DirectoryCB != NULL)
5599 pCurrentElement = &NameArray->ElementArray[ 0];
5601 NameArray->CurrentEntry = pCurrentElement;
5603 NameArray->Count = 1;
5605 NameArray->LinkCount = 0;
5607 lCount = InterlockedIncrement( &DirectoryCB->DirOpenReferenceCount);
5609 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5610 AFS_TRACE_LEVEL_VERBOSE,
5611 "AFSResetNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5613 &DirectoryCB->NameInformation.FileName,
5617 pCurrentElement->DirectoryCB = DirectoryCB;
5619 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5621 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5623 pCurrentElement->Flags = 0;
5625 if( pCurrentElement->FileId.Vnode == 1)
5628 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5631 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5632 AFS_TRACE_LEVEL_VERBOSE,
5633 "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5635 pCurrentElement->DirectoryCB,
5636 pCurrentElement->FileId.Cell,
5637 pCurrentElement->FileId.Volume,
5638 pCurrentElement->FileId.Vnode,
5639 pCurrentElement->FileId.Unique,
5640 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5641 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5649 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5652 AFSNameArrayCB *pCurrentElement = NULL;
5654 pCurrentElement = &NameArray->ElementArray[ 0];
5656 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5658 while( pCurrentElement->DirectoryCB != NULL)
5661 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5662 pCurrentElement->FileId.Cell,
5663 pCurrentElement->FileId.Volume,
5664 pCurrentElement->FileId.Vnode,
5665 pCurrentElement->FileId.Unique,
5666 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5671 AFSPrint("AFSDumpNameArray End\n\n");
5677 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5682 // Depending on the type of node, set the event
5685 switch( Fcb->Header.NodeTypeCode)
5688 case AFS_DIRECTORY_FCB:
5693 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5703 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5709 // Depending on the type of node, set the event
5712 switch( Fcb->Header.NodeTypeCode)
5715 case AFS_DIRECTORY_FCB:
5720 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5722 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5732 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5735 BOOLEAN bIsInProcess = FALSE;
5740 if( ObjectInfo->Fcb == NULL)
5743 try_return( bIsInProcess);
5746 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5749 case AFS_DIRECTORY_FCB:
5754 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5757 bIsInProcess = TRUE;
5769 return bIsInProcess;
5773 AFSVerifyVolume( IN ULONGLONG ProcessId,
5774 IN AFSVolumeCB *VolumeCB)
5777 UNREFERENCED_PARAMETER(ProcessId);
5778 UNREFERENCED_PARAMETER(VolumeCB);
5779 NTSTATUS ntStatus = STATUS_SUCCESS;
5786 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5789 NTSTATUS ntStatus = STATUS_SUCCESS;
5790 AFSObjectInfoCB *pObjectInfoCB = NULL;
5791 AFSDirectoryCB *pDirNode = NULL;
5792 ULONG ulEntryLength = 0;
5793 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5799 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5802 if( pObjectInfoCB == NULL)
5805 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5808 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5809 AFS_TRACE_LEVEL_VERBOSE,
5810 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %p\n",
5813 pObjectInfoCB->ObjectReferenceCount = 1;
5815 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5817 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5819 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5821 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5825 if( pDirNode == NULL)
5828 AFSDeleteObjectInfo( pObjectInfoCB);
5830 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5833 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5834 sizeof( AFSNonPagedDirectoryCB),
5835 AFS_DIR_ENTRY_NP_TAG);
5837 if( pNonPagedDirEntry == NULL)
5840 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5843 RtlZeroMemory( pDirNode,
5846 RtlZeroMemory( pNonPagedDirEntry,
5847 sizeof( AFSNonPagedDirectoryCB));
5849 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5851 pDirNode->NonPaged = pNonPagedDirEntry;
5853 pDirNode->ObjectInformation = pObjectInfoCB;
5855 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5861 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5863 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5865 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5867 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5869 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5870 AFSPIOCtlName.Buffer,
5871 pDirNode->NameInformation.FileName.Length);
5873 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5876 if ( InterlockedCompareExchangePointer( (PVOID *)&ObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5879 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5880 AFS_TRACE_LEVEL_WARNING,
5881 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5882 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5886 // Increment the open reference and handle on the node
5889 lCount = AFSObjectInfoIncrement( pDirNode->ObjectInformation);
5891 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
5892 AFS_TRACE_LEVEL_VERBOSE,
5893 "AFSInitPIOCtlDirectoryCB Increment count on Object %p Cnt %d\n",
5894 pDirNode->ObjectInformation,
5897 try_return( ntStatus = STATUS_REPARSE);
5902 if ( ntStatus != STATUS_SUCCESS)
5905 if ( pDirNode != NULL)
5908 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5911 if( pNonPagedDirEntry != NULL)
5914 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5916 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5919 if ( pObjectInfoCB != NULL)
5922 AFSDeleteObjectInfo( pObjectInfoCB);
5931 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5932 IN AFSDirectoryCB *DirectoryCB,
5933 IN UNICODE_STRING *ParentPathName,
5934 IN AFSNameArrayHdr *RelatedNameArray,
5936 OUT AFSFileInfoCB *FileInfo)
5939 NTSTATUS ntStatus = STATUS_SUCCESS;
5940 AFSDirEnumEntry *pDirEntry = NULL;
5941 UNICODE_STRING uniFullPathName = {0};
5942 AFSNameArrayHdr *pNameArray = NULL;
5943 AFSVolumeCB *pVolumeCB = NULL;
5944 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5945 WCHAR *pwchBuffer = NULL;
5946 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5947 ULONG ulNameDifference = 0;
5954 // Retrieve a target name for the entry
5957 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5960 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5963 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5965 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5970 if( !NT_SUCCESS( ntStatus) ||
5971 pDirEntry->TargetNameLength == 0)
5974 if( pDirEntry != NULL)
5977 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5980 try_return( ntStatus);
5983 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5986 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5990 // Update the target name
5993 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5994 &DirectoryCB->Flags,
5995 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5996 (USHORT)pDirEntry->TargetNameLength);
5998 if( !NT_SUCCESS( ntStatus))
6001 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6003 try_return( ntStatus);
6007 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6011 // Need to pass the full path in for parsing.
6014 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
6017 uniFullPathName.Length = 0;
6018 uniFullPathName.MaximumLength = ParentPathName->Length +
6020 DirectoryCB->NameInformation.TargetName.Length;
6022 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6023 uniFullPathName.MaximumLength,
6024 AFS_NAME_BUFFER_SIX_TAG);
6026 if( uniFullPathName.Buffer == NULL)
6029 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6031 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6034 pwchBuffer = uniFullPathName.Buffer;
6036 RtlZeroMemory( uniFullPathName.Buffer,
6037 uniFullPathName.MaximumLength);
6039 RtlCopyMemory( uniFullPathName.Buffer,
6040 ParentPathName->Buffer,
6041 ParentPathName->Length);
6043 uniFullPathName.Length = ParentPathName->Length;
6045 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
6046 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
6049 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
6051 uniFullPathName.Length += sizeof( WCHAR);
6054 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
6055 DirectoryCB->NameInformation.TargetName.Buffer,
6056 DirectoryCB->NameInformation.TargetName.Length);
6058 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
6060 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
6061 uniParsedName.MaximumLength = uniParsedName.Length;
6063 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
6065 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6068 // We populate up to the current parent
6071 if( RelatedNameArray != NULL)
6074 pNameArray = AFSInitNameArray( NULL,
6075 RelatedNameArray->MaxElementCount);
6077 if( pNameArray == NULL)
6080 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6083 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
6090 pNameArray = AFSInitNameArray( NULL,
6093 if( pNameArray == NULL)
6096 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6099 ntStatus = AFSPopulateNameArray( pNameArray,
6104 if( !NT_SUCCESS( ntStatus))
6107 try_return( ntStatus);
6110 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
6112 pParentDirEntry = ParentDirectoryCB;
6117 uniFullPathName.Length = 0;
6118 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6120 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6121 uniFullPathName.MaximumLength,
6122 AFS_NAME_BUFFER_SEVEN_TAG);
6124 if( uniFullPathName.Buffer == NULL)
6127 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6129 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6132 pwchBuffer = uniFullPathName.Buffer;
6134 RtlZeroMemory( uniFullPathName.Buffer,
6135 uniFullPathName.MaximumLength);
6137 RtlCopyMemory( uniFullPathName.Buffer,
6138 DirectoryCB->NameInformation.TargetName.Buffer,
6139 DirectoryCB->NameInformation.TargetName.Length);
6141 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6144 // This name should begin with the \afs server so parse it off and check it
6147 FsRtlDissectName( uniFullPathName,
6151 if( RtlCompareUnicodeString( &uniComponentName,
6156 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6158 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6159 AFS_TRACE_LEVEL_ERROR,
6160 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
6163 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
6166 uniFullPathName = uniRemainingPath;
6168 uniParsedName = uniFullPathName;
6170 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6172 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6178 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6181 if( pNameArray == NULL)
6184 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6187 pVolumeCB = AFSGlobalRoot;
6189 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6193 // Increment the ref count on the volume and dir entry for correct processing below
6196 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6198 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6199 AFS_TRACE_LEVEL_VERBOSE,
6200 "AFSRetrieveFileAttributes Increment count on volume %p Cnt %d\n",
6204 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6206 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6207 AFS_TRACE_LEVEL_VERBOSE,
6208 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6209 &pParentDirEntry->NameInformation.FileName,
6214 ntStatus = AFSLocateNameEntry( NULL,
6219 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
6225 if( !NT_SUCCESS( ntStatus) ||
6226 ntStatus == STATUS_REPARSE)
6230 // The volume lock was released on failure or reparse above
6231 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6234 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6237 if( pVolumeCB != NULL)
6240 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6242 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6243 AFS_TRACE_LEVEL_VERBOSE,
6244 "AFSRetrieveFileAttributes Decrement count on volume %p Cnt %d\n",
6249 if( pDirectoryEntry != NULL)
6252 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6254 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6255 AFS_TRACE_LEVEL_VERBOSE,
6256 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6257 &pDirectoryEntry->NameInformation.FileName,
6262 ASSERT( lCount >= 0);
6267 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6269 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6270 AFS_TRACE_LEVEL_VERBOSE,
6271 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6272 &pParentDirEntry->NameInformation.FileName,
6277 ASSERT( lCount >= 0);
6283 try_return( ntStatus);
6287 // Store off the information
6290 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6293 // Check for the mount point being returned
6296 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
6299 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6301 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
6302 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6305 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6308 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6313 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6317 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6319 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6321 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6323 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6325 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6327 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6330 // Remove the reference made above
6333 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6335 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6336 AFS_TRACE_LEVEL_VERBOSE,
6337 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
6338 &pDirectoryEntry->NameInformation.FileName,
6343 ASSERT( lCount >= 0);
6347 if( pDirEntry != NULL)
6350 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6353 if( pVolumeCB != NULL)
6356 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6358 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6359 AFS_TRACE_LEVEL_VERBOSE,
6360 "AFSRetrieveFileAttributes Decrement2 count on volume %p Cnt %d\n",
6365 if( pNameArray != NULL)
6368 AFSFreeNameArray( pNameArray);
6371 if( pwchBuffer != NULL)
6375 // Always free the buffer that we allocated as AFSLocateNameEntry
6376 // will not free it. If uniFullPathName.Buffer was allocated by
6377 // AFSLocateNameEntry, then we must free that as well.
6378 // Check that the uniFullPathName.Buffer in the string is not the same
6379 // offset by the length of the server name
6382 if( uniFullPathName.Length > 0 &&
6383 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6386 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6389 AFSExFreePoolWithTag( pwchBuffer, 0);
6397 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6398 IN ULONGLONG HashIndex)
6401 NTSTATUS ntStatus = STATUS_SUCCESS;
6402 AFSObjectInfoCB *pObjectInfo = NULL;
6408 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6409 sizeof( AFSObjectInfoCB),
6410 AFS_OBJECT_INFO_TAG);
6412 if( pObjectInfo == NULL)
6415 try_return( pObjectInfo);
6418 RtlZeroMemory( pObjectInfo,
6419 sizeof( AFSObjectInfoCB));
6421 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6422 sizeof( AFSNonPagedObjectInfoCB),
6423 AFS_NP_OBJECT_INFO_TAG);
6425 if( pObjectInfo->NonPagedInfo == NULL)
6428 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6430 try_return( pObjectInfo = NULL);
6433 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6435 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6437 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6439 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6441 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6443 if( ParentObjectInfo != NULL)
6445 lCount = AFSObjectInfoIncrement( ParentObjectInfo);
6449 // Initialize the access time
6452 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6458 // Insert the entry into the object tree and list
6461 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6463 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6466 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6471 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6472 &pObjectInfo->TreeEntry);
6474 ASSERT( NT_SUCCESS( ntStatus));
6478 // And the object list in the volume
6481 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6484 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6489 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6491 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6494 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6497 // Indicate the object is in the hash tree and linked list in the volume
6500 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6512 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo)
6517 if ( ObjectInfo->ObjectReferenceCount == 0)
6520 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6523 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6528 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6531 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6536 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6538 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6543 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6549 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo)
6554 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6557 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6562 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6564 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6566 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6569 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6572 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6580 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6583 BOOLEAN bAcquiredTreeLock = FALSE;
6586 if ( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_ROOT_VOLUME))
6590 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6591 // embedded in the VolumeCB.
6599 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6602 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6604 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6607 bAcquiredTreeLock = TRUE;
6611 // Remove it from the tree and list if it was inserted
6614 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6617 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6618 &ObjectInfo->TreeEntry);
6621 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6624 if( ObjectInfo->ListEntry.fLink == NULL)
6627 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6629 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6632 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6638 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6641 if( ObjectInfo->ListEntry.bLink == NULL)
6644 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6646 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6649 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6655 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6659 if( ObjectInfo->ParentObjectInformation != NULL)
6662 lCount = AFSObjectInfoDecrement( ObjectInfo->ParentObjectInformation);
6665 if( bAcquiredTreeLock)
6668 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6672 // Release the fid in the service
6675 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6678 AFSReleaseFid( &ObjectInfo->FileId);
6681 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6683 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6685 AFSExFreePoolWithTag( ObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6687 AFSExFreePoolWithTag( ObjectInfo, AFS_OBJECT_INFO_TAG);
6693 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6694 OUT AFSDirectoryCB **TargetDirEntry)
6697 NTSTATUS ntStatus = STATUS_SUCCESS;
6698 AFSDirEnumEntry *pDirEntry = NULL;
6699 UNICODE_STRING uniFullPathName = {0};
6700 AFSNameArrayHdr *pNameArray = NULL;
6701 AFSVolumeCB *pVolumeCB = NULL;
6702 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6703 WCHAR *pwchBuffer = NULL;
6704 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6705 ULONG ulNameDifference = 0;
6712 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6713 DirectoryCB->ObjectInformation,
6717 if( !NT_SUCCESS( ntStatus))
6719 try_return( ntStatus);
6723 // Retrieve a target name for the entry
6726 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6729 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6732 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6734 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6739 if( !NT_SUCCESS( ntStatus) ||
6740 pDirEntry->TargetNameLength == 0)
6743 if( pDirEntry != NULL)
6746 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6749 try_return( ntStatus);
6752 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6755 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6759 // Update the target name
6762 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6763 &DirectoryCB->Flags,
6764 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6765 (USHORT)pDirEntry->TargetNameLength);
6767 if( !NT_SUCCESS( ntStatus))
6770 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6772 try_return( ntStatus);
6776 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6780 // Need to pass the full path in for parsing.
6783 uniFullPathName.Length = 0;
6784 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6786 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6787 uniFullPathName.MaximumLength,
6788 AFS_NAME_BUFFER_EIGHT_TAG);
6790 if( uniFullPathName.Buffer == NULL)
6793 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6795 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6798 pwchBuffer = uniFullPathName.Buffer;
6800 RtlZeroMemory( uniFullPathName.Buffer,
6801 uniFullPathName.MaximumLength);
6803 RtlCopyMemory( uniFullPathName.Buffer,
6804 DirectoryCB->NameInformation.TargetName.Buffer,
6805 DirectoryCB->NameInformation.TargetName.Length);
6807 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6810 // This name should begin with the \afs server so parse it off and chech it
6813 FsRtlDissectName( uniFullPathName,
6817 if( RtlCompareUnicodeString( &uniComponentName,
6823 // Try evaluating the full path
6826 uniFullPathName.Buffer = pwchBuffer;
6828 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6830 uniFullPathName.MaximumLength = uniFullPathName.Length;
6835 uniFullPathName = uniRemainingPath;
6838 uniParsedName = uniFullPathName;
6840 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6842 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6848 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6851 if( pNameArray == NULL)
6854 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6857 pVolumeCB = AFSGlobalRoot;
6859 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6861 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6863 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6864 AFS_TRACE_LEVEL_VERBOSE,
6865 "AFSEvaluateRootEntry Increment count on volume %p Cnt %d\n",
6869 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6871 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6872 AFS_TRACE_LEVEL_VERBOSE,
6873 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6874 &pParentDirEntry->NameInformation.FileName,
6879 ntStatus = AFSLocateNameEntry( NULL,
6890 if( !NT_SUCCESS( ntStatus) ||
6891 ntStatus == STATUS_REPARSE)
6895 // The volume lock was released on failure or reparse above
6896 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6899 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6902 if( pVolumeCB != NULL)
6905 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6907 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6908 AFS_TRACE_LEVEL_VERBOSE,
6909 "AFSEvaluateRootEntry Decrement count on volume %p Cnt %d\n",
6914 if( pDirectoryEntry != NULL)
6917 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6919 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6920 AFS_TRACE_LEVEL_VERBOSE,
6921 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6922 &pDirectoryEntry->NameInformation.FileName,
6927 ASSERT( lCount >= 0);
6932 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6934 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6935 AFS_TRACE_LEVEL_VERBOSE,
6936 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6937 &pParentDirEntry->NameInformation.FileName,
6942 ASSERT( lCount >= 0);
6948 try_return( ntStatus);
6952 // Pass back the target dir entry for this request
6955 *TargetDirEntry = pDirectoryEntry;
6959 if( pDirEntry != NULL)
6962 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6965 if( pVolumeCB != NULL)
6968 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6970 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6971 AFS_TRACE_LEVEL_VERBOSE,
6972 "AFSEvaluateRootEntry Decrement2 count on volume %p Cnt %d\n",
6977 if( pNameArray != NULL)
6980 AFSFreeNameArray( pNameArray);
6983 if( pwchBuffer != NULL)
6987 // Always free the buffer that we allocated as AFSLocateNameEntry
6988 // will not free it. If uniFullPathName.Buffer was allocated by
6989 // AFSLocateNameEntry, then we must free that as well.
6990 // Check that the uniFullPathName.Buffer in the string is not the same
6991 // offset by the length of the server name
6994 if( uniFullPathName.Length > 0 &&
6995 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6998 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
7001 AFSExFreePoolWithTag( pwchBuffer, 0);
7009 AFSCleanupFcb( IN AFSFcb *Fcb,
7010 IN BOOLEAN ForceFlush)
7013 NTSTATUS ntStatus = STATUS_SUCCESS;
7014 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
7015 LARGE_INTEGER liTime;
7016 IO_STATUS_BLOCK stIoStatus;
7021 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7023 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7025 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
7028 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
7029 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7032 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7033 AFS_TRACE_LEVEL_VERBOSE,
7034 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
7035 &Fcb->NPFcb->Resource,
7036 PsGetCurrentThread());
7038 AFSAcquireShared( &Fcb->NPFcb->Resource,
7041 if( Fcb->OpenReferenceCount > 0)
7044 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7045 AFS_TRACE_LEVEL_VERBOSE,
7046 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7047 &Fcb->NPFcb->SectionObjectResource,
7048 PsGetCurrentThread());
7050 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
7056 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7061 if( !NT_SUCCESS( stIoStatus.Status))
7064 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7065 AFS_TRACE_LEVEL_ERROR,
7066 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7067 Fcb->ObjectInformation->FileId.Cell,
7068 Fcb->ObjectInformation->FileId.Volume,
7069 Fcb->ObjectInformation->FileId.Vnode,
7070 Fcb->ObjectInformation->FileId.Unique,
7072 stIoStatus.Information);
7074 ntStatus = stIoStatus.Status;
7077 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7080 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7086 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7087 AFS_TRACE_LEVEL_WARNING,
7088 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
7089 Fcb->ObjectInformation->FileId.Cell,
7090 Fcb->ObjectInformation->FileId.Volume,
7091 Fcb->ObjectInformation->FileId.Vnode,
7092 Fcb->ObjectInformation->FileId.Unique);
7094 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7098 __except( EXCEPTION_EXECUTE_HANDLER)
7101 ntStatus = GetExceptionCode();
7105 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7106 Fcb->ObjectInformation->FileId.Cell,
7107 Fcb->ObjectInformation->FileId.Volume,
7108 Fcb->ObjectInformation->FileId.Vnode,
7109 Fcb->ObjectInformation->FileId.Unique,
7112 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7115 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7116 AFS_TRACE_LEVEL_VERBOSE,
7117 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7118 &Fcb->NPFcb->SectionObjectResource,
7119 PsGetCurrentThread());
7121 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7124 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7125 AFS_TRACE_LEVEL_VERBOSE,
7126 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
7127 &Fcb->NPFcb->Resource,
7128 PsGetCurrentThread());
7130 AFSReleaseResource( &Fcb->NPFcb->Resource);
7133 // Wait for any currently running flush or release requests to complete
7136 AFSWaitOnQueuedFlushes( Fcb);
7139 // Now perform another flush on the file
7142 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7146 AFSReleaseExtentsWithFlush( Fcb,
7152 if( Fcb->OpenReferenceCount == 0 ||
7153 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7154 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7157 AFSTearDownFcbExtents( Fcb,
7161 try_return( ntStatus);
7164 KeQueryTickCount( &liTime);
7167 // First up are there dirty extents in the cache to flush?
7170 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7171 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7175 // The file has been marked as invalid. Dump it
7178 AFSTearDownFcbExtents( Fcb,
7181 else if( ForceFlush ||
7182 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7183 Fcb->Specific.File.ExtentCount) &&
7184 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7185 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7187 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7189 Fcb->OpenReferenceCount == 0)
7192 AFSReleaseExtentsWithFlush( Fcb,
7199 // If there are extents and they haven't been used recently *and*
7200 // are not being used
7204 ( 0 != Fcb->Specific.File.ExtentCount &&
7205 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7206 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7207 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7210 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7211 AFS_TRACE_LEVEL_VERBOSE,
7212 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7213 &Fcb->NPFcb->SectionObjectResource,
7214 PsGetCurrentThread());
7216 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7222 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7227 if( !NT_SUCCESS( stIoStatus.Status))
7230 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7231 AFS_TRACE_LEVEL_ERROR,
7232 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7233 Fcb->ObjectInformation->FileId.Cell,
7234 Fcb->ObjectInformation->FileId.Volume,
7235 Fcb->ObjectInformation->FileId.Vnode,
7236 Fcb->ObjectInformation->FileId.Unique,
7238 stIoStatus.Information);
7240 ntStatus = stIoStatus.Status;
7244 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7247 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7253 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7254 AFS_TRACE_LEVEL_WARNING,
7255 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7256 Fcb->ObjectInformation->FileId.Cell,
7257 Fcb->ObjectInformation->FileId.Volume,
7258 Fcb->ObjectInformation->FileId.Vnode,
7259 Fcb->ObjectInformation->FileId.Unique);
7261 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7265 __except( EXCEPTION_EXECUTE_HANDLER)
7268 ntStatus = GetExceptionCode();
7272 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7273 Fcb->ObjectInformation->FileId.Cell,
7274 Fcb->ObjectInformation->FileId.Volume,
7275 Fcb->ObjectInformation->FileId.Vnode,
7276 Fcb->ObjectInformation->FileId.Unique,
7280 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7281 AFS_TRACE_LEVEL_VERBOSE,
7282 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7283 &Fcb->NPFcb->SectionObjectResource,
7284 PsGetCurrentThread());
7286 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7288 if( Fcb->OpenReferenceCount <= 0)
7292 // Tear em down we'll not be needing them again
7295 AFSTearDownFcbExtents( Fcb,
7302 ntStatus = STATUS_RETRY;
7315 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7316 IN UNICODE_STRING *NewFileName)
7319 NTSTATUS ntStatus = STATUS_SUCCESS;
7320 WCHAR *pTmpBuffer = NULL;
7325 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7328 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7331 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7333 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7335 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7339 // OK, we need to allocate a new name buffer
7342 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7343 NewFileName->Length,
7344 AFS_NAME_BUFFER_NINE_TAG);
7346 if( pTmpBuffer == NULL)
7349 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7352 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7354 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7356 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7359 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7361 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7362 NewFileName->Buffer,
7363 NewFileName->Length);
7374 AFSReadCacheFile( IN void *ReadBuffer,
7375 IN LARGE_INTEGER *ReadOffset,
7376 IN ULONG RequestedDataLength,
7377 IN OUT PULONG BytesRead)
7380 NTSTATUS ntStatus = STATUS_SUCCESS;
7383 PIO_STACK_LOCATION pIoStackLocation = NULL;
7384 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7385 FILE_OBJECT *pCacheFileObject = NULL;
7390 pCacheFileObject = AFSReferenceCacheFileObject();
7392 if( pCacheFileObject == NULL)
7394 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7397 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7400 // Initialize the event
7403 KeInitializeEvent( &kEvent,
7404 SynchronizationEvent,
7408 // Allocate an irp for this request. This could also come from a
7409 // private pool, for instance.
7412 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7418 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7422 // Build the IRP's main body
7425 pIrp->UserBuffer = ReadBuffer;
7427 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7428 pIrp->RequestorMode = KernelMode;
7429 pIrp->Flags |= IRP_READ_OPERATION;
7432 // Set up the I/O stack location.
7435 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7436 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7437 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7438 pIoStackLocation->FileObject = pCacheFileObject;
7439 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7441 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7444 // Set the completion routine.
7447 IoSetCompletionRoutine( pIrp,
7455 // Send it to the FSD
7458 ntStatus = IoCallDriver( pTargetDeviceObject,
7461 if( NT_SUCCESS( ntStatus))
7468 ntStatus = KeWaitForSingleObject( &kEvent,
7474 if( NT_SUCCESS( ntStatus))
7477 ntStatus = pIrp->IoStatus.Status;
7479 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7485 if( pCacheFileObject != NULL)
7487 AFSReleaseCacheFileObject( pCacheFileObject);
7493 if( pIrp->MdlAddress != NULL)
7496 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7499 MmUnlockPages( pIrp->MdlAddress);
7502 IoFreeMdl( pIrp->MdlAddress);
7505 pIrp->MdlAddress = NULL;
7519 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7524 UNREFERENCED_PARAMETER(Irp);
7525 UNREFERENCED_PARAMETER(DeviceObject);
7526 KEVENT *pEvent = (KEVENT *)Context;
7532 return STATUS_MORE_PROCESSING_REQUIRED;
7536 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7539 BOOLEAN bIsEmpty = FALSE;
7540 AFSDirectoryCB *pDirEntry = NULL;
7545 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7550 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7553 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7555 while( pDirEntry != NULL)
7558 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7559 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7567 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7572 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7579 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7580 IN AFSDirectoryCB *DirEntry)
7583 NTSTATUS ntStatus = STATUS_SUCCESS;
7588 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7591 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7592 AFS_TRACE_LEVEL_VERBOSE,
7593 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7595 &DirEntry->NameInformation.FileName);
7597 try_return( ntStatus);
7600 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7603 // Remove the entry from the parent tree
7606 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7607 AFS_TRACE_LEVEL_VERBOSE,
7608 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7610 &DirEntry->NameInformation.FileName);
7612 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7615 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7616 AFS_TRACE_LEVEL_VERBOSE,
7617 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7619 &DirEntry->NameInformation.FileName);
7621 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7624 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7628 // From the short name tree
7631 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7632 AFS_TRACE_LEVEL_VERBOSE,
7633 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7635 &DirEntry->NameInformation.FileName);
7637 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7640 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7643 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7644 AFS_TRACE_LEVEL_VERBOSE,
7645 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7647 &DirEntry->NameInformation.FileName);
7649 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7651 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7662 AFSGetAuthenticationId()
7665 LARGE_INTEGER liAuthId = {0,0};
7666 NTSTATUS ntStatus = STATUS_SUCCESS;
7667 PACCESS_TOKEN hToken = NULL;
7668 PTOKEN_STATISTICS pTokenInfo = NULL;
7669 BOOLEAN bCopyOnOpen = FALSE;
7670 BOOLEAN bEffectiveOnly = FALSE;
7671 BOOLEAN bPrimaryToken = FALSE;
7672 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7677 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7680 &stImpersonationLevel);
7685 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7690 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7691 AFS_TRACE_LEVEL_ERROR,
7692 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7694 try_return( ntStatus);
7697 bPrimaryToken = TRUE;
7700 ntStatus = SeQueryInformationToken( hToken,
7702 (PVOID *)&pTokenInfo);
7704 if( !NT_SUCCESS( ntStatus))
7707 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7708 AFS_TRACE_LEVEL_ERROR,
7709 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7711 try_return( ntStatus);
7714 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7715 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7717 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7718 AFS_TRACE_LEVEL_VERBOSE,
7719 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7730 PsDereferenceImpersonationToken( hToken);
7735 PsDereferencePrimaryToken( hToken);
7739 if( pTokenInfo != NULL)
7742 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7750 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7754 UNREFERENCED_PARAMETER(Fcb);
7755 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7757 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7760 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7762 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7765 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7767 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7770 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7772 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7775 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7777 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7784 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7787 BOOLEAN bIsValid = TRUE;
7789 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7791 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7793 while( pCurrentDirEntry != NULL)
7796 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7800 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7805 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7806 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7809 if( pDirEntry == NULL)
7816 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7819 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
7822 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7824 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7826 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7835 AFSReferenceCacheFileObject()
7838 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7839 FILE_OBJECT *pCacheFileObject = NULL;
7841 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7844 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7846 if( pCacheFileObject != NULL)
7848 ObReferenceObject( pCacheFileObject);
7851 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7853 return pCacheFileObject;
7857 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7860 ASSERT( CacheFileObject != NULL);
7862 ObDereferenceObject( CacheFileObject);
7868 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7871 NTSTATUS ntStatus = STATUS_SUCCESS;
7872 AFSDeviceExt *pControlDevExt = NULL;
7873 ULONG ulTimeIncrement = 0;
7879 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7881 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7883 AFSServerName = LibraryInit->AFSServerName;
7885 AFSMountRootName = LibraryInit->AFSMountRootName;
7887 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7890 // Callbacks in the framework
7893 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7895 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7897 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7899 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7901 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
7903 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7905 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7907 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7909 if( LibraryInit->AFSCacheBaseAddress != NULL)
7912 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7914 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7916 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7920 // Initialize some flush parameters
7923 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7925 ulTimeIncrement = KeQueryTimeIncrement();
7927 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7928 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7929 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7930 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7931 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7934 // Initialize the global root entry
7937 ntStatus = AFSInitVolume( NULL,
7938 &LibraryInit->GlobalRootFid,
7941 if( !NT_SUCCESS( ntStatus))
7944 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7945 AFS_TRACE_LEVEL_ERROR,
7946 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7949 try_return( ntStatus);
7952 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7955 if( !NT_SUCCESS( ntStatus))
7958 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7959 AFS_TRACE_LEVEL_ERROR,
7960 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7963 lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
7965 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7966 AFS_TRACE_LEVEL_VERBOSE,
7967 "AFSInitializeLibrary Increment count on volume %p Cnt %d\n",
7971 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7973 try_return( ntStatus);
7977 // Update the node type code to AFS_ROOT_ALL
7980 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7982 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7985 // Invalidate all known volumes since contact with the service and therefore
7986 // the file server was lost.
7989 AFSInvalidateAllVolumes();
7992 // Drop the locks acquired above
7995 AFSInitVolumeWorker( AFSGlobalRoot);
7997 lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
7999 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8000 AFS_TRACE_LEVEL_VERBOSE,
8001 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8005 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8007 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
8021 NTSTATUS ntStatus = STATUS_SUCCESS;
8022 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
8027 if( AFSGlobalDotDirEntry != NULL)
8030 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
8032 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
8034 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
8036 ExFreePool( AFSGlobalDotDirEntry);
8038 AFSGlobalDotDirEntry = NULL;
8041 if( AFSGlobalDotDotDirEntry != NULL)
8044 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
8046 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
8048 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
8050 ExFreePool( AFSGlobalDotDotDirEntry);
8052 AFSGlobalDotDotDirEntry = NULL;
8055 if( AFSSpecialShareNames != NULL)
8058 pDirNode = AFSSpecialShareNames;
8060 while( pDirNode != NULL)
8063 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
8065 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
8067 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
8069 ExFreePool( pDirNode->NonPaged);
8071 ExFreePool( pDirNode);
8073 pDirNode = pLastDirNode;
8076 AFSSpecialShareNames = NULL;
8084 AFSDefaultLogMsg( IN ULONG Subsystem,
8090 UNREFERENCED_PARAMETER(Subsystem);
8091 UNREFERENCED_PARAMETER(Level);
8092 NTSTATUS ntStatus = STATUS_SUCCESS;
8094 char chDebugBuffer[ 256];
8099 va_start( va_args, Format);
8101 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8106 if( NT_SUCCESS( ntStatus))
8108 DbgPrint( chDebugBuffer);
8118 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8119 IN ULONG InputBufferLength,
8120 IN AFSStatusInfoCB *StatusInfo,
8121 OUT ULONG *ReturnLength)
8124 NTSTATUS ntStatus = STATUS_SUCCESS;
8125 AFSVolumeCB *pVolumeCB = NULL;
8126 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8127 AFSObjectInfoCB *pObjectInfo = NULL;
8128 ULONGLONG ullIndex = 0;
8129 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8130 AFSNameArrayHdr *pNameArray = NULL;
8131 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8138 // If we are given a FID then look up the entry by that, otherwise
8142 if( GetStatusInfo->FileID.Cell != 0 &&
8143 GetStatusInfo->FileID.Volume != 0 &&
8144 GetStatusInfo->FileID.Vnode != 0 &&
8145 GetStatusInfo->FileID.Unique != 0)
8148 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8151 // Locate the volume node
8154 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8156 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8158 (AFSBTreeEntry **)&pVolumeCB);
8160 if( pVolumeCB != NULL)
8163 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8165 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8166 AFS_TRACE_LEVEL_VERBOSE,
8167 "AFSGetObjectStatus Increment count on volume %p Cnt %d\n",
8172 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8174 if( !NT_SUCCESS( ntStatus) ||
8177 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8180 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8183 pObjectInfo = &pVolumeCB->ObjectInformation;
8185 lCount = AFSObjectInfoIncrement( pObjectInfo);
8187 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8189 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8190 AFS_TRACE_LEVEL_VERBOSE,
8191 "AFSGetObjectStatus Decrement count on volume %p Cnt %d\n",
8198 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8201 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8203 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8204 AFS_TRACE_LEVEL_VERBOSE,
8205 "AFSGetObjectStatus Decrement2 count on volume %p Cnt %d\n",
8209 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8211 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8213 (AFSBTreeEntry **)&pObjectInfo);
8215 if( pObjectInfo != NULL)
8219 // Reference the node so it won't be torn down
8222 lCount = AFSObjectInfoIncrement( pObjectInfo);
8224 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8225 AFS_TRACE_LEVEL_VERBOSE,
8226 "AFSGetObjectStatus Increment count on object %p Cnt %d\n",
8231 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8233 if( !NT_SUCCESS( ntStatus) ||
8234 pObjectInfo == NULL)
8236 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8243 if( GetStatusInfo->FileNameLength == 0 ||
8244 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8246 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8249 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8250 uniFullPathName.MaximumLength = uniFullPathName.Length;
8252 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8255 // This name should begin with the \afs server so parse it off and check it
8258 FsRtlDissectName( uniFullPathName,
8262 if( RtlCompareUnicodeString( &uniComponentName,
8266 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8267 AFS_TRACE_LEVEL_ERROR,
8268 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8271 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8274 uniFullPathName = uniRemainingPath;
8276 uniParsedName = uniFullPathName;
8282 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8285 if( pNameArray == NULL)
8287 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8290 pVolumeCB = AFSGlobalRoot;
8292 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8295 // Increment the ref count on the volume and dir entry for correct processing below
8298 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8300 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8301 AFS_TRACE_LEVEL_VERBOSE,
8302 "AFSGetObjectStatus Increment2 count on volume %p Cnt %d\n",
8306 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8308 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8309 AFS_TRACE_LEVEL_VERBOSE,
8310 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8311 &pParentDirEntry->NameInformation.FileName,
8316 ntStatus = AFSLocateNameEntry( NULL,
8321 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8322 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8328 if( !NT_SUCCESS( ntStatus) ||
8329 ntStatus == STATUS_REPARSE)
8333 // The volume lock was released on failure or reparse above
8334 // Except for STATUS_OBJECT_NAME_NOT_FOUND
8337 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
8340 if( pVolumeCB != NULL)
8343 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8345 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8346 AFS_TRACE_LEVEL_VERBOSE,
8347 "AFSGetObjectStatus Decrement3 count on volume %p Cnt %d\n",
8352 if( pDirectoryEntry != NULL)
8355 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8357 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8358 AFS_TRACE_LEVEL_VERBOSE,
8359 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8360 &pDirectoryEntry->NameInformation.FileName,
8365 ASSERT( lCount >= 0);
8370 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8372 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8373 AFS_TRACE_LEVEL_VERBOSE,
8374 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8375 &pParentDirEntry->NameInformation.FileName,
8380 ASSERT( lCount >= 0);
8386 try_return( ntStatus);
8390 // Remove the reference made above
8393 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8395 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8396 AFS_TRACE_LEVEL_VERBOSE,
8397 "AFSGetObjectStatus Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
8398 &pDirectoryEntry->NameInformation.FileName,
8403 ASSERT( lCount >= 0);
8405 pObjectInfo = pDirectoryEntry->ObjectInformation;
8407 lCount = AFSObjectInfoIncrement( pObjectInfo);
8409 if( pVolumeCB != NULL)
8412 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8414 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8415 AFS_TRACE_LEVEL_VERBOSE,
8416 "AFSGetObjectStatus Decrement4 count on volume %p Cnt %d\n",
8423 // At this point we have an object info block, return the information
8426 StatusInfo->FileId = pObjectInfo->FileId;
8428 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8430 StatusInfo->Expiration = pObjectInfo->Expiration;
8432 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8434 StatusInfo->FileType = pObjectInfo->FileType;
8436 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8438 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8440 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8442 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8444 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8446 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8448 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8450 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8452 StatusInfo->EaSize = pObjectInfo->EaSize;
8454 StatusInfo->Links = pObjectInfo->Links;
8457 // Return the information length
8460 *ReturnLength = sizeof( AFSStatusInfoCB);
8464 if( pObjectInfo != NULL)
8467 lCount = AFSObjectInfoDecrement( pObjectInfo);
8470 if( pNameArray != NULL)
8473 AFSFreeNameArray( pNameArray);
8481 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8482 IN UNICODE_STRING *ComponentName)
8485 NTSTATUS ntStatus = STATUS_SUCCESS;
8486 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8487 AFSDirectoryCB *pDirEntry = NULL;
8495 // Search for the entry in the parent
8498 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8499 AFS_TRACE_LEVEL_VERBOSE_2,
8500 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8503 ulCRC = AFSGenerateCRC( ComponentName,
8506 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8509 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8513 if( pDirEntry == NULL)
8517 // Missed so perform a case insensitive lookup
8520 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8521 AFS_TRACE_LEVEL_VERBOSE_2,
8522 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8525 ulCRC = AFSGenerateCRC( ComponentName,
8528 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8532 if( pDirEntry == NULL)
8536 // OK, if this component is a valid short name then try
8537 // a lookup in the short name tree
8540 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8541 RtlIsNameLegalDOS8Dot3( ComponentName,
8546 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8547 AFS_TRACE_LEVEL_VERBOSE_2,
8548 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8551 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8558 if( pDirEntry != NULL)
8560 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8562 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8563 AFS_TRACE_LEVEL_VERBOSE,
8564 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8565 &pDirEntry->NameInformation.FileName,
8570 ASSERT( lCount >= 0);
8573 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8575 if( pDirEntry == NULL)
8578 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8579 AFS_TRACE_LEVEL_VERBOSE_2,
8580 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
8583 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8587 // We have the symlink object but previously failed to process it so return access
8591 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8592 AFS_TRACE_LEVEL_VERBOSE_2,
8593 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8596 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8598 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8600 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8601 AFS_TRACE_LEVEL_VERBOSE,
8602 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8603 &pDirEntry->NameInformation.FileName,
8608 ASSERT( lCount >= 0);
8619 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8620 OUT UNICODE_STRING *ComponentName)
8623 NTSTATUS ntStatus = STATUS_SUCCESS;
8624 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8626 uniFullPathName = *FullPathName;
8631 FsRtlDissectName( uniFullPathName,
8635 if( uniRemainingPath.Length == 0)
8640 uniFullPathName = uniRemainingPath;
8643 if( uniComponentName.Length > 0)
8645 *ComponentName = uniComponentName;
8652 AFSDumpTraceFiles_Default()
8658 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8661 BOOLEAN bIsValidName = TRUE;
8667 while( usIndex < FileName->Length/sizeof( WCHAR))
8670 if( FileName->Buffer[ usIndex] == L':' ||
8671 FileName->Buffer[ usIndex] == L'*' ||
8672 FileName->Buffer[ usIndex] == L'?' ||
8673 FileName->Buffer[ usIndex] == L'"' ||
8674 FileName->Buffer[ usIndex] == L'<' ||
8675 FileName->Buffer[ usIndex] == L'>')
8677 bIsValidName = FALSE;
8685 return bIsValidName;
8689 AFSCreateDefaultSecurityDescriptor()
8692 NTSTATUS ntStatus = STATUS_SUCCESS;
8694 ULONG ulSACLSize = 0;
8695 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8696 ULONG ulACESize = 0;
8697 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8698 ULONG ulSDLength = 0;
8699 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8700 PSID pWorldSID = NULL;
8701 ULONG *pulSubAuthority = NULL;
8702 ULONG ulWorldSIDLEngth = 0;
8707 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8709 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8711 AFS_GENERIC_MEMORY_29_TAG);
8713 if( pWorldSID == NULL)
8715 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8716 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8719 RtlZeroMemory( pWorldSID,
8722 RtlInitializeSid( pWorldSID,
8723 &SeWorldSidAuthority,
8726 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8727 *pulSubAuthority = SECURITY_WORLD_RID;
8729 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8732 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8737 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8739 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8741 AFS_GENERIC_MEMORY_29_TAG);
8746 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8748 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8751 RtlZeroMemory( pACE,
8754 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8755 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8756 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8757 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8759 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8761 SeExports->SeLowMandatorySid);
8763 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8764 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8766 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8768 AFS_GENERIC_MEMORY_29_TAG);
8773 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8775 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8778 ntStatus = RtlCreateAcl( pSACL,
8782 if( !NT_SUCCESS( ntStatus))
8785 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8788 try_return( ntStatus);
8791 ntStatus = RtlAddAce( pSACL,
8795 pACE->Header.AceSize);
8797 if( !NT_SUCCESS( ntStatus))
8800 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8803 try_return( ntStatus);
8807 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8808 sizeof( SECURITY_DESCRIPTOR),
8809 AFS_GENERIC_MEMORY_27_TAG);
8811 if( pSecurityDescr == NULL)
8814 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8816 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8819 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8820 SECURITY_DESCRIPTOR_REVISION);
8822 if( !NT_SUCCESS( ntStatus))
8825 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8828 try_return( ntStatus);
8831 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8833 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8838 if( !NT_SUCCESS( ntStatus))
8841 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8844 try_return( ntStatus);
8849 // Add in the group and owner to the SD
8852 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8854 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8858 if( !NT_SUCCESS( ntStatus))
8861 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8864 try_return( ntStatus);
8868 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8872 if( !NT_SUCCESS( ntStatus))
8875 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8878 try_return( ntStatus);
8881 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8884 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8886 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8889 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8891 AFS_GENERIC_MEMORY_27_TAG);
8893 if( pRelativeSecurityDescr == NULL)
8896 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8898 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8901 ulSDLength = PAGE_SIZE;
8903 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8904 pRelativeSecurityDescr,
8907 if( !NT_SUCCESS( ntStatus))
8910 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8913 try_return( ntStatus);
8916 AFSDefaultSD = pRelativeSecurityDescr;
8920 if( !NT_SUCCESS( ntStatus))
8923 if( pRelativeSecurityDescr != NULL)
8925 ExFreePool( pRelativeSecurityDescr);
8929 if( pSecurityDescr != NULL)
8931 ExFreePool( pSecurityDescr);
8944 if( pWorldSID != NULL)
8946 ExFreePool( pWorldSID);
8954 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8955 OUT UNICODE_STRING *ParentPath)
8958 *ParentPath = *FullFileName;
8961 // If the final character is a \, jump over it
8964 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8966 ParentPath->Length -= sizeof( WCHAR);
8969 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8971 ParentPath->Length -= sizeof( WCHAR);
8975 // And the separator
8978 ParentPath->Length -= sizeof( WCHAR);
8984 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8985 IN AFSObjectInfoCB *ObjectInfo,
8986 IN BOOLEAN WriteAccess,
8987 OUT GUID *AuthGroup)
8990 NTSTATUS ntStatus = STATUS_SUCCESS;
8991 GUID stAuthGroup, stZeroAuthGroup;
8992 BOOLEAN bFoundAuthGroup = FALSE;
8993 AFSCcb *pCcb = NULL;
8999 RtlZeroMemory( &stAuthGroup,
9002 RtlZeroMemory( &stZeroAuthGroup,
9008 if( ObjectInfo != NULL &&
9009 ObjectInfo->Fcb != NULL)
9011 pFcb = ObjectInfo->Fcb;
9018 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
9021 pCcb = Fcb->CcbListHead;
9023 while( pCcb != NULL)
9027 pCcb->GrantedAccess & FILE_WRITE_DATA)
9029 RtlCopyMemory( &stAuthGroup,
9033 bFoundAuthGroup = TRUE;
9037 else if( pCcb->GrantedAccess & FILE_READ_DATA)
9040 // At least get the read-only access
9043 RtlCopyMemory( &stAuthGroup,
9047 bFoundAuthGroup = TRUE;
9050 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9053 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9056 if( !bFoundAuthGroup)
9059 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9060 (ULONGLONG)PsGetCurrentThreadId(),
9063 if( RtlCompareMemory( &stZeroAuthGroup,
9065 sizeof( GUID)) == sizeof( GUID))
9068 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9070 try_return( ntStatus = STATUS_ACCESS_DENIED);
9074 RtlCopyMemory( AuthGroup,
9087 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9088 IN ULONG InvalidateReason)
9091 NTSTATUS ntStatus = STATUS_SUCCESS;
9094 ULONG ulProcessCount = 0;
9100 switch( InvalidateReason)
9103 case AFS_INVALIDATE_DELETED:
9106 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9107 ObjectInfo->Fcb != NULL)
9110 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9113 ObjectInfo->Links = 0;
9115 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9117 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9122 // Clear out the extents
9123 // And get rid of them (note this involves waiting
9124 // for any writes or reads to the cache to complete)
9127 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9130 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9136 case AFS_INVALIDATE_DATA_VERSION:
9139 LARGE_INTEGER liCurrentOffset = {0,0};
9140 LARGE_INTEGER liFlushLength = {0,0};
9141 ULONG ulFlushLength = 0;
9142 BOOLEAN bLocked = FALSE;
9143 BOOLEAN bExtentsLocked = FALSE;
9144 BOOLEAN bCleanExtents = FALSE;
9146 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9147 ObjectInfo->Fcb != NULL)
9150 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9155 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9156 AFS_TRACE_LEVEL_VERBOSE,
9157 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9158 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9159 PsGetCurrentThread());
9161 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9164 bExtentsLocked = TRUE;
9167 // There are several possibilities here:
9169 // 0. If there are no extents or all of the extents are dirty, do nothing.
9171 // 1. There could be nothing dirty and an open reference count of zero
9172 // in which case we can just tear down all of the extents without
9173 // holding any resources.
9175 // 2. There could be nothing dirty and a non-zero open reference count
9176 // in which case we can issue a CcPurge against the entire file
9177 // while holding just the Fcb Resource.
9179 // 3. There can be dirty extents in which case we need to identify
9180 // the non-dirty ranges and then perform a CcPurge on just the
9181 // non-dirty ranges while holding just the Fcb Resource.
9184 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9187 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9190 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9192 bExtentsLocked = FALSE;
9194 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9197 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9201 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9207 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9208 AFS_TRACE_LEVEL_VERBOSE,
9209 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9210 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9211 PsGetCurrentThread());
9213 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9216 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9223 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9224 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9230 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9231 AFS_TRACE_LEVEL_WARNING,
9232 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9233 ObjectInfo->FileId.Cell,
9234 ObjectInfo->FileId.Volume,
9235 ObjectInfo->FileId.Vnode,
9236 ObjectInfo->FileId.Unique);
9238 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9243 bCleanExtents = TRUE;
9246 __except( EXCEPTION_EXECUTE_HANDLER)
9249 ntStatus = GetExceptionCode();
9253 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9254 ObjectInfo->FileId.Cell,
9255 ObjectInfo->FileId.Volume,
9256 ObjectInfo->FileId.Vnode,
9257 ObjectInfo->FileId.Unique,
9260 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9263 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9264 AFS_TRACE_LEVEL_VERBOSE,
9265 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9266 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9267 PsGetCurrentThread());
9269 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9275 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9277 bExtentsLocked = FALSE;
9279 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9280 AFS_TRACE_LEVEL_VERBOSE,
9281 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9282 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9283 PsGetCurrentThread());
9285 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9288 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9293 // Must build a list of non-dirty ranges from the beginning of the file
9294 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9295 // ranges. In all but the most extreme random data write scenario there will
9296 // be significantly fewer.
9298 // For each range we need offset and size.
9301 AFSByteRange * ByteRangeList = NULL;
9302 ULONG ulByteRangeCount = 0;
9304 BOOLEAN bPurgeOnClose = FALSE;
9309 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9312 if ( ByteRangeList != NULL ||
9313 ulByteRangeCount == 0)
9316 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9323 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9325 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9326 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9327 &ByteRangeList[ulIndex].FileOffset,
9332 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9333 AFS_TRACE_LEVEL_WARNING,
9334 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9335 ObjectInfo->FileId.Cell,
9336 ObjectInfo->FileId.Volume,
9337 ObjectInfo->FileId.Vnode,
9338 ObjectInfo->FileId.Unique);
9340 bPurgeOnClose = TRUE;
9345 bCleanExtents = TRUE;
9348 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9350 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9352 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9359 // We couldn't allocate the memory to build the purge list
9360 // so just walk the extent list while holding the ExtentsList Resource.
9361 // This could deadlock but we do not have much choice.
9364 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9366 bExtentsLocked = TRUE;
9368 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9372 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9376 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9378 while( ulProcessCount < ulCount)
9380 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9382 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9384 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9385 &pEntry->FileOffset,
9390 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9391 AFS_TRACE_LEVEL_WARNING,
9392 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9393 ObjectInfo->FileId.Cell,
9394 ObjectInfo->FileId.Volume,
9395 ObjectInfo->FileId.Vnode,
9396 ObjectInfo->FileId.Unique);
9398 bPurgeOnClose = TRUE;
9403 bCleanExtents = TRUE;
9407 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9410 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9412 while( liFlushLength.QuadPart > 0)
9415 if( liFlushLength.QuadPart > 512 * 1024000)
9417 ulFlushLength = 512 * 1024000;
9421 ulFlushLength = liFlushLength.LowPart;
9424 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9430 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9431 AFS_TRACE_LEVEL_WARNING,
9432 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9433 ObjectInfo->FileId.Cell,
9434 ObjectInfo->FileId.Volume,
9435 ObjectInfo->FileId.Vnode,
9436 ObjectInfo->FileId.Unique);
9438 bPurgeOnClose = TRUE;
9443 bCleanExtents = TRUE;
9446 liFlushLength.QuadPart -= ulFlushLength;
9450 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9458 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9464 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9465 AFS_TRACE_LEVEL_WARNING,
9466 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9467 ObjectInfo->FileId.Cell,
9468 ObjectInfo->FileId.Volume,
9469 ObjectInfo->FileId.Vnode,
9470 ObjectInfo->FileId.Unique);
9472 bPurgeOnClose = TRUE;
9477 bCleanExtents = TRUE;
9484 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9488 __except( EXCEPTION_EXECUTE_HANDLER)
9491 ntStatus = GetExceptionCode();
9495 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9496 ObjectInfo->FileId.Cell,
9497 ObjectInfo->FileId.Volume,
9498 ObjectInfo->FileId.Vnode,
9499 ObjectInfo->FileId.Unique,
9503 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9504 AFS_TRACE_LEVEL_VERBOSE,
9505 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9506 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9507 PsGetCurrentThread());
9509 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9513 if ( bExtentsLocked)
9516 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9522 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9528 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9537 if( ObjectInfo != NULL)
9540 AFSObjectInfoDecrement( ObjectInfo);