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 AFSDbgTrace(( 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 AFSDbgTrace(( 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 AFSDbgTrace(( 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,
674 AFS_OBJECT_REFERENCE_GLOBAL);
676 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
677 AFS_TRACE_LEVEL_VERBOSE,
678 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
682 ntStatus = STATUS_SUCCESS;
684 ulEntryLength = sizeof( AFSDirectoryCB) +
687 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
691 if( pDirNode == NULL)
694 AFSDeleteObjectInfo( &pObjectInfoCB);
696 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
697 AFS_TRACE_LEVEL_ERROR,
698 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n"));
700 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
703 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
704 AFS_TRACE_LEVEL_VERBOSE,
705 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocated %p\n",
708 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
709 sizeof( AFSNonPagedDirectoryCB),
710 AFS_DIR_ENTRY_NP_TAG);
712 if( pNonPagedDirEntry == NULL)
715 ExFreePool( pDirNode);
717 AFSDeleteObjectInfo( &pObjectInfoCB);
719 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
720 AFS_TRACE_LEVEL_ERROR,
721 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n"));
723 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
726 RtlZeroMemory( pDirNode,
729 RtlZeroMemory( pNonPagedDirEntry,
730 sizeof( AFSNonPagedDirectoryCB));
732 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
734 pDirNode->NonPaged = pNonPagedDirEntry;
736 pDirNode->ObjectInformation = pObjectInfoCB;
742 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
744 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
747 // Setup the names in the entry
750 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
752 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
754 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
756 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
759 // Populate the rest of the data
762 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
764 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
766 AFSGlobalDotDirEntry = pDirNode;
772 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
775 if( pObjectInfoCB == NULL)
778 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
779 AFS_TRACE_LEVEL_ERROR,
780 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
783 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
786 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
787 AFS_OBJECT_REFERENCE_GLOBAL);
789 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
790 AFS_TRACE_LEVEL_VERBOSE,
791 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
795 ntStatus = STATUS_SUCCESS;
797 ulEntryLength = sizeof( AFSDirectoryCB) +
798 ( 2 * sizeof( WCHAR));
800 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
804 if( pDirNode == NULL)
807 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
808 AFS_TRACE_LEVEL_ERROR,
809 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocation failure\n"));
811 AFSDeleteObjectInfo( &pObjectInfoCB);
813 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
816 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
817 AFS_TRACE_LEVEL_VERBOSE,
818 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocated %p\n",
821 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
822 sizeof( AFSNonPagedDirectoryCB),
823 AFS_DIR_ENTRY_NP_TAG);
825 if( pNonPagedDirEntry == NULL)
828 ExFreePool( pDirNode);
830 AFSDeleteObjectInfo( &pObjectInfoCB);
832 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
835 RtlZeroMemory( pDirNode,
838 RtlZeroMemory( pNonPagedDirEntry,
839 sizeof( AFSNonPagedDirectoryCB));
841 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
843 pDirNode->NonPaged = pNonPagedDirEntry;
845 pDirNode->ObjectInformation = pObjectInfoCB;
851 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
853 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
856 // Setup the names in the entry
859 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
861 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
863 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
865 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
867 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
870 // Populate the rest of the data
873 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
875 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
877 AFSGlobalDotDotDirEntry = pDirNode;
881 if( !NT_SUCCESS( ntStatus))
884 if( AFSGlobalDotDirEntry != NULL)
887 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
889 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
891 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
893 ExFreePool( AFSGlobalDotDirEntry);
895 AFSGlobalDotDirEntry = NULL;
898 if( AFSGlobalDotDotDirEntry != NULL)
901 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
903 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
905 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
907 ExFreePool( AFSGlobalDotDotDirEntry);
909 AFSGlobalDotDotDirEntry = NULL;
918 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
919 IN PUNICODE_STRING FileName,
920 IN PUNICODE_STRING TargetName,
921 IN AFSDirEnumEntry *DirEnumEntry,
925 AFSDirectoryCB *pDirNode = NULL;
926 NTSTATUS ntStatus = STATUS_SUCCESS;
927 ULONG ulEntryLength = 0;
928 AFSObjectInfoCB *pObjectInfoCB = NULL;
929 BOOLEAN bAllocatedObjectCB = FALSE;
930 ULONGLONG ullIndex = 0;
931 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
937 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
938 AFS_TRACE_LEVEL_VERBOSE,
939 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
941 ParentObjectInfo->FileId.Cell,
942 ParentObjectInfo->FileId.Volume,
943 ParentObjectInfo->FileId.Vnode,
944 ParentObjectInfo->FileId.Unique));
947 // First thing is to locate/create our object information block
951 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
954 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
956 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
958 (AFSBTreeEntry **)&pObjectInfoCB);
960 if( !NT_SUCCESS( ntStatus) ||
961 pObjectInfoCB == NULL)
965 // Allocate our object info cb
968 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
971 if( pObjectInfoCB == NULL)
974 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
976 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
979 bAllocatedObjectCB = TRUE;
981 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
982 AFS_TRACE_LEVEL_VERBOSE,
983 "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
989 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
990 AFS_OBJECT_REFERENCE_DIRENTRY);
992 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
993 AFS_TRACE_LEVEL_VERBOSE,
994 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
998 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1000 ntStatus = STATUS_SUCCESS;
1002 ulEntryLength = sizeof( AFSDirectoryCB) +
1005 if( TargetName != NULL)
1008 ulEntryLength += TargetName->Length;
1011 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1015 if( pDirNode == NULL)
1018 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1021 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1022 AFS_TRACE_LEVEL_VERBOSE,
1023 "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
1026 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1027 sizeof( AFSNonPagedDirectoryCB),
1028 AFS_DIR_ENTRY_NP_TAG);
1030 if( pNonPagedDirEntry == NULL)
1033 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1036 RtlZeroMemory( pDirNode,
1039 RtlZeroMemory( pNonPagedDirEntry,
1040 sizeof( AFSNonPagedDirectoryCB));
1042 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1044 pDirNode->NonPaged = pNonPagedDirEntry;
1046 pDirNode->ObjectInformation = pObjectInfoCB;
1049 // Set valid entry and NOT_IN_PARENT flag
1052 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1054 pDirNode->FileIndex = FileIndex;
1057 // Setup the names in the entry
1060 if( FileName->Length > 0)
1063 pDirNode->NameInformation.FileName.Length = FileName->Length;
1065 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1067 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1069 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1071 pDirNode->NameInformation.FileName.Length);
1074 // Create a CRC for the file
1077 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1080 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1084 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1085 AFS_TRACE_LEVEL_VERBOSE,
1086 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1089 ParentObjectInfo->FileId.Cell,
1090 ParentObjectInfo->FileId.Volume,
1091 ParentObjectInfo->FileId.Vnode,
1092 ParentObjectInfo->FileId.Unique));
1094 if( TargetName != NULL &&
1095 TargetName->Length > 0)
1098 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1100 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1102 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1103 sizeof( AFSDirectoryCB) +
1104 pDirNode->NameInformation.FileName.Length);
1106 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1108 pDirNode->NameInformation.TargetName.Length);
1112 // If we allocated the object information cb then update the information
1115 if( bAllocatedObjectCB)
1119 // Populate the rest of the data
1122 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1124 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1126 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1128 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1130 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1132 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1134 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1136 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1138 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1140 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1142 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1143 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1146 pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1149 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
1152 if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1155 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1160 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1164 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1167 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1168 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1172 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1173 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1174 pObjectInfoCB->TargetFileId.Unique == 0 &&
1175 pDirNode->NameInformation.TargetName.Length == 0)
1179 // This will ensure we perform a validation on the node
1182 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1185 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1188 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1193 // Object specific information
1196 pObjectInfoCB->Links = DirEnumEntry->Links;
1198 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1200 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1204 if( !NT_SUCCESS( ntStatus))
1207 if( pNonPagedDirEntry != NULL)
1210 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1212 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1215 if( pDirNode != NULL)
1218 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1219 AFS_TRACE_LEVEL_VERBOSE,
1220 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1223 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1229 // Dereference our object info block if we have one
1232 if( pObjectInfoCB != NULL)
1235 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1236 AFS_OBJECT_REFERENCE_DIRENTRY);
1238 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1239 AFS_TRACE_LEVEL_VERBOSE,
1240 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1244 if( bAllocatedObjectCB)
1247 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1249 AFSDeleteObjectInfo( &pObjectInfoCB);
1259 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1260 IN BOOLEAN DirectoryEntry)
1263 BOOLEAN bReturn = TRUE;
1264 ACCESS_MASK stAccessMask = 0;
1267 // Get rid of anything we don't know about
1270 DesiredAccess = (DesiredAccess &
1276 ACCESS_SYSTEM_SECURITY |
1280 FILE_READ_ATTRIBUTES |
1281 FILE_WRITE_ATTRIBUTES |
1282 FILE_LIST_DIRECTORY |
1288 // Our 'read only' access mask. These are the accesses we will
1289 // allow for a read only file
1292 stAccessMask = DELETE |
1297 ACCESS_SYSTEM_SECURITY |
1301 FILE_READ_ATTRIBUTES |
1302 FILE_WRITE_ATTRIBUTES |
1304 FILE_LIST_DIRECTORY |
1308 // For a directory, add in the directory specific accesses
1314 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1319 if( FlagOn( DesiredAccess, ~stAccessMask))
1323 // A write access is set ...
1333 AFSEvaluateNode( IN GUID *AuthGroup,
1334 IN AFSDirectoryCB *DirEntry)
1337 NTSTATUS ntStatus = STATUS_SUCCESS;
1338 AFSDirEnumEntry *pDirEntry = NULL;
1339 UNICODE_STRING uniTargetName;
1344 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1349 if( !NT_SUCCESS( ntStatus))
1352 try_return( ntStatus);
1355 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1357 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1359 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1361 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1363 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1365 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1367 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1369 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1371 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1373 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1375 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1377 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1378 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1381 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1384 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1387 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1390 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1395 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1399 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1401 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1404 // If we have a target name then see if it needs updating ...
1407 if( pDirEntry->TargetNameLength > 0)
1411 // Update the target name information if needed
1414 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1416 uniTargetName.MaximumLength = uniTargetName.Length;
1418 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1420 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1423 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1424 RtlCompareUnicodeString( &uniTargetName,
1425 &DirEntry->NameInformation.TargetName,
1430 // Update the target name
1433 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1435 uniTargetName.Buffer,
1436 uniTargetName.Length);
1438 if( !NT_SUCCESS( ntStatus))
1441 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1443 try_return( ntStatus);
1447 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1452 if( pDirEntry != NULL)
1455 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1463 AFSValidateSymLink( IN GUID *AuthGroup,
1464 IN AFSDirectoryCB *DirEntry)
1467 NTSTATUS ntStatus = STATUS_SUCCESS;
1468 AFSDirEnumEntry *pDirEntry = NULL;
1469 UNICODE_STRING uniTargetName;
1474 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1479 if( !NT_SUCCESS( ntStatus))
1482 try_return( ntStatus);
1485 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1486 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1489 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1490 AFS_TRACE_LEVEL_VERBOSE_2,
1491 "AFSValidateSymLink Invalid type Status %08lX\n",
1492 STATUS_OBJECT_NAME_NOT_FOUND));
1494 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1497 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1499 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1501 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1504 // Update the target name information if needed
1507 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1509 uniTargetName.MaximumLength = uniTargetName.Length;
1511 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1513 if( uniTargetName.Length > 0)
1516 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1519 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1520 RtlCompareUnicodeString( &uniTargetName,
1521 &DirEntry->NameInformation.TargetName,
1526 // Update the target name
1529 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1531 uniTargetName.Buffer,
1532 uniTargetName.Length);
1534 if( !NT_SUCCESS( ntStatus))
1537 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1539 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1543 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1547 // If the FileType is the same then nothing to do since it IS
1551 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1554 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1556 try_return( ntStatus = STATUS_SUCCESS);
1559 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1561 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1563 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1565 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1567 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1569 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1571 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1573 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1575 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1576 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1579 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1582 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1585 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1588 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1593 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1597 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1599 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1603 if( pDirEntry != NULL)
1606 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1614 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1618 NTSTATUS ntStatus = STATUS_SUCCESS;
1619 IO_STATUS_BLOCK stIoStatus;
1621 AFSObjectInfoCB * pParentObjectInfo = NULL;
1623 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1624 AFS_TRACE_LEVEL_VERBOSE,
1625 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1626 (*ppObjectInfo)->FileType,
1627 (*ppObjectInfo)->FileId.Cell,
1628 (*ppObjectInfo)->FileId.Volume,
1629 (*ppObjectInfo)->FileId.Vnode,
1630 (*ppObjectInfo)->FileId.Unique,
1633 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1636 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1637 &(*ppObjectInfo)->ParentFileId);
1640 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1641 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1642 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1645 // We only act on the mount point itself, not the target. If the
1646 // node has been deleted then mark it as such otherwise indicate
1647 // it requires verification
1650 if( Reason == AFS_INVALIDATE_DELETED)
1652 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1657 if( Reason == AFS_INVALIDATE_FLUSHED)
1660 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1662 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1665 (*ppObjectInfo)->Expiration.QuadPart = 0;
1667 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1669 (*ppObjectInfo)->TargetFileId.Unique = 0;
1671 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1672 AFS_TRACE_LEVEL_VERBOSE,
1673 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1674 (*ppObjectInfo)->FileId.Cell,
1675 (*ppObjectInfo)->FileId.Volume,
1676 (*ppObjectInfo)->FileId.Vnode,
1677 (*ppObjectInfo)->FileId.Unique));
1679 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1682 if ( pParentObjectInfo != NULL)
1685 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1687 if( Reason == AFS_INVALIDATE_CREDS)
1689 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1692 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1693 Reason == AFS_INVALIDATE_FLUSHED)
1695 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1699 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1702 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1705 FILE_ACTION_MODIFIED);
1708 try_return( ntStatus);
1712 // Depending on the reason for invalidation then perform work on the node
1718 case AFS_INVALIDATE_DELETED:
1722 // Mark this node as invalid
1725 (*ppObjectInfo)->Links = 0;
1727 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1729 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1730 AFS_TRACE_LEVEL_VERBOSE,
1731 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1732 (*ppObjectInfo)->FileId.Cell,
1733 (*ppObjectInfo)->FileId.Volume,
1734 (*ppObjectInfo)->FileId.Vnode,
1735 (*ppObjectInfo)->FileId.Unique));
1737 if( pParentObjectInfo != NULL)
1740 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1741 AFS_TRACE_LEVEL_VERBOSE,
1742 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1743 pParentObjectInfo->FileId.Cell,
1744 pParentObjectInfo->FileId.Volume,
1745 pParentObjectInfo->FileId.Vnode,
1746 pParentObjectInfo->FileId.Unique));
1748 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1750 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1752 pParentObjectInfo->Expiration.QuadPart = 0;
1754 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1756 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1760 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1763 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1766 FILE_ACTION_REMOVED);
1769 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1772 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1778 case AFS_INVALIDATE_FLUSHED:
1781 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1782 (*ppObjectInfo)->Fcb != NULL)
1785 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1786 AFS_TRACE_LEVEL_VERBOSE,
1787 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1788 (*ppObjectInfo)->FileId.Cell,
1789 (*ppObjectInfo)->FileId.Volume,
1790 (*ppObjectInfo)->FileId.Vnode,
1791 (*ppObjectInfo)->FileId.Unique));
1793 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1799 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1804 if( !NT_SUCCESS( stIoStatus.Status))
1807 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1808 AFS_TRACE_LEVEL_ERROR,
1809 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1810 (*ppObjectInfo)->FileId.Cell,
1811 (*ppObjectInfo)->FileId.Volume,
1812 (*ppObjectInfo)->FileId.Vnode,
1813 (*ppObjectInfo)->FileId.Unique,
1815 stIoStatus.Information));
1817 ntStatus = stIoStatus.Status;
1821 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1824 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1830 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1831 AFS_TRACE_LEVEL_WARNING,
1832 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1833 (*ppObjectInfo)->FileId.Cell,
1834 (*ppObjectInfo)->FileId.Volume,
1835 (*ppObjectInfo)->FileId.Vnode,
1836 (*ppObjectInfo)->FileId.Unique));
1838 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1842 __except( EXCEPTION_EXECUTE_HANDLER)
1845 ntStatus = GetExceptionCode();
1849 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1850 (*ppObjectInfo)->FileId.Cell,
1851 (*ppObjectInfo)->FileId.Volume,
1852 (*ppObjectInfo)->FileId.Vnode,
1853 (*ppObjectInfo)->FileId.Unique,
1856 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1859 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1862 // Clear out the extents
1863 // Get rid of them (note this involves waiting
1864 // for any writes or reads to the cache to complete)
1867 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1871 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1874 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1877 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1878 AFS_TRACE_LEVEL_VERBOSE,
1879 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1880 (*ppObjectInfo)->FileId.Cell,
1881 (*ppObjectInfo)->FileId.Volume,
1882 (*ppObjectInfo)->FileId.Vnode,
1883 (*ppObjectInfo)->FileId.Unique));
1885 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1888 // Fall through to the default processing
1894 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1896 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1900 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1903 if( Reason == AFS_INVALIDATE_CREDS)
1905 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1908 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1910 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1914 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1917 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1920 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1923 FILE_ACTION_MODIFIED);
1925 else if ( pParentObjectInfo != NULL)
1928 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1931 FILE_ACTION_MODIFIED);
1935 // Indicate this node requires re-evaluation for the remaining reasons
1938 (*ppObjectInfo)->Expiration.QuadPart = 0;
1940 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1941 AFS_TRACE_LEVEL_VERBOSE,
1942 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1943 (*ppObjectInfo)->FileId.Cell,
1944 (*ppObjectInfo)->FileId.Volume,
1945 (*ppObjectInfo)->FileId.Vnode,
1946 (*ppObjectInfo)->FileId.Unique));
1948 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1950 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1951 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1952 ( Reason == AFS_INVALIDATE_CALLBACK ||
1953 Reason == AFS_INVALIDATE_EXPIRED))
1955 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1956 AFS_INVALIDATE_DATA_VERSION)))
1959 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1969 if ( pParentObjectInfo != NULL)
1972 AFSReleaseObjectInfo( &pParentObjectInfo);
1979 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1982 NTSTATUS ntStatus = STATUS_SUCCESS;
1983 AFSVolumeCB *pVolumeCB = NULL;
1984 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1985 ULONGLONG ullIndex = 0;
1986 AFSObjectInfoCB *pObjectInfo = NULL;
1992 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1993 AFS_TRACE_LEVEL_VERBOSE,
1994 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1995 InvalidateCB->FileID.Cell,
1996 InvalidateCB->FileID.Volume,
1997 InvalidateCB->FileID.Vnode,
1998 InvalidateCB->FileID.Unique,
1999 InvalidateCB->FileType,
2000 InvalidateCB->WholeVolume,
2001 InvalidateCB->Reason));
2004 // Need to locate the Fcb for the directory to purge
2007 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2008 AFS_TRACE_LEVEL_VERBOSE,
2009 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2010 &pDevExt->Specific.RDR.VolumeTreeLock,
2011 PsGetCurrentThread()));
2014 // Starve any exclusive waiters on this paticular call
2017 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2020 // Locate the volume node
2023 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2025 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2027 (AFSBTreeEntry **)&pVolumeCB);
2029 if( pVolumeCB != NULL)
2032 lCount = AFSVolumeIncrement( pVolumeCB,
2033 AFS_VOLUME_REFERENCE_INVALIDATE);
2035 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2036 AFS_TRACE_LEVEL_VERBOSE,
2037 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2042 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2044 if( !NT_SUCCESS( ntStatus) ||
2048 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2049 AFS_TRACE_LEVEL_WARNING,
2050 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2051 InvalidateCB->FileID.Cell,
2052 InvalidateCB->FileID.Volume,
2053 InvalidateCB->FileID.Vnode,
2054 InvalidateCB->FileID.Unique,
2057 try_return( ntStatus = STATUS_SUCCESS);
2061 // If this is a whole volume invalidation then go do it now
2064 if( InvalidateCB->WholeVolume)
2067 ntStatus = AFSInvalidateVolume( pVolumeCB,
2068 InvalidateCB->Reason);
2070 try_return( ntStatus);
2073 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
2076 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2079 pObjectInfo = &pVolumeCB->ObjectInformation;
2084 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2086 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2088 (AFSBTreeEntry **)&pObjectInfo);
2091 if( pObjectInfo != NULL)
2095 // Reference the node so it won't be torn down
2098 lCount = AFSObjectInfoIncrement( pObjectInfo,
2099 AFS_OBJECT_REFERENCE_INVALIDATION);
2101 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2102 AFS_TRACE_LEVEL_VERBOSE,
2103 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2108 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2110 if( !NT_SUCCESS( ntStatus) ||
2111 pObjectInfo == NULL)
2114 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2115 AFS_TRACE_LEVEL_VERBOSE,
2116 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2117 InvalidateCB->FileID.Cell,
2118 InvalidateCB->FileID.Volume,
2119 InvalidateCB->FileID.Vnode,
2120 InvalidateCB->FileID.Unique,
2123 try_return( ntStatus = STATUS_SUCCESS);
2126 AFSInvalidateObject( &pObjectInfo,
2127 InvalidateCB->Reason);
2131 if( pObjectInfo != NULL)
2134 lCount = AFSObjectInfoDecrement( pObjectInfo,
2135 AFS_OBJECT_REFERENCE_INVALIDATION);
2137 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2138 AFS_TRACE_LEVEL_VERBOSE,
2139 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2144 if ( pVolumeCB != NULL)
2147 lCount = AFSVolumeDecrement( pVolumeCB,
2148 AFS_VOLUME_REFERENCE_INVALIDATE);
2150 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2151 AFS_TRACE_LEVEL_VERBOSE,
2152 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2162 AFSIsChildOfParent( IN AFSFcb *Dcb,
2166 BOOLEAN bIsChild = FALSE;
2167 AFSFcb *pCurrentFcb = Fcb;
2168 AFSObjectInfoCB * pParentObjectInfo = NULL;
2170 while( pCurrentFcb != NULL)
2173 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2174 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2182 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2183 &pCurrentFcb->ObjectInformation->ParentFileId);
2185 if ( pParentObjectInfo != NULL)
2188 pCurrentFcb = pParentObjectInfo->Fcb;
2190 AFSReleaseObjectInfo( &pParentObjectInfo);
2204 AFSCreateHighIndex( IN AFSFileID *FileID)
2207 ULONGLONG ullIndex = 0;
2209 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2216 AFSCreateLowIndex( IN AFSFileID *FileID)
2219 ULONGLONG ullIndex = 0;
2221 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2227 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2228 IN ACCESS_MASK GrantedAccess,
2229 IN BOOLEAN DirectoryEntry)
2232 BOOLEAN bAccessGranted = TRUE;
2235 // Check if we are asking for read/write and granted only read only
2236 // NOTE: There will be more checks here
2239 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2241 AFSCheckForReadOnlyAccess( GrantedAccess,
2245 bAccessGranted = FALSE;
2248 return bAccessGranted;
2252 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2255 NTSTATUS ntStatus = STATUS_SUCCESS;
2256 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2262 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2264 if( AFSGlobalRoot == NULL)
2271 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2274 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2281 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2288 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2289 IN UNICODE_STRING *SubstituteName,
2290 IN ULONG StringIndex)
2293 NTSTATUS ntStatus = STATUS_SUCCESS;
2294 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2295 AFSSysNameCB *pSysName = NULL;
2296 ERESOURCE *pSysNameLock = NULL;
2299 UNICODE_STRING uniSysName;
2306 if( IoIs32bitProcess( NULL))
2309 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2311 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2316 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2318 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2322 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2324 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2328 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2329 AFS_TRACE_LEVEL_VERBOSE,
2330 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2332 PsGetCurrentThread()));
2334 AFSAcquireShared( pSysNameLock,
2338 // Find where we are in the list
2341 while( pSysName != NULL &&
2342 ulIndex < StringIndex)
2345 pSysName = pSysName->fLink;
2350 if( pSysName == NULL)
2353 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2354 AFS_TRACE_LEVEL_VERBOSE_2,
2355 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2357 STATUS_OBJECT_NAME_NOT_FOUND));
2359 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2362 RtlInitUnicodeString( &uniSysName,
2365 // If it is a full component of @SYS then just substitue the
2369 if( RtlCompareUnicodeString( &uniSysName,
2374 SubstituteName->Length = pSysName->SysName.Length;
2375 SubstituteName->MaximumLength = SubstituteName->Length;
2377 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2378 SubstituteName->Length,
2379 AFS_SUBST_BUFFER_TAG);
2381 if( SubstituteName->Buffer == NULL)
2384 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2387 RtlCopyMemory( SubstituteName->Buffer,
2388 pSysName->SysName.Buffer,
2389 pSysName->SysName.Length);
2396 while( ComponentName->Buffer[ usIndex] != L'@')
2402 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2403 SubstituteName->MaximumLength = SubstituteName->Length;
2405 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2406 SubstituteName->Length,
2407 AFS_SUBST_BUFFER_TAG);
2409 if( SubstituteName->Buffer == NULL)
2412 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2415 RtlCopyMemory( SubstituteName->Buffer,
2416 ComponentName->Buffer,
2417 usIndex * sizeof( WCHAR));
2419 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2420 pSysName->SysName.Buffer,
2421 pSysName->SysName.Length);
2426 AFSReleaseResource( pSysNameLock);
2433 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2434 IN OUT UNICODE_STRING *ComponentName,
2435 IN UNICODE_STRING *SubstituteName,
2436 IN OUT UNICODE_STRING *RemainingPath,
2437 IN BOOLEAN FreePathName)
2440 NTSTATUS ntStatus = STATUS_SUCCESS;
2441 UNICODE_STRING uniPathName;
2442 USHORT usPrefixNameLen = 0;
2443 SHORT sNameLenDelta = 0;
2449 // If the passed in name can handle the additional length
2450 // then just moves things around
2453 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2455 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2457 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2460 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2463 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2464 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2465 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2468 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2469 SubstituteName->Buffer,
2470 SubstituteName->Length);
2472 FullPathName->Length += sNameLenDelta;
2474 ComponentName->Length += sNameLenDelta;
2476 ComponentName->MaximumLength = ComponentName->Length;
2478 if ( RemainingPath->Buffer)
2481 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2484 try_return( ntStatus);
2488 // Need to re-allocate the buffer
2491 uniPathName.Length = FullPathName->Length -
2492 ComponentName->Length +
2493 SubstituteName->Length;
2495 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2497 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2498 uniPathName.MaximumLength,
2499 AFS_NAME_BUFFER_FOUR_TAG);
2501 if( uniPathName.Buffer == NULL)
2504 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2507 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2509 usPrefixNameLen *= sizeof( WCHAR);
2511 RtlZeroMemory( uniPathName.Buffer,
2512 uniPathName.MaximumLength);
2514 RtlCopyMemory( uniPathName.Buffer,
2515 FullPathName->Buffer,
2518 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2519 SubstituteName->Buffer,
2520 SubstituteName->Length);
2522 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2525 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2526 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2527 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2530 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2532 ComponentName->Length += sNameLenDelta;
2534 ComponentName->MaximumLength = ComponentName->Length;
2536 if ( RemainingPath->Buffer)
2539 RemainingPath->Buffer = uniPathName.Buffer
2540 + (RemainingPath->Buffer - FullPathName->Buffer)
2541 + sNameLenDelta/sizeof( WCHAR);
2546 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2549 *FullPathName = uniPathName;
2560 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2564 NTSTATUS ntStatus = STATUS_SUCCESS;
2565 AFSObjectInfoCB *pCurrentObject = NULL;
2566 AFSObjectInfoCB *pNextObject = NULL;
2572 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2573 AFS_TRACE_LEVEL_VERBOSE,
2574 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2575 VolumeCB->ObjectInformation.FileId.Cell,
2576 VolumeCB->ObjectInformation.FileId.Volume,
2577 VolumeCB->ObjectInformation.FileId.Vnode,
2578 VolumeCB->ObjectInformation.FileId.Unique,
2582 // Depending on the reason for invalidation then perform work on the node
2588 case AFS_INVALIDATE_DELETED:
2592 // Mark this volume as invalid
2595 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2597 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2604 // Invalidate the volume root directory
2607 pCurrentObject = &VolumeCB->ObjectInformation;
2609 if ( pCurrentObject )
2612 lCount = AFSObjectInfoIncrement( pCurrentObject,
2613 AFS_OBJECT_REFERENCE_INVALIDATION);
2615 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2616 AFS_TRACE_LEVEL_VERBOSE,
2617 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2621 AFSInvalidateObject( &pCurrentObject,
2624 if ( pCurrentObject)
2627 lCount = AFSObjectInfoDecrement( pCurrentObject,
2628 AFS_OBJECT_REFERENCE_INVALIDATION);
2630 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2631 AFS_TRACE_LEVEL_VERBOSE,
2632 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2639 // Apply invalidation to all other volume objects
2642 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2645 pCurrentObject = VolumeCB->ObjectInfoListHead;
2647 if ( pCurrentObject)
2651 // Reference the node so it won't be torn down
2654 lCount = AFSObjectInfoIncrement( pCurrentObject,
2655 AFS_OBJECT_REFERENCE_INVALIDATION);
2657 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2658 AFS_TRACE_LEVEL_VERBOSE,
2659 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2664 while( pCurrentObject != NULL)
2667 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2673 // Reference the node so it won't be torn down
2676 lCount = AFSObjectInfoIncrement( pNextObject,
2677 AFS_OBJECT_REFERENCE_INVALIDATION);
2679 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2680 AFS_TRACE_LEVEL_VERBOSE,
2681 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2686 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2688 AFSInvalidateObject( &pCurrentObject,
2691 if ( pCurrentObject )
2694 lCount = AFSObjectInfoDecrement( pCurrentObject,
2695 AFS_OBJECT_REFERENCE_INVALIDATION);
2697 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2698 AFS_TRACE_LEVEL_VERBOSE,
2699 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2704 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2707 pCurrentObject = pNextObject;
2710 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2717 AFSInvalidateAllVolumes( VOID)
2719 AFSVolumeCB *pVolumeCB = NULL;
2720 AFSVolumeCB *pNextVolumeCB = NULL;
2721 AFSDeviceExt *pRDRDeviceExt = NULL;
2724 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2726 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2727 AFS_TRACE_LEVEL_VERBOSE,
2728 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2729 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2730 PsGetCurrentThread()));
2732 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2735 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2740 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2741 AFS_TRACE_LEVEL_VERBOSE,
2742 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2743 pVolumeCB->ObjectInfoTree.TreeLock,
2744 PsGetCurrentThread()));
2746 lCount = AFSVolumeIncrement( pVolumeCB,
2747 AFS_VOLUME_REFERENCE_INVALIDATE);
2749 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2750 AFS_TRACE_LEVEL_VERBOSE,
2751 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2756 while( pVolumeCB != NULL)
2759 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2764 lCount = AFSVolumeIncrement( pNextVolumeCB,
2765 AFS_VOLUME_REFERENCE_INVALIDATE);
2767 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2768 AFS_TRACE_LEVEL_VERBOSE,
2769 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2774 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2776 // do I need to hold the volume lock here?
2778 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2780 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2783 lCount = AFSVolumeDecrement( pVolumeCB,
2784 AFS_VOLUME_REFERENCE_INVALIDATE);
2786 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2787 AFS_TRACE_LEVEL_VERBOSE,
2788 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2792 pVolumeCB = pNextVolumeCB;
2795 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2799 AFSVerifyEntry( IN GUID *AuthGroup,
2800 IN AFSDirectoryCB *DirEntry)
2803 NTSTATUS ntStatus = STATUS_SUCCESS;
2804 AFSDirEnumEntry *pDirEnumEntry = NULL;
2805 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2806 IO_STATUS_BLOCK stIoStatus;
2811 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2812 AFS_TRACE_LEVEL_VERBOSE_2,
2813 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2814 &DirEntry->NameInformation.FileName,
2815 pObjectInfo->FileId.Cell,
2816 pObjectInfo->FileId.Volume,
2817 pObjectInfo->FileId.Vnode,
2818 pObjectInfo->FileId.Unique));
2820 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2825 if( !NT_SUCCESS( ntStatus))
2828 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2829 AFS_TRACE_LEVEL_ERROR,
2830 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2831 &DirEntry->NameInformation.FileName,
2832 pObjectInfo->FileId.Cell,
2833 pObjectInfo->FileId.Volume,
2834 pObjectInfo->FileId.Vnode,
2835 pObjectInfo->FileId.Unique,
2838 try_return( ntStatus);
2842 // Check the data version of the file
2845 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2847 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2850 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2851 AFS_TRACE_LEVEL_VERBOSE,
2852 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2853 pObjectInfo->DataVersion.QuadPart,
2854 &DirEntry->NameInformation.FileName,
2855 pObjectInfo->FileId.Cell,
2856 pObjectInfo->FileId.Volume,
2857 pObjectInfo->FileId.Vnode,
2858 pObjectInfo->FileId.Unique));
2861 // We are ok, just get out
2864 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2866 try_return( ntStatus = STATUS_SUCCESS);
2871 // New data version so we will need to process the node based on the type
2874 switch( pDirEnumEntry->FileType)
2877 case AFS_FILE_TYPE_MOUNTPOINT:
2881 // For a mount point we need to ensure the target is the same
2884 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2885 &pDirEnumEntry->TargetFileId))
2891 // Update the metadata for the entry
2894 ntStatus = AFSUpdateMetaData( DirEntry,
2897 if( NT_SUCCESS( ntStatus))
2900 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2906 case AFS_FILE_TYPE_SYMLINK:
2910 // Update the metadata for the entry
2913 ntStatus = AFSUpdateMetaData( DirEntry,
2916 if( NT_SUCCESS( ntStatus))
2919 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2925 case AFS_FILE_TYPE_FILE:
2927 FILE_OBJECT * pCCFileObject = NULL;
2928 BOOLEAN bPurgeExtents = FALSE;
2930 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
2933 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2934 AFS_TRACE_LEVEL_VERBOSE,
2935 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
2936 &DirEntry->NameInformation.FileName,
2937 pObjectInfo->FileId.Cell,
2938 pObjectInfo->FileId.Volume,
2939 pObjectInfo->FileId.Vnode,
2940 pObjectInfo->FileId.Unique,
2941 pObjectInfo->DataVersion.LowPart,
2942 pDirEnumEntry->DataVersion.LowPart));
2944 bPurgeExtents = TRUE;
2947 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2950 bPurgeExtents = TRUE;
2952 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2953 AFS_TRACE_LEVEL_VERBOSE,
2954 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2955 &DirEntry->NameInformation.FileName,
2956 pObjectInfo->FileId.Cell,
2957 pObjectInfo->FileId.Volume,
2958 pObjectInfo->FileId.Vnode,
2959 pObjectInfo->FileId.Unique));
2961 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2964 if( pObjectInfo->Fcb != NULL)
2967 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2968 AFS_TRACE_LEVEL_VERBOSE,
2969 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2970 &DirEntry->NameInformation.FileName,
2971 pObjectInfo->FileId.Cell,
2972 pObjectInfo->FileId.Volume,
2973 pObjectInfo->FileId.Vnode,
2974 pObjectInfo->FileId.Unique));
2976 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2982 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2987 if( !NT_SUCCESS( stIoStatus.Status))
2990 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
2991 AFS_TRACE_LEVEL_ERROR,
2992 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2993 &DirEntry->NameInformation.FileName,
2994 pObjectInfo->FileId.Cell,
2995 pObjectInfo->FileId.Volume,
2996 pObjectInfo->FileId.Vnode,
2997 pObjectInfo->FileId.Unique,
2999 stIoStatus.Information));
3001 ntStatus = stIoStatus.Status;
3004 if ( bPurgeExtents &&
3005 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3008 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3014 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3015 AFS_TRACE_LEVEL_WARNING,
3016 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3017 &DirEntry->NameInformation.FileName,
3018 pObjectInfo->FileId.Cell,
3019 pObjectInfo->FileId.Volume,
3020 pObjectInfo->FileId.Vnode,
3021 pObjectInfo->FileId.Unique));
3023 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3027 __except( EXCEPTION_EXECUTE_HANDLER)
3029 ntStatus = GetExceptionCode();
3033 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3034 &DirEntry->NameInformation.FileName,
3035 pObjectInfo->FileId.Cell,
3036 pObjectInfo->FileId.Volume,
3037 pObjectInfo->FileId.Vnode,
3038 pObjectInfo->FileId.Unique,
3041 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3044 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3048 AFSFlushExtents( pObjectInfo->Fcb,
3053 // Reacquire the Fcb to purge the cache
3056 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3057 AFS_TRACE_LEVEL_VERBOSE,
3058 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3059 &pObjectInfo->Fcb->NPFcb->Resource,
3060 PsGetCurrentThread()));
3062 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3066 // Update the metadata for the entry
3069 ntStatus = AFSUpdateMetaData( DirEntry,
3072 if( !NT_SUCCESS( ntStatus))
3075 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3076 AFS_TRACE_LEVEL_ERROR,
3077 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3078 &DirEntry->NameInformation.FileName,
3079 pObjectInfo->FileId.Cell,
3080 pObjectInfo->FileId.Volume,
3081 pObjectInfo->FileId.Vnode,
3082 pObjectInfo->FileId.Unique,
3089 // Update file sizes
3092 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3093 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3094 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3096 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3097 AFS_TRACE_LEVEL_VERBOSE,
3098 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3099 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3100 PsGetCurrentThread()));
3102 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3105 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3107 if ( pCCFileObject != NULL)
3109 CcSetFileSizes( pCCFileObject,
3110 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3113 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3114 AFS_TRACE_LEVEL_VERBOSE,
3115 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3116 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3117 PsGetCurrentThread()));
3119 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3121 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3127 // Update the metadata for the entry
3130 ntStatus = AFSUpdateMetaData( DirEntry,
3133 if( !NT_SUCCESS( ntStatus))
3136 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3137 AFS_TRACE_LEVEL_ERROR,
3138 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3139 &DirEntry->NameInformation.FileName,
3140 pObjectInfo->FileId.Cell,
3141 pObjectInfo->FileId.Volume,
3142 pObjectInfo->FileId.Vnode,
3143 pObjectInfo->FileId.Unique,
3149 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3150 AFS_TRACE_LEVEL_WARNING,
3151 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3152 &DirEntry->NameInformation.FileName,
3153 pObjectInfo->FileId.Cell,
3154 pObjectInfo->FileId.Volume,
3155 pObjectInfo->FileId.Vnode,
3156 pObjectInfo->FileId.Unique));
3159 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3164 case AFS_FILE_TYPE_DIRECTORY:
3168 // For a directory or root entry flush the content of
3169 // the directory enumeration.
3172 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3175 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3176 AFS_TRACE_LEVEL_VERBOSE_2,
3177 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3178 &DirEntry->NameInformation.FileName,
3179 pObjectInfo->FileId.Cell,
3180 pObjectInfo->FileId.Volume,
3181 pObjectInfo->FileId.Vnode,
3182 pObjectInfo->FileId.Unique));
3184 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3187 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3190 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3192 if ( !NT_SUCCESS( ntStatus))
3195 try_return( ntStatus);
3200 // Update the metadata for the entry
3203 ntStatus = AFSUpdateMetaData( DirEntry,
3206 if( NT_SUCCESS( ntStatus))
3209 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3215 case AFS_FILE_TYPE_DFSLINK:
3218 UNICODE_STRING uniTargetName;
3221 // For a DFS link need to check the target name has not changed
3224 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3226 uniTargetName.MaximumLength = uniTargetName.Length;
3228 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3230 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3233 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3234 RtlCompareUnicodeString( &uniTargetName,
3235 &DirEntry->NameInformation.TargetName,
3240 // Update the target name
3243 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3245 uniTargetName.Buffer,
3246 uniTargetName.Length);
3248 if( !NT_SUCCESS( ntStatus))
3251 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3257 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3260 // Update the metadata for the entry
3263 ntStatus = AFSUpdateMetaData( DirEntry,
3266 if( NT_SUCCESS( ntStatus))
3269 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3277 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3278 AFS_TRACE_LEVEL_WARNING,
3279 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3280 pObjectInfo->FileType,
3281 &DirEntry->NameInformation.FileName,
3282 pObjectInfo->FileId.Cell,
3283 pObjectInfo->FileId.Volume,
3284 pObjectInfo->FileId.Vnode,
3285 pObjectInfo->FileId.Unique));
3292 if( pDirEnumEntry != NULL)
3295 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3303 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3306 NTSTATUS ntStatus = STATUS_SUCCESS;
3307 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3308 ULONGLONG ullIndex = 0;
3309 AFSVolumeCB *pVolumeCB = NULL;
3315 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3316 AFS_TRACE_LEVEL_VERBOSE,
3317 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3318 VolumeStatus->Online,
3319 VolumeStatus->FileID.Cell,
3320 VolumeStatus->FileID.Volume));
3323 // Need to locate the Fcb for the directory to purge
3326 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3327 AFS_TRACE_LEVEL_VERBOSE,
3328 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3329 &pDevExt->Specific.RDR.VolumeTreeLock,
3330 PsGetCurrentThread()));
3332 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3335 // Locate the volume node
3338 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3340 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3342 (AFSBTreeEntry **)&pVolumeCB);
3344 if( pVolumeCB != NULL)
3347 lCount = AFSVolumeIncrement( pVolumeCB,
3348 AFS_VOLUME_REFERENCE_INVALIDATE);
3350 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3351 AFS_TRACE_LEVEL_VERBOSE,
3352 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3356 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3359 // Set the volume state accordingly
3362 if( VolumeStatus->Online)
3365 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3370 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3379 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3382 NTSTATUS ntStatus = STATUS_SUCCESS;
3387 if( AFSGlobalRoot == NULL)
3390 try_return( ntStatus);
3393 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3397 // Set the network state according to the information
3400 if( NetworkStatus->Online)
3403 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3408 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3411 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3422 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3426 NTSTATUS ntStatus = STATUS_SUCCESS;
3427 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3428 BOOLEAN bAcquiredLock = FALSE;
3429 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3434 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3435 AFS_TRACE_LEVEL_VERBOSE,
3436 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3437 ObjectInfo->FileId.Cell,
3438 ObjectInfo->FileId.Volume,
3439 ObjectInfo->FileId.Vnode,
3440 ObjectInfo->FileId.Unique));
3442 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3445 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3446 AFS_TRACE_LEVEL_VERBOSE,
3447 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3448 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3449 PsGetCurrentThread()));
3451 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3454 bAcquiredLock = TRUE;
3458 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3461 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3462 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3465 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3466 AFS_TRACE_LEVEL_ERROR,
3467 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3468 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3469 ObjectInfo->FileId.Cell,
3470 ObjectInfo->FileId.Volume,
3471 ObjectInfo->FileId.Vnode,
3472 ObjectInfo->FileId.Unique));
3476 // Reset the directory list information by clearing all valid entries
3479 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3481 while( pCurrentDirEntry != NULL)
3484 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3486 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3490 // If this entry has been deleted then process it here
3493 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3494 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3495 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3498 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3499 AFS_TRACE_LEVEL_VERBOSE,
3500 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3502 &pCurrentDirEntry->NameInformation.FileName));
3504 AFSDeleteDirEntry( ObjectInfo,
3510 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3512 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3513 AFS_TRACE_LEVEL_VERBOSE,
3514 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3516 pCurrentDirEntry->DirOpenReferenceCount));
3519 // We pull the short name from the parent tree since it could change below
3522 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3525 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3526 AFS_TRACE_LEVEL_VERBOSE,
3527 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3529 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3530 &pCurrentDirEntry->NameInformation.FileName));
3532 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3535 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3540 pCurrentDirEntry = pNextDirEntry;
3544 // Reget the directory contents
3547 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3550 if ( !NT_SUCCESS( ntStatus))
3552 try_return( ntStatus);
3556 // Now start again and tear down any entries not valid
3559 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3561 while( pCurrentDirEntry != NULL)
3564 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3566 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3569 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3570 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3571 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3574 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3577 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3579 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3580 AFS_TRACE_LEVEL_VERBOSE,
3581 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3583 &pCurrentDirEntry->NameInformation.FileName));
3585 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3590 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3593 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3594 AFS_TRACE_LEVEL_VERBOSE,
3595 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3597 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3598 &pCurrentDirEntry->NameInformation.FileName));
3602 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3604 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3605 AFS_TRACE_LEVEL_VERBOSE,
3606 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3608 &pCurrentDirEntry->NameInformation.FileName));
3613 pCurrentDirEntry = pNextDirEntry;
3618 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3619 AFS_TRACE_LEVEL_VERBOSE,
3620 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3622 pCurrentDirEntry->DirOpenReferenceCount));
3624 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3625 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3628 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3629 AFS_TRACE_LEVEL_VERBOSE,
3630 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3631 &pCurrentDirEntry->NameInformation.FileName,
3632 ObjectInfo->FileId.Cell,
3633 ObjectInfo->FileId.Volume,
3634 ObjectInfo->FileId.Vnode,
3635 ObjectInfo->FileId.Unique));
3637 AFSDeleteDirEntry( ObjectInfo,
3643 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3644 AFS_TRACE_LEVEL_VERBOSE,
3645 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3647 &pCurrentDirEntry->NameInformation.FileName,
3648 ObjectInfo->FileId.Cell,
3649 ObjectInfo->FileId.Volume,
3650 ObjectInfo->FileId.Vnode,
3651 ObjectInfo->FileId.Unique));
3653 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3655 AFSRemoveNameEntry( ObjectInfo,
3659 pCurrentDirEntry = pNextDirEntry;
3663 if( !AFSValidateDirList( ObjectInfo))
3666 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3675 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3683 AFSIsVolumeFID( IN AFSFileID *FileID)
3686 BOOLEAN bIsVolume = FALSE;
3688 if( FileID->Vnode == 1 &&
3689 FileID->Unique == 1)
3699 AFSIsFinalNode( IN AFSFcb *Fcb)
3702 BOOLEAN bIsFinalNode = FALSE;
3704 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3705 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3706 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3707 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3708 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3711 bIsFinalNode = TRUE;
3716 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3717 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3720 return bIsFinalNode;
3724 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3725 IN AFSDirEnumEntry *DirEnumEntry)
3728 NTSTATUS ntStatus = STATUS_SUCCESS;
3729 UNICODE_STRING uniTargetName;
3730 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3735 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3737 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3739 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3741 pObjectInfo->FileType = DirEnumEntry->FileType;
3743 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3745 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3747 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3749 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3751 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3753 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3755 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3757 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3758 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3761 pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3764 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
3767 if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
3770 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3775 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3779 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3781 pObjectInfo->Links = DirEnumEntry->Links;
3783 if( DirEnumEntry->TargetNameLength > 0 &&
3784 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3785 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3789 // Update the target name information if needed
3792 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3794 uniTargetName.MaximumLength = uniTargetName.Length;
3796 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3798 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3801 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3802 RtlCompareUnicodeString( &uniTargetName,
3803 &DirEntry->NameInformation.TargetName,
3808 // Update the target name
3811 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3813 uniTargetName.Buffer,
3814 uniTargetName.Length);
3816 if( !NT_SUCCESS( ntStatus))
3819 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3821 try_return( ntStatus);
3825 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3827 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3828 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3831 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3834 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3835 DirEntry->NameInformation.TargetName.Buffer != NULL)
3837 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3840 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3842 DirEntry->NameInformation.TargetName.Length = 0;
3843 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3844 DirEntry->NameInformation.TargetName.Buffer = NULL;
3846 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3858 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3860 IN BOOLEAN FastCall,
3861 IN BOOLEAN bSafeToPurge)
3864 NTSTATUS ntStatus = STATUS_SUCCESS;
3865 LARGE_INTEGER liSystemTime;
3866 AFSDirEnumEntry *pDirEnumEntry = NULL;
3867 AFSFcb *pCurrentFcb = NULL;
3868 BOOLEAN bReleaseFcb = FALSE;
3869 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3875 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3879 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3880 AFS_TRACE_LEVEL_VERBOSE_2,
3881 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3882 &DirEntry->NameInformation.FileName,
3883 pObjectInfo->FileId.Cell,
3884 pObjectInfo->FileId.Volume,
3885 pObjectInfo->FileId.Vnode,
3886 pObjectInfo->FileId.Unique,
3890 // If this is a fake node then bail since the service knows nothing about it
3893 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3896 try_return( ntStatus);
3900 // This routine ensures that the current entry is valid by:
3902 // 1) Checking that the expiration time is non-zero and after where we
3906 KeQuerySystemTime( &liSystemTime);
3908 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3909 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3910 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3911 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3914 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3915 AFS_TRACE_LEVEL_VERBOSE_2,
3916 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3917 &DirEntry->NameInformation.FileName,
3918 pObjectInfo->FileId.Cell,
3919 pObjectInfo->FileId.Volume,
3920 pObjectInfo->FileId.Vnode,
3921 pObjectInfo->FileId.Unique));
3923 try_return( ntStatus);
3927 // This node requires updating
3930 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3935 if( !NT_SUCCESS( ntStatus))
3938 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3939 AFS_TRACE_LEVEL_ERROR,
3940 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3942 &DirEntry->NameInformation.FileName,
3943 pObjectInfo->FileId.Cell,
3944 pObjectInfo->FileId.Volume,
3945 pObjectInfo->FileId.Vnode,
3946 pObjectInfo->FileId.Unique,
3950 // Failed validation of node so return access-denied
3953 try_return( ntStatus);
3956 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3957 AFS_TRACE_LEVEL_VERBOSE,
3958 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3960 &DirEntry->NameInformation.FileName,
3961 pObjectInfo->FileId.Cell,
3962 pObjectInfo->FileId.Volume,
3963 pObjectInfo->FileId.Vnode,
3964 pObjectInfo->FileId.Unique,
3965 pObjectInfo->DataVersion.QuadPart,
3966 pDirEnumEntry->DataVersion.QuadPart,
3967 pDirEnumEntry->FileType));
3971 // Based on the file type, process the node
3974 switch( pDirEnumEntry->FileType)
3977 case AFS_FILE_TYPE_MOUNTPOINT:
3981 // Update the metadata for the entry
3984 ntStatus = AFSUpdateMetaData( DirEntry,
3987 if( NT_SUCCESS( ntStatus))
3990 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3996 case AFS_FILE_TYPE_SYMLINK:
3997 case AFS_FILE_TYPE_DFSLINK:
4001 // Update the metadata for the entry
4004 ntStatus = AFSUpdateMetaData( DirEntry,
4007 if( NT_SUCCESS( ntStatus))
4010 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4016 case AFS_FILE_TYPE_FILE:
4019 BOOLEAN bPurgeExtents = FALSE;
4022 // For a file where the data version has become invalid we need to
4023 // fail any current extent requests and purge the cache for the file
4024 // Can't hold the Fcb resource while doing this
4027 if( pObjectInfo->Fcb != NULL &&
4028 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4029 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4032 pCurrentFcb = pObjectInfo->Fcb;
4034 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4037 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4038 AFS_TRACE_LEVEL_VERBOSE,
4039 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4040 &pCurrentFcb->NPFcb->Resource,
4041 PsGetCurrentThread()));
4043 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4049 if( pCurrentFcb != NULL)
4052 IO_STATUS_BLOCK stIoStatus;
4054 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4055 AFS_TRACE_LEVEL_VERBOSE_2,
4056 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4057 &DirEntry->NameInformation.FileName,
4058 pObjectInfo->FileId.Cell,
4059 pObjectInfo->FileId.Volume,
4060 pObjectInfo->FileId.Vnode,
4061 pObjectInfo->FileId.Unique));
4063 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4066 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4067 AFS_TRACE_LEVEL_VERBOSE,
4068 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4069 &DirEntry->NameInformation.FileName,
4070 pObjectInfo->FileId.Cell,
4071 pObjectInfo->FileId.Volume,
4072 pObjectInfo->FileId.Vnode,
4073 pObjectInfo->FileId.Unique,
4074 pObjectInfo->DataVersion.LowPart,
4075 pDirEnumEntry->DataVersion.LowPart));
4077 bPurgeExtents = TRUE;
4083 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4085 bPurgeExtents = TRUE;
4087 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4088 AFS_TRACE_LEVEL_VERBOSE,
4089 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4090 &DirEntry->NameInformation.FileName,
4091 pObjectInfo->FileId.Cell,
4092 pObjectInfo->FileId.Volume,
4093 pObjectInfo->FileId.Vnode,
4094 pObjectInfo->FileId.Unique));
4096 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4099 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4100 AFS_TRACE_LEVEL_VERBOSE,
4101 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4102 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4103 PsGetCurrentThread()));
4105 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4109 // Release Fcb->Resource to avoid Trend Micro deadlock
4112 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
4117 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4122 if( !NT_SUCCESS( stIoStatus.Status))
4125 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4126 AFS_TRACE_LEVEL_ERROR,
4127 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4128 &DirEntry->NameInformation.FileName,
4129 pObjectInfo->FileId.Cell,
4130 pObjectInfo->FileId.Volume,
4131 pObjectInfo->FileId.Vnode,
4132 pObjectInfo->FileId.Unique,
4134 stIoStatus.Information));
4136 ntStatus = stIoStatus.Status;
4139 if ( bPurgeExtents &&
4140 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4143 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4149 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4150 AFS_TRACE_LEVEL_WARNING,
4151 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4152 &DirEntry->NameInformation.FileName,
4153 pObjectInfo->FileId.Cell,
4154 pObjectInfo->FileId.Volume,
4155 pObjectInfo->FileId.Vnode,
4156 pObjectInfo->FileId.Unique));
4158 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4162 __except( EXCEPTION_EXECUTE_HANDLER)
4164 ntStatus = GetExceptionCode();
4168 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4169 &DirEntry->NameInformation.FileName,
4170 pObjectInfo->FileId.Cell,
4171 pObjectInfo->FileId.Volume,
4172 pObjectInfo->FileId.Vnode,
4173 pObjectInfo->FileId.Unique,
4176 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4179 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4180 AFS_TRACE_LEVEL_VERBOSE,
4181 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4182 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4183 PsGetCurrentThread()));
4185 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4187 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4196 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4201 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4203 bReleaseFcb = FALSE;
4205 if ( bPurgeExtents &&
4208 AFSFlushExtents( pCurrentFcb,
4215 // Update the metadata for the entry but only if it is safe to do so.
4216 // If it was determined that a data version change has occurred or
4217 // that a pending data verification was required, do not update the
4218 // ObjectInfo meta data or the FileObject size information. That
4219 // way it is consistent for the next time that the data is verified
4223 if ( !(bPurgeExtents && bSafeToPurge))
4226 ntStatus = AFSUpdateMetaData( DirEntry,
4229 if( !NT_SUCCESS( ntStatus))
4232 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4233 AFS_TRACE_LEVEL_ERROR,
4234 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4235 &DirEntry->NameInformation.FileName,
4236 pObjectInfo->FileId.Cell,
4237 pObjectInfo->FileId.Volume,
4238 pObjectInfo->FileId.Vnode,
4239 pObjectInfo->FileId.Unique,
4245 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4248 // Update file sizes
4251 if( pObjectInfo->Fcb != NULL)
4253 FILE_OBJECT *pCCFileObject;
4255 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4256 AFS_TRACE_LEVEL_VERBOSE,
4257 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4258 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4259 PsGetCurrentThread()));
4261 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4264 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4266 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4267 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4268 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4270 if ( pCCFileObject != NULL)
4272 CcSetFileSizes( pCCFileObject,
4273 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4276 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4277 AFS_TRACE_LEVEL_VERBOSE,
4278 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4279 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4280 PsGetCurrentThread()));
4282 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4288 case AFS_FILE_TYPE_DIRECTORY:
4291 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4295 // For a directory or root entry flush the content of
4296 // the directory enumeration.
4299 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4300 AFS_TRACE_LEVEL_VERBOSE,
4301 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4302 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4303 PsGetCurrentThread()));
4305 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4308 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4309 AFS_TRACE_LEVEL_VERBOSE_2,
4310 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4311 &DirEntry->NameInformation.FileName,
4312 pObjectInfo->FileId.Cell,
4313 pObjectInfo->FileId.Volume,
4314 pObjectInfo->FileId.Vnode,
4315 pObjectInfo->FileId.Unique));
4317 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4320 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4323 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4326 if( !NT_SUCCESS( ntStatus))
4329 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4330 AFS_TRACE_LEVEL_ERROR,
4331 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4332 &DirEntry->NameInformation.FileName,
4333 pObjectInfo->FileId.Cell,
4334 pObjectInfo->FileId.Volume,
4335 pObjectInfo->FileId.Vnode,
4336 pObjectInfo->FileId.Unique,
4344 // Update the metadata for the entry
4347 ntStatus = AFSUpdateMetaData( DirEntry,
4350 if( NT_SUCCESS( ntStatus))
4353 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4361 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4362 AFS_TRACE_LEVEL_WARNING,
4363 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4364 pObjectInfo->FileType,
4366 &DirEntry->NameInformation.FileName,
4367 pObjectInfo->FileId.Cell,
4368 pObjectInfo->FileId.Volume,
4369 pObjectInfo->FileId.Vnode,
4370 pObjectInfo->FileId.Unique));
4380 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4383 if( pDirEnumEntry != NULL)
4386 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4394 AFSInitializeSpecialShareNameList()
4397 NTSTATUS ntStatus = STATUS_SUCCESS;
4398 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4399 AFSObjectInfoCB *pObjectInfoCB = NULL;
4400 UNICODE_STRING uniShareName;
4401 ULONG ulEntryLength = 0;
4402 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4408 RtlInitUnicodeString( &uniShareName,
4411 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4414 if( pObjectInfoCB == NULL)
4417 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4420 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4421 AFS_OBJECT_REFERENCE_GLOBAL);
4423 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4424 AFS_TRACE_LEVEL_VERBOSE,
4425 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4429 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4431 ulEntryLength = sizeof( AFSDirectoryCB) +
4432 uniShareName.Length;
4434 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4438 if( pDirNode == NULL)
4441 AFSDeleteObjectInfo( &pObjectInfoCB);
4443 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4446 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4447 AFS_TRACE_LEVEL_VERBOSE,
4448 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4451 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4452 sizeof( AFSNonPagedDirectoryCB),
4453 AFS_DIR_ENTRY_NP_TAG);
4455 if( pNonPagedDirEntry == NULL)
4458 ExFreePool( pDirNode);
4460 AFSDeleteObjectInfo( &pObjectInfoCB);
4462 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4465 RtlZeroMemory( pDirNode,
4468 RtlZeroMemory( pNonPagedDirEntry,
4469 sizeof( AFSNonPagedDirectoryCB));
4471 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4473 pDirNode->NonPaged = pNonPagedDirEntry;
4475 pDirNode->ObjectInformation = pObjectInfoCB;
4481 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4483 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4485 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4487 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4489 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4490 uniShareName.Buffer,
4491 pDirNode->NameInformation.FileName.Length);
4493 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4496 AFSSpecialShareNames = pDirNode;
4498 pLastDirNode = pDirNode;
4501 RtlInitUnicodeString( &uniShareName,
4504 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4507 if( pObjectInfoCB == NULL)
4510 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4513 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4514 AFS_OBJECT_REFERENCE_GLOBAL);
4516 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4517 AFS_TRACE_LEVEL_VERBOSE,
4518 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4522 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4524 ulEntryLength = sizeof( AFSDirectoryCB) +
4525 uniShareName.Length;
4527 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4531 if( pDirNode == NULL)
4534 AFSDeleteObjectInfo( &pObjectInfoCB);
4536 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4539 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4540 AFS_TRACE_LEVEL_VERBOSE,
4541 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4544 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4545 sizeof( AFSNonPagedDirectoryCB),
4546 AFS_DIR_ENTRY_NP_TAG);
4548 if( pNonPagedDirEntry == NULL)
4551 ExFreePool( pDirNode);
4553 AFSDeleteObjectInfo( &pObjectInfoCB);
4555 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4558 RtlZeroMemory( pDirNode,
4561 RtlZeroMemory( pNonPagedDirEntry,
4562 sizeof( AFSNonPagedDirectoryCB));
4564 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4566 pDirNode->NonPaged = pNonPagedDirEntry;
4568 pDirNode->ObjectInformation = pObjectInfoCB;
4574 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4576 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4578 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4580 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4582 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4583 uniShareName.Buffer,
4584 pDirNode->NameInformation.FileName.Length);
4586 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4589 pLastDirNode->ListEntry.fLink = pDirNode;
4591 pDirNode->ListEntry.bLink = pLastDirNode;
4595 if( !NT_SUCCESS( ntStatus))
4598 if( AFSSpecialShareNames != NULL)
4601 pDirNode = AFSSpecialShareNames;
4603 while( pDirNode != NULL)
4606 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4608 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4610 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4612 ExFreePool( pDirNode->NonPaged);
4614 ExFreePool( pDirNode);
4616 pDirNode = pLastDirNode;
4619 AFSSpecialShareNames = NULL;
4628 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4629 IN UNICODE_STRING *SecondaryName)
4632 AFSDirectoryCB *pDirectoryCB = NULL;
4633 ULONGLONG ullHash = 0;
4634 UNICODE_STRING uniFullShareName;
4640 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4641 AFS_TRACE_LEVEL_VERBOSE_2,
4642 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4646 uniFullShareName = *ShareName;
4649 // Generate our hash value
4652 ullHash = AFSGenerateCRC( &uniFullShareName,
4656 // Loop through our special share names to see if this is one of them
4659 pDirectoryCB = AFSSpecialShareNames;
4661 while( pDirectoryCB != NULL)
4664 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4670 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4674 return pDirectoryCB;
4678 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4682 // Block on the queue flush event
4685 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4695 AFSWaitOnQueuedReleases()
4698 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4701 // Block on the queue flush event
4704 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4714 AFSIsEqualFID( IN AFSFileID *FileId1,
4715 IN AFSFileID *FileId2)
4718 BOOLEAN bIsEqual = FALSE;
4720 if( FileId1->Hash == FileId2->Hash &&
4721 FileId1->Unique == FileId2->Unique &&
4722 FileId1->Vnode == FileId2->Vnode &&
4723 FileId1->Volume == FileId2->Volume &&
4724 FileId1->Cell == FileId2->Cell)
4734 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4737 NTSTATUS ntStatus = STATUS_SUCCESS;
4738 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4743 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4746 // Reset the directory list information
4749 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4751 while( pCurrentDirEntry != NULL)
4754 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4756 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
4757 pCurrentDirEntry->NameArrayReferenceCount <= 0)
4760 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4761 AFS_TRACE_LEVEL_VERBOSE,
4762 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4764 &pCurrentDirEntry->NameInformation.FileName));
4766 AFSDeleteDirEntry( ObjectInfoCB,
4772 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4773 AFS_TRACE_LEVEL_VERBOSE,
4774 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4776 &pCurrentDirEntry->NameInformation.FileName));
4778 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4780 AFSRemoveNameEntry( ObjectInfoCB,
4784 pCurrentDirEntry = pNextDirEntry;
4787 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4789 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4791 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4793 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4795 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4797 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4799 AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4800 AFS_TRACE_LEVEL_VERBOSE,
4801 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4802 ObjectInfoCB->FileId.Cell,
4803 ObjectInfoCB->FileId.Volume,
4804 ObjectInfoCB->FileId.Vnode,
4805 ObjectInfoCB->FileId.Unique));
4812 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4815 NTSTATUS ntStatus = STATUS_SUCCESS;
4816 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4817 UNICODE_STRING uniFullName;
4822 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4823 AFS_TRACE_LEVEL_VERBOSE,
4824 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4825 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4826 PsGetCurrentThread()));
4828 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4831 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4834 try_return( ntStatus);
4838 // Initialize the root information
4841 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4844 // Enumerate the shares in the volume
4847 ntStatus = AFSEnumerateDirectory( AuthGroup,
4848 &AFSGlobalRoot->ObjectInformation,
4851 if( !NT_SUCCESS( ntStatus))
4854 try_return( ntStatus);
4857 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4859 uniFullName.MaximumLength = PAGE_SIZE;
4860 uniFullName.Length = 0;
4862 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4863 uniFullName.MaximumLength,
4864 AFS_GENERIC_MEMORY_12_TAG);
4866 if( uniFullName.Buffer == NULL)
4870 // Reset the directory content
4873 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4875 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4877 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4881 // Populate our list of entries in the NP enumeration list
4884 while( pDirGlobalDirNode != NULL)
4887 uniFullName.Buffer[ 0] = L'\\';
4888 uniFullName.Buffer[ 1] = L'\\';
4890 uniFullName.Length = 2 * sizeof( WCHAR);
4892 RtlCopyMemory( &uniFullName.Buffer[ 2],
4893 AFSServerName.Buffer,
4894 AFSServerName.Length);
4896 uniFullName.Length += AFSServerName.Length;
4898 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4900 uniFullName.Length += sizeof( WCHAR);
4902 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4903 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4904 pDirGlobalDirNode->NameInformation.FileName.Length);
4906 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4908 AFSAddConnectionEx( &uniFullName,
4909 RESOURCEDISPLAYTYPE_SHARE,
4912 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4915 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
4919 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4926 AFSIsRelativeName( IN UNICODE_STRING *Name)
4929 BOOLEAN bIsRelative = FALSE;
4931 if( Name->Length > 0 &&
4932 Name->Buffer[ 0] != L'\\')
4942 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
4944 UNICODE_STRING uniTempName;
4945 BOOLEAN bIsAbsolute = FALSE;
4948 // An absolute AFS path must begin with \afs\... or equivalent
4951 if ( Name->Length == 0 ||
4952 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
4953 Name->Buffer[ 0] != L'\\' ||
4954 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
4960 uniTempName.Length = AFSMountRootName.Length;
4961 uniTempName.MaximumLength = AFSMountRootName.Length;
4963 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4964 uniTempName.MaximumLength,
4965 AFS_NAME_BUFFER_TWO_TAG);
4967 if( uniTempName.Buffer == NULL)
4973 RtlCopyMemory( uniTempName.Buffer,
4975 AFSMountRootName.Length);
4977 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
4981 AFSExFreePoolWithTag( uniTempName.Buffer,
4982 AFS_NAME_BUFFER_TWO_TAG);
4989 AFSUpdateName( IN UNICODE_STRING *Name)
4994 while( usIndex < Name->Length/sizeof( WCHAR))
4997 if( Name->Buffer[ usIndex] == L'/')
5000 Name->Buffer[ usIndex] = L'\\';
5010 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
5011 IN OUT ULONG *Flags,
5012 IN WCHAR *NameBuffer,
5013 IN USHORT NameLength)
5016 NTSTATUS ntStatus = STATUS_SUCCESS;
5017 WCHAR *pTmpBuffer = NULL;
5023 // If we have enough space then just move in the name otherwise
5024 // allocate a new buffer
5027 if( TargetName->Length < NameLength)
5030 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5032 AFS_NAME_BUFFER_FIVE_TAG);
5034 if( pTmpBuffer == NULL)
5037 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5040 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5043 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5046 TargetName->MaximumLength = NameLength;
5048 TargetName->Buffer = pTmpBuffer;
5050 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5053 TargetName->Length = NameLength;
5055 RtlCopyMemory( TargetName->Buffer,
5057 TargetName->Length);
5060 // Update the name in the buffer
5063 AFSUpdateName( TargetName);
5074 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
5075 IN ULONG InitialElementCount)
5078 AFSNameArrayHdr *pNameArray = NULL;
5079 AFSNameArrayCB *pCurrentElement = NULL;
5080 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5086 if( InitialElementCount == 0)
5089 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
5092 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
5093 sizeof( AFSNameArrayHdr) +
5094 (InitialElementCount * sizeof( AFSNameArrayCB)),
5095 AFS_NAME_ARRAY_TAG);
5097 if( pNameArray == NULL)
5100 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5101 AFS_TRACE_LEVEL_ERROR,
5102 "AFSInitNameArray Failed to allocate name array\n"));
5104 try_return( pNameArray);
5107 RtlZeroMemory( pNameArray,
5108 sizeof( AFSNameArrayHdr) +
5109 (InitialElementCount * sizeof( AFSNameArrayCB)));
5111 pNameArray->MaxElementCount = InitialElementCount;
5113 if( DirectoryCB != NULL)
5116 pCurrentElement = &pNameArray->ElementArray[ 0];
5118 pNameArray->CurrentEntry = pCurrentElement;
5120 pNameArray->Count = 1;
5122 pNameArray->LinkCount = 0;
5124 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5126 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5127 AFS_TRACE_LEVEL_VERBOSE,
5128 "AFSInitNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5130 &DirectoryCB->NameInformation.FileName,
5134 pCurrentElement->DirectoryCB = DirectoryCB;
5136 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5138 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5140 if( pCurrentElement->FileId.Vnode == 1)
5143 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5146 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5147 AFS_TRACE_LEVEL_VERBOSE,
5148 "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5150 pCurrentElement->DirectoryCB,
5151 pCurrentElement->FileId.Cell,
5152 pCurrentElement->FileId.Volume,
5153 pCurrentElement->FileId.Vnode,
5154 pCurrentElement->FileId.Unique,
5155 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5156 pCurrentElement->DirectoryCB->ObjectInformation->FileType));
5168 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
5169 IN UNICODE_STRING *Path,
5170 IN AFSDirectoryCB *DirectoryCB)
5173 NTSTATUS ntStatus = STATUS_SUCCESS;
5174 AFSNameArrayCB *pCurrentElement = NULL;
5180 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5181 AFS_TRACE_LEVEL_VERBOSE,
5182 "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5186 DirectoryCB->ObjectInformation->FileId.Cell,
5187 DirectoryCB->ObjectInformation->FileId.Volume,
5188 DirectoryCB->ObjectInformation->FileId.Vnode,
5189 DirectoryCB->ObjectInformation->FileId.Unique,
5190 &DirectoryCB->NameInformation.FileName,
5191 DirectoryCB->ObjectInformation->FileType));
5194 // Init some info in the header
5197 pCurrentElement = &NameArray->ElementArray[ 0];
5199 NameArray->CurrentEntry = pCurrentElement;
5202 // The first entry points at the root
5205 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
5207 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5209 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5210 AFS_TRACE_LEVEL_VERBOSE,
5211 "AFSPopulateNameArray [NA:%p] Increment count on volume %wZ DE %p Cnt %d\n",
5213 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5214 pCurrentElement->DirectoryCB,
5217 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
5219 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
5221 pCurrentElement->Flags = 0;
5223 if( pCurrentElement->FileId.Vnode == 1)
5226 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5229 NameArray->Count = 1;
5231 NameArray->LinkCount = 0;
5233 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5234 AFS_TRACE_LEVEL_VERBOSE,
5235 "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5237 pCurrentElement->DirectoryCB,
5238 pCurrentElement->FileId.Cell,
5239 pCurrentElement->FileId.Volume,
5240 pCurrentElement->FileId.Vnode,
5241 pCurrentElement->FileId.Unique,
5242 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5243 pCurrentElement->DirectoryCB->ObjectInformation->FileType));
5246 // If the root is the parent then we are done ...
5249 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
5251 try_return( ntStatus);
5263 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
5264 IN AFSNameArrayHdr *RelatedNameArray,
5265 IN AFSDirectoryCB *DirectoryCB)
5268 NTSTATUS ntStatus = STATUS_SUCCESS;
5269 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
5278 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5279 AFS_TRACE_LEVEL_VERBOSE,
5280 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5284 DirectoryCB->ObjectInformation->FileId.Cell,
5285 DirectoryCB->ObjectInformation->FileId.Volume,
5286 DirectoryCB->ObjectInformation->FileId.Vnode,
5287 DirectoryCB->ObjectInformation->FileId.Unique,
5288 &DirectoryCB->NameInformation.FileName,
5289 DirectoryCB->ObjectInformation->FileType));
5294 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5295 AFS_TRACE_LEVEL_VERBOSE,
5296 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE NULL\n",
5302 // Init some info in the header
5305 pCurrentElement = &NameArray->ElementArray[ 0];
5307 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5309 NameArray->Count = 0;
5311 NameArray->LinkCount = RelatedNameArray->LinkCount;
5314 // Populate the name array with the data from the related array
5320 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5322 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5324 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5326 pCurrentElement->Flags = 0;
5328 if( pCurrentElement->FileId.Vnode == 1)
5331 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5334 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5336 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5337 AFS_TRACE_LEVEL_VERBOSE,
5338 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5340 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5341 pCurrentElement->DirectoryCB,
5344 lCount = InterlockedIncrement( &NameArray->Count);
5346 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5347 AFS_TRACE_LEVEL_VERBOSE,
5348 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5351 pCurrentElement->DirectoryCB,
5352 pCurrentElement->FileId.Cell,
5353 pCurrentElement->FileId.Volume,
5354 pCurrentElement->FileId.Vnode,
5355 pCurrentElement->FileId.Unique,
5356 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5357 pCurrentElement->DirectoryCB->ObjectInformation->FileType));
5359 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5360 NameArray->Count == RelatedNameArray->Count)
5372 pCurrentRelatedElement++;
5375 NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
5382 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5385 NTSTATUS ntStatus = STATUS_SUCCESS;
5386 AFSNameArrayCB *pCurrentElement = NULL;
5387 LONG lCount, lElement;
5392 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5393 AFS_TRACE_LEVEL_VERBOSE,
5394 "AFSFreeNameArray [NA:%p]\n",
5397 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5400 pCurrentElement = &NameArray->ElementArray[ lElement];
5402 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5404 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5405 AFS_TRACE_LEVEL_VERBOSE,
5406 "AFSFreeNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5408 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5409 pCurrentElement->DirectoryCB,
5412 ASSERT( lCount >= 0);
5415 AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
5422 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5423 IN AFSDirectoryCB *DirectoryCB)
5426 NTSTATUS ntStatus = STATUS_SUCCESS;
5427 AFSNameArrayCB *pCurrentElement = NULL;
5433 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5434 AFS_TRACE_LEVEL_VERBOSE,
5435 "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5438 DirectoryCB->ObjectInformation->FileId.Cell,
5439 DirectoryCB->ObjectInformation->FileId.Volume,
5440 DirectoryCB->ObjectInformation->FileId.Vnode,
5441 DirectoryCB->ObjectInformation->FileId.Unique,
5442 &DirectoryCB->NameInformation.FileName,
5443 DirectoryCB->ObjectInformation->FileType));
5445 if( NameArray->Count == (LONG) NameArray->MaxElementCount)
5448 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5449 AFS_TRACE_LEVEL_ERROR,
5450 "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
5453 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5456 for ( lCount = 0; lCount < NameArray->Count; lCount++)
5459 if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
5460 &DirectoryCB->ObjectInformation->FileId) )
5463 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5464 AFS_TRACE_LEVEL_WARNING,
5465 "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
5468 STATUS_ACCESS_DENIED));
5470 try_return( ntStatus = STATUS_ACCESS_DENIED);
5474 if( NameArray->Count > 0)
5477 NameArray->CurrentEntry++;
5481 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5484 pCurrentElement = NameArray->CurrentEntry;
5486 lCount = InterlockedIncrement( &NameArray->Count);
5488 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5490 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5491 AFS_TRACE_LEVEL_VERBOSE,
5492 "AFSInsertNextElement [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5494 &DirectoryCB->NameInformation.FileName,
5498 ASSERT( lCount > 0);
5500 pCurrentElement->DirectoryCB = DirectoryCB;
5502 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5504 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5506 pCurrentElement->Flags = 0;
5508 if( pCurrentElement->FileId.Vnode == 1)
5511 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5514 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5515 AFS_TRACE_LEVEL_VERBOSE,
5516 "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5518 NameArray->Count - 1,
5519 pCurrentElement->DirectoryCB,
5520 pCurrentElement->FileId.Cell,
5521 pCurrentElement->FileId.Volume,
5522 pCurrentElement->FileId.Vnode,
5523 pCurrentElement->FileId.Unique,
5524 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5525 pCurrentElement->DirectoryCB->ObjectInformation->FileType));
5536 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5539 AFSDirectoryCB *pDirectoryCB = NULL;
5540 AFSNameArrayCB *pCurrentElement = NULL;
5541 BOOLEAN bVolumeRoot = FALSE;
5547 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5548 AFS_TRACE_LEVEL_VERBOSE,
5549 "AFSBackupEntry [NA:%p]\n",
5552 if( NameArray->Count == 0)
5555 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5556 AFS_TRACE_LEVEL_ERROR,
5557 "AFSBackupEntry [NA:%p] No more entries\n",
5560 try_return( pCurrentElement);
5563 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->NameArrayReferenceCount);
5565 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5566 AFS_TRACE_LEVEL_VERBOSE,
5567 "AFSBackupEntry [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5569 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5570 NameArray->CurrentEntry->DirectoryCB,
5573 ASSERT( lCount >= 0);
5575 NameArray->CurrentEntry->DirectoryCB = NULL;
5577 lCount = InterlockedDecrement( &NameArray->Count);
5581 NameArray->CurrentEntry = NULL;
5583 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5584 AFS_TRACE_LEVEL_ERROR,
5585 "AFSBackupEntry [NA:%p] No more entries\n",
5591 bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5593 NameArray->CurrentEntry--;
5595 pCurrentElement = NameArray->CurrentEntry;
5597 pDirectoryCB = pCurrentElement->DirectoryCB;
5599 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5600 AFS_TRACE_LEVEL_VERBOSE,
5601 "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5603 NameArray->Count - 1,
5604 pCurrentElement->DirectoryCB,
5605 pCurrentElement->FileId.Cell,
5606 pCurrentElement->FileId.Volume,
5607 pCurrentElement->FileId.Vnode,
5608 pCurrentElement->FileId.Unique,
5609 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5610 pCurrentElement->DirectoryCB->ObjectInformation->FileType));
5613 // If the entry we are removing is a volume root,
5614 // we must remove the mount point entry as well.
5615 // If the NameArray was constructed by checking the
5616 // share name via the service, the name array can
5617 // contain two volume roots in sequence without a
5618 // mount point separating them.
5622 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
5625 pDirectoryCB = AFSBackupEntry( NameArray);
5635 return pDirectoryCB;
5639 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5642 AFSDirectoryCB *pDirEntry = NULL;
5643 AFSNameArrayCB *pElement = NULL;
5648 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5649 AFS_TRACE_LEVEL_VERBOSE,
5650 "AFSGetParentEntry [NA:%p]\n",
5653 if( NameArray->Count == 0 ||
5654 NameArray->Count == 1)
5657 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5658 AFS_TRACE_LEVEL_ERROR,
5659 "AFSGetParentEntry [NA:%p] No more entries\n",
5662 try_return( pDirEntry = NULL);
5665 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5667 pDirEntry = pElement->DirectoryCB;
5669 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5670 AFS_TRACE_LEVEL_VERBOSE,
5671 "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5673 NameArray->Count - 2,
5674 pElement->DirectoryCB,
5675 pElement->FileId.Cell,
5676 pElement->FileId.Volume,
5677 pElement->FileId.Vnode,
5678 pElement->FileId.Unique,
5679 &pElement->DirectoryCB->NameInformation.FileName,
5680 pElement->DirectoryCB->ObjectInformation->FileType));
5691 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5692 IN AFSDirectoryCB *DirectoryCB)
5695 AFSNameArrayCB *pCurrentElement = NULL;
5696 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5697 LONG lCount, lElement;
5702 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5703 AFS_TRACE_LEVEL_VERBOSE,
5704 "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5707 DirectoryCB->ObjectInformation->FileId.Cell,
5708 DirectoryCB->ObjectInformation->FileId.Volume,
5709 DirectoryCB->ObjectInformation->FileId.Vnode,
5710 DirectoryCB->ObjectInformation->FileId.Unique,
5711 &DirectoryCB->NameInformation.FileName,
5712 DirectoryCB->ObjectInformation->FileType));
5715 // Dereference previous name array contents
5718 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5721 pCurrentElement = &NameArray->ElementArray[ lElement];
5723 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5725 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5726 AFS_TRACE_LEVEL_VERBOSE,
5727 "AFSResetNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5729 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5730 pCurrentElement->DirectoryCB,
5733 ASSERT( lCount >= 0);
5736 RtlZeroMemory( NameArray,
5737 sizeof( AFSNameArrayHdr) +
5738 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5740 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5742 if( DirectoryCB != NULL)
5745 pCurrentElement = &NameArray->ElementArray[ 0];
5747 NameArray->CurrentEntry = pCurrentElement;
5749 NameArray->Count = 1;
5751 NameArray->LinkCount = 0;
5753 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5755 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5756 AFS_TRACE_LEVEL_VERBOSE,
5757 "AFSResetNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5759 &DirectoryCB->NameInformation.FileName,
5763 pCurrentElement->DirectoryCB = DirectoryCB;
5765 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5767 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5769 pCurrentElement->Flags = 0;
5771 if( pCurrentElement->FileId.Vnode == 1)
5774 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5777 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5778 AFS_TRACE_LEVEL_VERBOSE,
5779 "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5781 pCurrentElement->DirectoryCB,
5782 pCurrentElement->FileId.Cell,
5783 pCurrentElement->FileId.Volume,
5784 pCurrentElement->FileId.Vnode,
5785 pCurrentElement->FileId.Unique,
5786 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5787 pCurrentElement->DirectoryCB->ObjectInformation->FileType));
5795 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5798 AFSNameArrayCB *pCurrentElement = NULL;
5800 pCurrentElement = &NameArray->ElementArray[ 0];
5802 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5804 while( pCurrentElement->DirectoryCB != NULL)
5807 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5808 pCurrentElement->FileId.Cell,
5809 pCurrentElement->FileId.Volume,
5810 pCurrentElement->FileId.Vnode,
5811 pCurrentElement->FileId.Unique,
5812 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5817 AFSPrint("AFSDumpNameArray End\n\n");
5823 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5828 // Depending on the type of node, set the event
5831 switch( Fcb->Header.NodeTypeCode)
5834 case AFS_DIRECTORY_FCB:
5839 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5849 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5855 // Depending on the type of node, set the event
5858 switch( Fcb->Header.NodeTypeCode)
5861 case AFS_DIRECTORY_FCB:
5866 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5868 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5878 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5881 BOOLEAN bIsInProcess = FALSE;
5886 if( ObjectInfo->Fcb == NULL)
5889 try_return( bIsInProcess);
5892 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5895 case AFS_DIRECTORY_FCB:
5900 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5903 bIsInProcess = TRUE;
5915 return bIsInProcess;
5919 AFSVerifyVolume( IN ULONGLONG ProcessId,
5920 IN AFSVolumeCB *VolumeCB)
5923 UNREFERENCED_PARAMETER(ProcessId);
5924 UNREFERENCED_PARAMETER(VolumeCB);
5925 NTSTATUS ntStatus = STATUS_SUCCESS;
5932 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5935 NTSTATUS ntStatus = STATUS_SUCCESS;
5936 AFSObjectInfoCB *pObjectInfoCB = NULL;
5937 AFSDirectoryCB *pDirNode = NULL;
5938 ULONG ulEntryLength = 0;
5939 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5945 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5948 if( pObjectInfoCB == NULL)
5951 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5954 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5955 AFS_OBJECT_REFERENCE_DIRENTRY);
5957 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5958 AFS_TRACE_LEVEL_VERBOSE,
5959 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5963 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5965 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5967 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5969 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5973 if( pDirNode == NULL)
5976 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5979 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5980 AFS_TRACE_LEVEL_VERBOSE,
5981 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5984 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5985 sizeof( AFSNonPagedDirectoryCB),
5986 AFS_DIR_ENTRY_NP_TAG);
5988 if( pNonPagedDirEntry == NULL)
5991 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5994 RtlZeroMemory( pDirNode,
5997 RtlZeroMemory( pNonPagedDirEntry,
5998 sizeof( AFSNonPagedDirectoryCB));
6000 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
6002 pDirNode->NonPaged = pNonPagedDirEntry;
6004 pDirNode->ObjectInformation = pObjectInfoCB;
6006 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
6012 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
6014 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
6016 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
6018 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
6020 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
6021 AFSPIOCtlName.Buffer,
6022 pDirNode->NameInformation.FileName.Length);
6024 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
6027 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
6030 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
6031 AFS_TRACE_LEVEL_WARNING,
6032 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
6033 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
6036 try_return( ntStatus = STATUS_REPARSE);
6041 if ( ntStatus != STATUS_SUCCESS)
6044 if ( pDirNode != NULL)
6047 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
6048 AFS_TRACE_LEVEL_VERBOSE,
6049 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
6052 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
6055 if( pNonPagedDirEntry != NULL)
6058 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
6060 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
6063 if ( pObjectInfoCB != NULL)
6066 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
6067 AFS_OBJECT_REFERENCE_DIRENTRY);
6069 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6070 AFS_TRACE_LEVEL_VERBOSE,
6071 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
6075 AFSDeleteObjectInfo( &pObjectInfoCB);
6084 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
6085 IN AFSDirectoryCB *DirectoryCB,
6086 IN UNICODE_STRING *ParentPathName,
6087 IN AFSNameArrayHdr *RelatedNameArray,
6089 OUT AFSFileInfoCB *FileInfo)
6092 NTSTATUS ntStatus = STATUS_SUCCESS;
6093 AFSDirEnumEntry *pDirEntry = NULL;
6094 UNICODE_STRING uniFullPathName = {0};
6095 AFSNameArrayHdr *pNameArray = NULL;
6096 AFSVolumeCB *pVolumeCB = NULL;
6097 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6098 AFSVolumeCB *pNewVolumeCB = NULL;
6099 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6100 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6101 AFSDirectoryCB *pNewParentDirEntry = NULL;
6102 WCHAR *pwchBuffer = NULL;
6103 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6104 ULONG ulNameDifference = 0;
6111 // Retrieve a target name for the entry
6114 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6117 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6120 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6122 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6127 if( !NT_SUCCESS( ntStatus) ||
6128 pDirEntry->TargetNameLength == 0)
6131 if( pDirEntry != NULL)
6134 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6137 try_return( ntStatus);
6140 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6143 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6147 // Update the target name
6150 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6151 &DirectoryCB->Flags,
6152 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6153 (USHORT)pDirEntry->TargetNameLength);
6155 if( !NT_SUCCESS( ntStatus))
6158 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6160 try_return( ntStatus);
6164 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6168 // Need to pass the full path in for parsing.
6171 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
6174 uniFullPathName.Length = 0;
6175 uniFullPathName.MaximumLength = ParentPathName->Length +
6177 DirectoryCB->NameInformation.TargetName.Length;
6179 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6180 uniFullPathName.MaximumLength,
6181 AFS_NAME_BUFFER_SIX_TAG);
6183 if( uniFullPathName.Buffer == NULL)
6186 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6188 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6191 pwchBuffer = uniFullPathName.Buffer;
6193 RtlZeroMemory( uniFullPathName.Buffer,
6194 uniFullPathName.MaximumLength);
6196 RtlCopyMemory( uniFullPathName.Buffer,
6197 ParentPathName->Buffer,
6198 ParentPathName->Length);
6200 uniFullPathName.Length = ParentPathName->Length;
6202 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
6203 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
6206 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
6208 uniFullPathName.Length += sizeof( WCHAR);
6211 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
6212 DirectoryCB->NameInformation.TargetName.Buffer,
6213 DirectoryCB->NameInformation.TargetName.Length);
6215 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
6217 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
6218 uniParsedName.MaximumLength = uniParsedName.Length;
6220 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
6222 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6225 // We populate up to the current parent
6228 if( RelatedNameArray != NULL)
6231 pNameArray = AFSInitNameArray( NULL,
6232 RelatedNameArray->MaxElementCount);
6234 if( pNameArray == NULL)
6237 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6240 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
6247 pNameArray = AFSInitNameArray( NULL,
6250 if( pNameArray == NULL)
6253 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6256 ntStatus = AFSPopulateNameArray( pNameArray,
6261 if( !NT_SUCCESS( ntStatus))
6264 try_return( ntStatus);
6267 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
6269 pParentDirEntry = ParentDirectoryCB;
6274 uniFullPathName.Length = 0;
6275 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6277 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6278 uniFullPathName.MaximumLength,
6279 AFS_NAME_BUFFER_SEVEN_TAG);
6281 if( uniFullPathName.Buffer == NULL)
6284 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6286 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6289 pwchBuffer = uniFullPathName.Buffer;
6291 RtlZeroMemory( uniFullPathName.Buffer,
6292 uniFullPathName.MaximumLength);
6294 RtlCopyMemory( uniFullPathName.Buffer,
6295 DirectoryCB->NameInformation.TargetName.Buffer,
6296 DirectoryCB->NameInformation.TargetName.Length);
6298 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6301 // This name should begin with the \afs server so parse it off and check it
6304 FsRtlDissectName( uniFullPathName,
6308 if( RtlCompareUnicodeString( &uniComponentName,
6313 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6315 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
6316 AFS_TRACE_LEVEL_ERROR,
6317 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
6320 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
6323 uniFullPathName = uniRemainingPath;
6325 uniParsedName = uniFullPathName;
6327 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6329 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6335 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6338 if( pNameArray == NULL)
6341 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6344 pVolumeCB = AFSGlobalRoot;
6346 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6350 // Increment the ref count on the volume and dir entry for correct processing below
6353 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
6355 lCount = AFSVolumeIncrement( pVolumeCB,
6356 VolumeReferenceReason);
6358 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6359 AFS_TRACE_LEVEL_VERBOSE,
6360 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
6362 VolumeReferenceReason,
6365 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6367 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6368 AFS_TRACE_LEVEL_VERBOSE,
6369 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6370 &pParentDirEntry->NameInformation.FileName,
6375 ntStatus = AFSLocateNameEntry( NULL,
6380 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
6384 &NewVolumeReferenceReason,
6385 &pNewParentDirEntry,
6389 if ( pNewVolumeCB != NULL)
6392 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6393 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6394 // the reference on pVolumeCB that was held prior to the call.
6395 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6396 // will be released second.
6399 lCount = AFSVolumeDecrement( pVolumeCB,
6400 VolumeReferenceReason);
6402 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6403 AFS_TRACE_LEVEL_VERBOSE,
6404 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
6406 VolumeReferenceReason,
6409 pVolumeCB = pNewVolumeCB;
6411 pNewVolumeCB = NULL;
6413 VolumeReferenceReason = NewVolumeReferenceReason;
6415 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6419 // AFSLocateNameEntry does not alter the reference count of
6420 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6421 // a reference held.
6424 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6426 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6427 AFS_TRACE_LEVEL_VERBOSE,
6428 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
6429 &pParentDirEntry->NameInformation.FileName,
6433 pParentDirEntry = pNewParentDirEntry;
6435 pNewParentDirEntry = NULL;
6437 if( !NT_SUCCESS( ntStatus) ||
6438 ntStatus == STATUS_REPARSE)
6441 try_return( ntStatus);
6445 // Store off the information
6448 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6451 // Check for the mount point being returned
6454 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
6455 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6458 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6460 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
6463 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6466 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6471 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6475 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6477 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6479 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6481 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6483 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6485 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6489 if( pDirEntry != NULL)
6492 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6495 if( pDirectoryEntry != NULL)
6498 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6500 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6501 AFS_TRACE_LEVEL_VERBOSE,
6502 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6503 &pDirectoryEntry->NameInformation.FileName,
6508 ASSERT( lCount >= 0);
6511 if ( pParentDirEntry != NULL)
6514 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6516 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6517 AFS_TRACE_LEVEL_VERBOSE,
6518 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6519 &pParentDirEntry->NameInformation.FileName,
6524 ASSERT( lCount >= 0);
6527 if( pVolumeCB != NULL)
6530 lCount = AFSVolumeDecrement( pVolumeCB,
6531 VolumeReferenceReason);
6533 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6534 AFS_TRACE_LEVEL_VERBOSE,
6535 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
6537 VolumeReferenceReason,
6541 if( pNameArray != NULL)
6544 AFSFreeNameArray( pNameArray);
6547 if( pwchBuffer != NULL)
6551 // Always free the buffer that we allocated as AFSLocateNameEntry
6552 // will not free it. If uniFullPathName.Buffer was allocated by
6553 // AFSLocateNameEntry, then we must free that as well.
6554 // Check that the uniFullPathName.Buffer in the string is not the same
6555 // offset by the length of the server name
6558 if( uniFullPathName.Length > 0 &&
6559 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6562 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6565 AFSExFreePoolWithTag( pwchBuffer, 0);
6573 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6574 IN ULONGLONG HashIndex)
6577 NTSTATUS ntStatus = STATUS_SUCCESS;
6578 AFSObjectInfoCB *pObjectInfo = NULL;
6584 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6585 sizeof( AFSObjectInfoCB),
6586 AFS_OBJECT_INFO_TAG);
6588 if( pObjectInfo == NULL)
6591 try_return( pObjectInfo);
6594 RtlZeroMemory( pObjectInfo,
6595 sizeof( AFSObjectInfoCB));
6597 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6598 sizeof( AFSNonPagedObjectInfoCB),
6599 AFS_NP_OBJECT_INFO_TAG);
6601 if( pObjectInfo->NonPagedInfo == NULL)
6604 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6606 try_return( pObjectInfo = NULL);
6609 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6611 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6613 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6615 if( ParentObjectInfo != NULL)
6618 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6620 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6622 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6624 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6625 AFS_OBJECT_REFERENCE_CHILD);
6627 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6628 AFS_TRACE_LEVEL_VERBOSE,
6629 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6635 // Initialize the access time
6638 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6643 ASSERT( ParentObjectInfo);
6646 // Insert the entry into the object tree and list
6649 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6651 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6654 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6659 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6660 &pObjectInfo->TreeEntry);
6662 ASSERT( NT_SUCCESS( ntStatus));
6666 // And the object list in the volume
6669 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6672 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6677 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6679 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6682 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6685 // Indicate the object is in the hash tree and linked list in the volume
6688 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6700 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6706 if ( ObjectInfo->ObjectReferenceCount == 0)
6709 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6712 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6717 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6720 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6725 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6727 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6732 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6734 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6740 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6744 LONG lCount, lCount2;
6746 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6749 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6754 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6756 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6758 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6761 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6764 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6766 ASSERT( lCount2 >= 0);
6768 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6774 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6775 IN AFSFileID *FileId)
6777 DWORD ntStatus = STATUS_SUCCESS;
6779 AFSObjectInfoCB *pObjectInfo = NULL;
6781 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6784 pObjectInfo = &VolumeCB->ObjectInformation;
6789 AFSAcquireExcl( VolumeCB->ObjectInfoTree.TreeLock,
6792 ullIndex = AFSCreateLowIndex( FileId);
6794 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6796 (AFSBTreeEntry **)&pObjectInfo);
6798 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6801 if ( NT_SUCCESS( ntStatus)) {
6803 AFSObjectInfoIncrement( pObjectInfo,
6804 AFS_OBJECT_REFERENCE_FIND);
6811 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6814 AFSObjectInfoDecrement( *ppObjectInfo,
6815 AFS_OBJECT_REFERENCE_FIND);
6817 *ppObjectInfo = NULL;
6821 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6824 BOOLEAN bAcquiredTreeLock = FALSE;
6825 AFSObjectInfoCB *pObjectInfo = NULL;
6826 BOOLEAN bHeldInService;
6827 AFSObjectInfoCB * pParentObjectInfo = NULL;
6831 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
6835 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6836 // embedded in the VolumeCB.
6844 pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
6846 (PVOID *)ppObjectInfo);
6848 if ( pObjectInfo == NULL)
6854 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6856 bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6858 if( !ExIsResourceAcquiredExclusiveLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6861 ASSERT( !ExIsResourceAcquiredLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6863 AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6866 bAcquiredTreeLock = TRUE;
6869 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6872 pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
6873 &pObjectInfo->ParentFileId);
6877 // Remove it from the tree and list if it was inserted
6880 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6883 AFSRemoveHashEntry( &pObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6884 &pObjectInfo->TreeEntry);
6887 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6890 if( pObjectInfo->ListEntry.fLink == NULL)
6893 pObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6895 if( pObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6898 pObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6904 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6907 if( pObjectInfo->ListEntry.bLink == NULL)
6910 pObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6912 if( pObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6915 pObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6921 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6925 if( pParentObjectInfo != NULL)
6928 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6930 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6931 AFS_OBJECT_REFERENCE_CHILD);
6933 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6934 AFS_TRACE_LEVEL_VERBOSE,
6935 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6939 AFSReleaseObjectInfo( &pParentObjectInfo);
6942 if( bAcquiredTreeLock)
6945 AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6951 FileId = pObjectInfo->FileId;
6954 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6956 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6958 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6960 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6963 // Release the fid in the service
6969 AFSReleaseFid( &FileId);
6976 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6977 OUT AFSDirectoryCB **TargetDirEntry)
6980 NTSTATUS ntStatus = STATUS_SUCCESS;
6981 AFSDirEnumEntry *pDirEntry = NULL;
6982 UNICODE_STRING uniFullPathName = {0};
6983 AFSNameArrayHdr *pNameArray = NULL;
6984 AFSVolumeCB *pVolumeCB = NULL;
6985 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6986 AFSVolumeCB *pNewVolumeCB = NULL;
6987 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6988 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6989 AFSDirectoryCB *pNewParentDirEntry = NULL;
6990 WCHAR *pwchBuffer = NULL;
6991 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6992 ULONG ulNameDifference = 0;
6999 ntStatus = AFSRetrieveValidAuthGroup( NULL,
7000 DirectoryCB->ObjectInformation,
7004 if( !NT_SUCCESS( ntStatus))
7006 try_return( ntStatus);
7010 // Retrieve a target name for the entry
7013 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
7016 if( DirectoryCB->NameInformation.TargetName.Length == 0)
7019 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7021 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
7026 if( !NT_SUCCESS( ntStatus) ||
7027 pDirEntry->TargetNameLength == 0)
7030 if( pDirEntry != NULL)
7033 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
7036 try_return( ntStatus);
7039 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
7042 if( DirectoryCB->NameInformation.TargetName.Length == 0)
7046 // Update the target name
7049 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
7050 &DirectoryCB->Flags,
7051 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
7052 (USHORT)pDirEntry->TargetNameLength);
7054 if( !NT_SUCCESS( ntStatus))
7057 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7059 try_return( ntStatus);
7063 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
7067 // Need to pass the full path in for parsing.
7070 uniFullPathName.Length = 0;
7071 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
7073 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7074 uniFullPathName.MaximumLength,
7075 AFS_NAME_BUFFER_EIGHT_TAG);
7077 if( uniFullPathName.Buffer == NULL)
7080 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7082 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7085 pwchBuffer = uniFullPathName.Buffer;
7087 RtlZeroMemory( uniFullPathName.Buffer,
7088 uniFullPathName.MaximumLength);
7090 RtlCopyMemory( uniFullPathName.Buffer,
7091 DirectoryCB->NameInformation.TargetName.Buffer,
7092 DirectoryCB->NameInformation.TargetName.Length);
7094 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
7097 // This name should begin with the \afs server so parse it off and chech it
7100 FsRtlDissectName( uniFullPathName,
7104 if( RtlCompareUnicodeString( &uniComponentName,
7110 // Try evaluating the full path
7113 uniFullPathName.Buffer = pwchBuffer;
7115 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
7117 uniFullPathName.MaximumLength = uniFullPathName.Length;
7122 uniFullPathName = uniRemainingPath;
7125 uniParsedName = uniFullPathName;
7127 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
7129 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7135 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7138 if( pNameArray == NULL)
7141 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7144 pVolumeCB = AFSGlobalRoot;
7146 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7148 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
7150 lCount = AFSVolumeIncrement( pVolumeCB,
7151 VolumeReferenceReason);
7153 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7154 AFS_TRACE_LEVEL_VERBOSE,
7155 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
7157 VolumeReferenceReason,
7160 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
7162 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7163 AFS_TRACE_LEVEL_VERBOSE,
7164 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7165 &pParentDirEntry->NameInformation.FileName,
7170 ntStatus = AFSLocateNameEntry( NULL,
7179 &VolumeReferenceReason,
7180 &pNewParentDirEntry,
7184 if ( pNewVolumeCB != NULL)
7187 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
7188 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
7189 // the reference on pVolumeCB that was held prior to the call.
7190 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
7191 // will be released second.
7194 lCount = AFSVolumeDecrement( pVolumeCB,
7195 VolumeReferenceReason);
7197 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7198 AFS_TRACE_LEVEL_VERBOSE,
7199 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
7201 VolumeReferenceReason,
7204 pVolumeCB = pNewVolumeCB;
7206 pNewVolumeCB = NULL;
7208 VolumeReferenceReason = NewVolumeReferenceReason;
7210 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7214 // AFSLocateNameEntry does not alter the reference count of
7215 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
7216 // a reference held.
7219 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
7221 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7222 AFS_TRACE_LEVEL_VERBOSE,
7223 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
7224 &pParentDirEntry->NameInformation.FileName,
7228 pParentDirEntry = pNewParentDirEntry;
7230 pNewParentDirEntry = NULL;
7232 if( !NT_SUCCESS( ntStatus) ||
7233 ntStatus == STATUS_REPARSE)
7238 try_return( ntStatus);
7242 // Pass back the target dir entry for this request
7243 // The caller must release the DirOpenReferenceCount
7246 *TargetDirEntry = pDirectoryEntry;
7248 pDirectoryEntry = NULL;
7252 if( pDirectoryEntry != NULL)
7255 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
7257 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7258 AFS_TRACE_LEVEL_VERBOSE,
7259 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7260 &pDirectoryEntry->NameInformation.FileName,
7265 ASSERT( lCount >= 0);
7268 if ( pParentDirEntry != NULL)
7271 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
7273 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7274 AFS_TRACE_LEVEL_VERBOSE,
7275 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7276 &pParentDirEntry->NameInformation.FileName,
7281 ASSERT( lCount >= 0);
7284 if( pDirEntry != NULL)
7287 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
7290 if( pVolumeCB != NULL)
7293 lCount = AFSVolumeDecrement( pVolumeCB,
7294 VolumeReferenceReason);
7296 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7297 AFS_TRACE_LEVEL_VERBOSE,
7298 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
7300 VolumeReferenceReason,
7304 if( pNameArray != NULL)
7307 AFSFreeNameArray( pNameArray);
7310 if( pwchBuffer != NULL)
7314 // Always free the buffer that we allocated as AFSLocateNameEntry
7315 // will not free it. If uniFullPathName.Buffer was allocated by
7316 // AFSLocateNameEntry, then we must free that as well.
7317 // Check that the uniFullPathName.Buffer in the string is not the same
7318 // offset by the length of the server name
7321 if( uniFullPathName.Length > 0 &&
7322 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
7325 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
7328 AFSExFreePoolWithTag( pwchBuffer, 0);
7336 AFSCleanupFcb( IN AFSFcb *Fcb,
7337 IN BOOLEAN ForceFlush)
7340 NTSTATUS ntStatus = STATUS_SUCCESS;
7341 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
7342 LARGE_INTEGER liTime;
7343 IO_STATUS_BLOCK stIoStatus;
7348 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7350 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7352 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
7355 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
7356 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7359 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7360 AFS_TRACE_LEVEL_VERBOSE,
7361 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
7362 &Fcb->NPFcb->Resource,
7363 PsGetCurrentThread()));
7365 AFSAcquireShared( &Fcb->NPFcb->Resource,
7368 if( Fcb->OpenReferenceCount > 0)
7371 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7372 AFS_TRACE_LEVEL_VERBOSE,
7373 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7374 &Fcb->NPFcb->SectionObjectResource,
7375 PsGetCurrentThread()));
7377 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
7383 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7388 if( !NT_SUCCESS( stIoStatus.Status))
7391 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7392 AFS_TRACE_LEVEL_ERROR,
7393 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7394 Fcb->ObjectInformation->FileId.Cell,
7395 Fcb->ObjectInformation->FileId.Volume,
7396 Fcb->ObjectInformation->FileId.Vnode,
7397 Fcb->ObjectInformation->FileId.Unique,
7399 stIoStatus.Information));
7401 ntStatus = stIoStatus.Status;
7404 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7407 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7413 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7414 AFS_TRACE_LEVEL_WARNING,
7415 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
7416 Fcb->ObjectInformation->FileId.Cell,
7417 Fcb->ObjectInformation->FileId.Volume,
7418 Fcb->ObjectInformation->FileId.Vnode,
7419 Fcb->ObjectInformation->FileId.Unique));
7421 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7425 __except( EXCEPTION_EXECUTE_HANDLER)
7428 ntStatus = GetExceptionCode();
7432 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7433 Fcb->ObjectInformation->FileId.Cell,
7434 Fcb->ObjectInformation->FileId.Volume,
7435 Fcb->ObjectInformation->FileId.Vnode,
7436 Fcb->ObjectInformation->FileId.Unique,
7439 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7442 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7443 AFS_TRACE_LEVEL_VERBOSE,
7444 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7445 &Fcb->NPFcb->SectionObjectResource,
7446 PsGetCurrentThread()));
7448 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7451 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7452 AFS_TRACE_LEVEL_VERBOSE,
7453 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
7454 &Fcb->NPFcb->Resource,
7455 PsGetCurrentThread()));
7457 AFSReleaseResource( &Fcb->NPFcb->Resource);
7460 // Wait for any currently running flush or release requests to complete
7463 AFSWaitOnQueuedFlushes( Fcb);
7466 // Now perform another flush on the file
7469 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7473 AFSReleaseExtentsWithFlush( Fcb,
7479 if( Fcb->OpenReferenceCount == 0 ||
7480 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7481 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7484 AFSTearDownFcbExtents( Fcb,
7488 try_return( ntStatus);
7491 KeQueryTickCount( &liTime);
7494 // First up are there dirty extents in the cache to flush?
7497 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7498 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7502 // The file has been marked as invalid. Dump it
7505 AFSTearDownFcbExtents( Fcb,
7508 else if( ForceFlush ||
7509 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7510 Fcb->Specific.File.ExtentCount) &&
7511 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7512 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7514 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7516 Fcb->OpenReferenceCount == 0)
7519 AFSReleaseExtentsWithFlush( Fcb,
7526 // If there are extents and they haven't been used recently *and*
7527 // are not being used
7531 ( 0 != Fcb->Specific.File.ExtentCount &&
7532 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7533 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7534 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7537 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7538 AFS_TRACE_LEVEL_VERBOSE,
7539 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7540 &Fcb->NPFcb->SectionObjectResource,
7541 PsGetCurrentThread()));
7543 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7549 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7554 if( !NT_SUCCESS( stIoStatus.Status))
7557 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7558 AFS_TRACE_LEVEL_ERROR,
7559 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7560 Fcb->ObjectInformation->FileId.Cell,
7561 Fcb->ObjectInformation->FileId.Volume,
7562 Fcb->ObjectInformation->FileId.Vnode,
7563 Fcb->ObjectInformation->FileId.Unique,
7565 stIoStatus.Information));
7567 ntStatus = stIoStatus.Status;
7571 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7574 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7580 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7581 AFS_TRACE_LEVEL_WARNING,
7582 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7583 Fcb->ObjectInformation->FileId.Cell,
7584 Fcb->ObjectInformation->FileId.Volume,
7585 Fcb->ObjectInformation->FileId.Vnode,
7586 Fcb->ObjectInformation->FileId.Unique));
7588 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7592 __except( EXCEPTION_EXECUTE_HANDLER)
7595 ntStatus = GetExceptionCode();
7599 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7600 Fcb->ObjectInformation->FileId.Cell,
7601 Fcb->ObjectInformation->FileId.Volume,
7602 Fcb->ObjectInformation->FileId.Vnode,
7603 Fcb->ObjectInformation->FileId.Unique,
7607 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7608 AFS_TRACE_LEVEL_VERBOSE,
7609 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7610 &Fcb->NPFcb->SectionObjectResource,
7611 PsGetCurrentThread()));
7613 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7615 if( Fcb->OpenReferenceCount <= 0)
7619 // Tear em down we'll not be needing them again
7622 AFSTearDownFcbExtents( Fcb,
7629 ntStatus = STATUS_RETRY;
7642 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7643 IN UNICODE_STRING *NewFileName)
7646 NTSTATUS ntStatus = STATUS_SUCCESS;
7647 WCHAR *pTmpBuffer = NULL;
7652 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7655 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7658 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7660 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7662 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7666 // OK, we need to allocate a new name buffer
7669 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7670 NewFileName->Length,
7671 AFS_NAME_BUFFER_NINE_TAG);
7673 if( pTmpBuffer == NULL)
7676 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7679 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7681 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7683 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7686 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7688 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7689 NewFileName->Buffer,
7690 NewFileName->Length);
7701 AFSReadCacheFile( IN void *ReadBuffer,
7702 IN LARGE_INTEGER *ReadOffset,
7703 IN ULONG RequestedDataLength,
7704 IN OUT PULONG BytesRead)
7707 NTSTATUS ntStatus = STATUS_SUCCESS;
7710 PIO_STACK_LOCATION pIoStackLocation = NULL;
7711 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7712 FILE_OBJECT *pCacheFileObject = NULL;
7717 pCacheFileObject = AFSReferenceCacheFileObject();
7719 if( pCacheFileObject == NULL)
7721 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7724 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7727 // Initialize the event
7730 KeInitializeEvent( &kEvent,
7731 SynchronizationEvent,
7735 // Allocate an irp for this request. This could also come from a
7736 // private pool, for instance.
7739 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7745 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7749 // Build the IRP's main body
7752 pIrp->UserBuffer = ReadBuffer;
7754 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7755 pIrp->RequestorMode = KernelMode;
7756 pIrp->Flags |= IRP_READ_OPERATION;
7759 // Set up the I/O stack location.
7762 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7763 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7764 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7765 pIoStackLocation->FileObject = pCacheFileObject;
7766 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7768 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7771 // Set the completion routine.
7774 IoSetCompletionRoutine( pIrp,
7782 // Send it to the FSD
7785 ntStatus = IoCallDriver( pTargetDeviceObject,
7788 if( NT_SUCCESS( ntStatus))
7795 ntStatus = KeWaitForSingleObject( &kEvent,
7801 if( NT_SUCCESS( ntStatus))
7804 ntStatus = pIrp->IoStatus.Status;
7806 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7812 if( pCacheFileObject != NULL)
7814 AFSReleaseCacheFileObject( pCacheFileObject);
7820 if( pIrp->MdlAddress != NULL)
7823 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7826 MmUnlockPages( pIrp->MdlAddress);
7829 IoFreeMdl( pIrp->MdlAddress);
7832 pIrp->MdlAddress = NULL;
7846 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7851 UNREFERENCED_PARAMETER(Irp);
7852 UNREFERENCED_PARAMETER(DeviceObject);
7853 KEVENT *pEvent = (KEVENT *)Context;
7859 return STATUS_MORE_PROCESSING_REQUIRED;
7863 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7866 BOOLEAN bIsEmpty = FALSE;
7867 AFSDirectoryCB *pDirEntry = NULL;
7872 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7877 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7880 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7882 while( pDirEntry != NULL)
7885 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7886 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7894 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7899 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7906 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7907 IN AFSDirectoryCB *DirEntry)
7910 NTSTATUS ntStatus = STATUS_SUCCESS;
7915 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7918 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7919 AFS_TRACE_LEVEL_VERBOSE,
7920 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7922 &DirEntry->NameInformation.FileName));
7924 try_return( ntStatus);
7927 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7930 // Remove the entry from the parent tree
7933 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7934 AFS_TRACE_LEVEL_VERBOSE,
7935 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7937 &DirEntry->NameInformation.FileName));
7939 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7942 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7943 AFS_TRACE_LEVEL_VERBOSE,
7944 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7946 &DirEntry->NameInformation.FileName));
7948 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7951 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7955 // From the short name tree
7958 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7959 AFS_TRACE_LEVEL_VERBOSE,
7960 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7962 &DirEntry->NameInformation.FileName));
7964 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7967 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7970 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7971 AFS_TRACE_LEVEL_VERBOSE,
7972 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7974 &DirEntry->NameInformation.FileName));
7976 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7978 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7989 AFSGetAuthenticationId()
7992 LARGE_INTEGER liAuthId = {0,0};
7993 NTSTATUS ntStatus = STATUS_SUCCESS;
7994 PACCESS_TOKEN hToken = NULL;
7995 PTOKEN_STATISTICS pTokenInfo = NULL;
7996 BOOLEAN bCopyOnOpen = FALSE;
7997 BOOLEAN bEffectiveOnly = FALSE;
7998 BOOLEAN bPrimaryToken = FALSE;
7999 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
8004 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
8007 &stImpersonationLevel);
8012 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
8017 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
8018 AFS_TRACE_LEVEL_ERROR,
8019 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
8021 try_return( ntStatus);
8024 bPrimaryToken = TRUE;
8027 ntStatus = SeQueryInformationToken( hToken,
8029 (PVOID *)&pTokenInfo);
8031 if( !NT_SUCCESS( ntStatus))
8034 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
8035 AFS_TRACE_LEVEL_ERROR,
8036 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
8039 try_return( ntStatus);
8042 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
8043 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
8045 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
8046 AFS_TRACE_LEVEL_VERBOSE,
8047 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
8048 liAuthId.QuadPart));
8058 PsDereferenceImpersonationToken( hToken);
8063 PsDereferencePrimaryToken( hToken);
8067 if( pTokenInfo != NULL)
8070 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
8078 AFSUnwindFileInfo( IN AFSFcb *Fcb,
8082 UNREFERENCED_PARAMETER(Fcb);
8083 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
8085 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
8088 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
8090 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
8093 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
8095 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
8098 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
8100 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
8103 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
8105 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
8112 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
8115 BOOLEAN bIsValid = TRUE;
8117 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
8119 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
8121 while( pCurrentDirEntry != NULL)
8124 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
8128 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
8133 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8134 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
8137 if( pDirEntry == NULL)
8144 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
8147 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
8150 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
8152 ObjectInfo->Specific.Directory.DirectoryNodeCount);
8154 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
8163 AFSReferenceCacheFileObject()
8166 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8167 FILE_OBJECT *pCacheFileObject = NULL;
8169 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
8172 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
8174 if( pCacheFileObject != NULL)
8176 ObReferenceObject( pCacheFileObject);
8179 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
8181 return pCacheFileObject;
8185 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
8188 ASSERT( CacheFileObject != NULL);
8190 ObDereferenceObject( CacheFileObject);
8196 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
8199 NTSTATUS ntStatus = STATUS_SUCCESS;
8200 AFSDeviceExt *pControlDevExt = NULL;
8201 ULONG ulTimeIncrement = 0;
8207 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
8209 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
8211 AFSServerName = LibraryInit->AFSServerName;
8213 AFSMountRootName = LibraryInit->AFSMountRootName;
8215 AFSDebugFlags = LibraryInit->AFSDebugFlags;
8218 // Callbacks in the framework
8221 AFSProcessRequest = LibraryInit->AFSProcessRequest;
8223 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
8225 AFSDebugTraceFnc = AFSDbgLogMsg;
8227 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
8229 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
8231 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
8233 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
8235 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
8237 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
8239 if( LibraryInit->AFSCacheBaseAddress != NULL)
8242 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
8244 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
8246 AFSLibCacheLength = LibraryInit->AFSCacheLength;
8250 // Initialize some flush parameters
8253 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
8255 ulTimeIncrement = KeQueryTimeIncrement();
8257 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
8258 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
8259 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
8260 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
8261 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
8264 // Initialize the global root entry
8267 ntStatus = AFSInitVolume( NULL,
8268 &LibraryInit->GlobalRootFid,
8269 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
8272 if( !NT_SUCCESS( ntStatus))
8275 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8276 AFS_TRACE_LEVEL_ERROR,
8277 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
8280 try_return( ntStatus);
8283 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
8286 if( !NT_SUCCESS( ntStatus))
8289 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8290 AFS_TRACE_LEVEL_ERROR,
8291 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
8294 lCount = AFSVolumeDecrement( AFSGlobalRoot,
8295 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
8297 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8298 AFS_TRACE_LEVEL_VERBOSE,
8299 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8303 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8305 try_return( ntStatus);
8309 // Update the node type code to AFS_ROOT_ALL
8312 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
8314 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
8317 // Invalidate all known volumes since contact with the service and therefore
8318 // the file server was lost.
8321 AFSInvalidateAllVolumes();
8324 // Drop the locks acquired above
8327 AFSInitVolumeWorker( AFSGlobalRoot);
8329 lCount = AFSVolumeDecrement( AFSGlobalRoot,
8330 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
8332 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8333 AFS_TRACE_LEVEL_VERBOSE,
8334 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8338 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8340 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
8354 NTSTATUS ntStatus = STATUS_SUCCESS;
8355 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
8361 if( AFSGlobalDotDirEntry != NULL)
8364 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
8365 AFS_OBJECT_REFERENCE_GLOBAL);
8367 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
8369 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
8371 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
8373 ExFreePool( AFSGlobalDotDirEntry);
8375 AFSGlobalDotDirEntry = NULL;
8378 if( AFSGlobalDotDotDirEntry != NULL)
8381 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
8382 AFS_OBJECT_REFERENCE_GLOBAL);
8384 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
8386 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
8388 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
8390 ExFreePool( AFSGlobalDotDotDirEntry);
8392 AFSGlobalDotDotDirEntry = NULL;
8395 if( AFSSpecialShareNames != NULL)
8398 pDirNode = AFSSpecialShareNames;
8400 while( pDirNode != NULL)
8403 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
8405 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
8406 AFS_OBJECT_REFERENCE_GLOBAL);
8408 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
8410 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
8412 ExFreePool( pDirNode->NonPaged);
8414 ExFreePool( pDirNode);
8416 pDirNode = pLastDirNode;
8419 AFSSpecialShareNames = NULL;
8427 AFSDefaultLogMsg( IN ULONG Subsystem,
8433 UNREFERENCED_PARAMETER(Subsystem);
8434 UNREFERENCED_PARAMETER(Level);
8435 NTSTATUS ntStatus = STATUS_SUCCESS;
8437 char chDebugBuffer[ 256];
8442 va_start( va_args, Format);
8444 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8449 if( NT_SUCCESS( ntStatus))
8451 DbgPrint( chDebugBuffer);
8461 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8462 IN ULONG InputBufferLength,
8463 IN AFSStatusInfoCB *StatusInfo,
8464 OUT ULONG *ReturnLength)
8467 NTSTATUS ntStatus = STATUS_SUCCESS;
8468 AFSVolumeCB *pVolumeCB = NULL;
8469 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8470 AFSVolumeCB *pNewVolumeCB = NULL;
8471 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8472 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8473 AFSObjectInfoCB *pObjectInfo = NULL;
8474 ULONGLONG ullIndex = 0;
8475 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8476 AFSNameArrayHdr *pNameArray = NULL;
8477 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8478 AFSDirectoryCB *pNewParentDirEntry = NULL;
8485 // If we are given a FID then look up the entry by that, otherwise
8489 if( GetStatusInfo->FileID.Cell != 0 &&
8490 GetStatusInfo->FileID.Volume != 0 &&
8491 GetStatusInfo->FileID.Vnode != 0 &&
8492 GetStatusInfo->FileID.Unique != 0)
8495 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8498 // Locate the volume node
8501 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8503 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8505 (AFSBTreeEntry **)&pVolumeCB);
8507 if( pVolumeCB != NULL)
8510 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8512 lCount = AFSVolumeIncrement( pVolumeCB,
8513 VolumeReferenceReason);
8515 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8516 AFS_TRACE_LEVEL_VERBOSE,
8517 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
8519 VolumeReferenceReason,
8523 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8525 if( !NT_SUCCESS( ntStatus) ||
8528 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8531 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8534 pObjectInfo = &pVolumeCB->ObjectInformation;
8536 lCount = AFSObjectInfoIncrement( pObjectInfo,
8537 AFS_OBJECT_REFERENCE_STATUS);
8539 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8540 AFS_TRACE_LEVEL_VERBOSE,
8541 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8548 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8551 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8553 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8555 (AFSBTreeEntry **)&pObjectInfo);
8557 if( pObjectInfo != NULL)
8561 // Reference the node so it won't be torn down
8564 lCount = AFSObjectInfoIncrement( pObjectInfo,
8565 AFS_OBJECT_REFERENCE_STATUS);
8567 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8568 AFS_TRACE_LEVEL_VERBOSE,
8569 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8574 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8576 if( !NT_SUCCESS( ntStatus) ||
8577 pObjectInfo == NULL)
8579 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8586 if( GetStatusInfo->FileNameLength == 0 ||
8587 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8589 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8592 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8593 uniFullPathName.MaximumLength = uniFullPathName.Length;
8595 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8598 // This name should begin with the \afs server so parse it off and check it
8601 FsRtlDissectName( uniFullPathName,
8605 if( RtlCompareUnicodeString( &uniComponentName,
8609 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8610 AFS_TRACE_LEVEL_ERROR,
8611 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8614 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8617 uniFullPathName = uniRemainingPath;
8619 uniParsedName = uniFullPathName;
8625 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8628 if( pNameArray == NULL)
8630 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8633 pVolumeCB = AFSGlobalRoot;
8635 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8638 // Increment the ref count on the volume and dir entry for correct processing below
8641 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8643 lCount = AFSVolumeIncrement( pVolumeCB,
8644 VolumeReferenceReason);
8646 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8647 AFS_TRACE_LEVEL_VERBOSE,
8648 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8650 VolumeReferenceReason,
8653 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8655 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8656 AFS_TRACE_LEVEL_VERBOSE,
8657 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8658 &pParentDirEntry->NameInformation.FileName,
8663 ntStatus = AFSLocateNameEntry( NULL,
8668 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8669 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8673 &NewVolumeReferenceReason,
8674 &pNewParentDirEntry,
8678 if ( pNewVolumeCB != NULL)
8682 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8683 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8684 // the reference on pVolumeCB that was held prior to the call.
8685 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8686 // will be released second.
8689 lCount = AFSVolumeDecrement( pVolumeCB,
8690 VolumeReferenceReason);
8692 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8693 AFS_TRACE_LEVEL_VERBOSE,
8694 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8696 VolumeReferenceReason,
8699 pVolumeCB = pNewVolumeCB;
8701 pNewVolumeCB = NULL;
8703 VolumeReferenceReason = NewVolumeReferenceReason;
8705 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8709 // AFSLocateNameEntry does not alter the reference count of
8710 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8711 // a reference held.
8714 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8716 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8717 AFS_TRACE_LEVEL_VERBOSE,
8718 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8719 &pParentDirEntry->NameInformation.FileName,
8723 pParentDirEntry = pNewParentDirEntry;
8725 pNewParentDirEntry = NULL;
8727 if( !NT_SUCCESS( ntStatus) ||
8728 ntStatus == STATUS_REPARSE)
8733 try_return( ntStatus);
8736 pObjectInfo = pDirectoryEntry->ObjectInformation;
8738 lCount = AFSObjectInfoIncrement( pObjectInfo,
8739 AFS_OBJECT_REFERENCE_STATUS);
8741 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8742 AFS_TRACE_LEVEL_VERBOSE,
8743 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8749 // At this point we have an object info block, return the information
8752 StatusInfo->FileId = pObjectInfo->FileId;
8754 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8756 StatusInfo->Expiration = pObjectInfo->Expiration;
8758 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8760 StatusInfo->FileType = pObjectInfo->FileType;
8762 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8764 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8766 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8768 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8770 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8772 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8774 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8776 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8778 StatusInfo->EaSize = pObjectInfo->EaSize;
8780 StatusInfo->Links = pObjectInfo->Links;
8783 // Return the information length
8786 *ReturnLength = sizeof( AFSStatusInfoCB);
8790 if( pDirectoryEntry != NULL)
8793 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8795 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8796 AFS_TRACE_LEVEL_VERBOSE,
8797 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8798 &pDirectoryEntry->NameInformation.FileName,
8803 ASSERT( lCount >= 0);
8806 if ( pParentDirEntry != NULL)
8809 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8811 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8812 AFS_TRACE_LEVEL_VERBOSE,
8813 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8814 &pParentDirEntry->NameInformation.FileName,
8819 ASSERT( lCount >= 0);
8822 if( pObjectInfo != NULL)
8825 lCount = AFSObjectInfoDecrement( pObjectInfo,
8826 AFS_OBJECT_REFERENCE_STATUS);
8828 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8829 AFS_TRACE_LEVEL_VERBOSE,
8830 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8835 if( pVolumeCB != NULL)
8838 lCount = AFSVolumeDecrement( pVolumeCB,
8839 VolumeReferenceReason);
8841 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8842 AFS_TRACE_LEVEL_VERBOSE,
8843 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8845 VolumeReferenceReason,
8849 if( pNameArray != NULL)
8852 AFSFreeNameArray( pNameArray);
8860 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8861 IN UNICODE_STRING *ComponentName)
8864 NTSTATUS ntStatus = STATUS_SUCCESS;
8865 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8866 AFSDirectoryCB *pDirEntry = NULL;
8874 // Search for the entry in the parent
8877 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8878 AFS_TRACE_LEVEL_VERBOSE_2,
8879 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8882 ulCRC = AFSGenerateCRC( ComponentName,
8885 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8888 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8892 if( pDirEntry == NULL)
8896 // Missed so perform a case insensitive lookup
8899 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8900 AFS_TRACE_LEVEL_VERBOSE_2,
8901 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8904 ulCRC = AFSGenerateCRC( ComponentName,
8907 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8911 if( pDirEntry == NULL)
8915 // OK, if this component is a valid short name then try
8916 // a lookup in the short name tree
8919 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8920 RtlIsNameLegalDOS8Dot3( ComponentName,
8925 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8926 AFS_TRACE_LEVEL_VERBOSE_2,
8927 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8930 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8937 if( pDirEntry != NULL)
8939 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8941 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8942 AFS_TRACE_LEVEL_VERBOSE,
8943 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8944 &pDirEntry->NameInformation.FileName,
8949 ASSERT( lCount >= 0);
8952 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8954 if( pDirEntry == NULL)
8957 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8958 AFS_TRACE_LEVEL_VERBOSE_2,
8959 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8961 STATUS_OBJECT_NAME_NOT_FOUND));
8963 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8967 // We have the symlink object but previously failed to process it so return access
8971 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8972 AFS_TRACE_LEVEL_VERBOSE_2,
8973 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8976 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8978 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8980 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8981 AFS_TRACE_LEVEL_VERBOSE,
8982 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8983 &pDirEntry->NameInformation.FileName,
8988 ASSERT( lCount >= 0);
8999 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
9000 OUT UNICODE_STRING *ComponentName)
9003 NTSTATUS ntStatus = STATUS_SUCCESS;
9004 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
9006 uniFullPathName = *FullPathName;
9011 FsRtlDissectName( uniFullPathName,
9015 if( uniRemainingPath.Length == 0)
9020 uniFullPathName = uniRemainingPath;
9023 if( uniComponentName.Length > 0)
9025 *ComponentName = uniComponentName;
9032 AFSDumpTraceFiles_Default()
9038 AFSValidNameFormat( IN UNICODE_STRING *FileName)
9041 BOOLEAN bIsValidName = TRUE;
9047 while( usIndex < FileName->Length/sizeof( WCHAR))
9050 if( FileName->Buffer[ usIndex] == L':' ||
9051 FileName->Buffer[ usIndex] == L'*' ||
9052 FileName->Buffer[ usIndex] == L'?' ||
9053 FileName->Buffer[ usIndex] == L'"' ||
9054 FileName->Buffer[ usIndex] == L'<' ||
9055 FileName->Buffer[ usIndex] == L'>')
9057 bIsValidName = FALSE;
9065 return bIsValidName;
9069 AFSCreateDefaultSecurityDescriptor()
9072 NTSTATUS ntStatus = STATUS_SUCCESS;
9074 ULONG ulSACLSize = 0;
9075 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
9076 ULONG ulACESize = 0;
9077 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
9078 ULONG ulSDLength = 0;
9079 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
9080 PSID pWorldSID = NULL;
9081 ULONG *pulSubAuthority = NULL;
9082 ULONG ulWorldSIDLEngth = 0;
9087 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
9089 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
9091 AFS_GENERIC_MEMORY_29_TAG);
9093 if( pWorldSID == NULL)
9095 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
9097 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9100 RtlZeroMemory( pWorldSID,
9103 RtlInitializeSid( pWorldSID,
9104 &SeWorldSidAuthority,
9107 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
9108 *pulSubAuthority = SECURITY_WORLD_RID;
9110 if( AFSRtlSetSaclSecurityDescriptor == NULL)
9113 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
9118 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
9120 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
9122 AFS_GENERIC_MEMORY_29_TAG);
9127 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
9129 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9132 RtlZeroMemory( pACE,
9135 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
9136 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
9137 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
9138 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
9140 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
9142 SeExports->SeLowMandatorySid);
9144 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
9145 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
9147 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
9149 AFS_GENERIC_MEMORY_29_TAG);
9154 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
9156 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9159 ntStatus = RtlCreateAcl( pSACL,
9163 if( !NT_SUCCESS( ntStatus))
9166 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
9169 try_return( ntStatus);
9172 ntStatus = RtlAddAce( pSACL,
9176 pACE->Header.AceSize);
9178 if( !NT_SUCCESS( ntStatus))
9181 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
9184 try_return( ntStatus);
9188 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
9189 sizeof( SECURITY_DESCRIPTOR),
9190 AFS_GENERIC_MEMORY_27_TAG);
9192 if( pSecurityDescr == NULL)
9195 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9197 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9200 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
9201 SECURITY_DESCRIPTOR_REVISION);
9203 if( !NT_SUCCESS( ntStatus))
9206 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
9209 try_return( ntStatus);
9212 if( AFSRtlSetSaclSecurityDescriptor != NULL)
9214 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
9219 if( !NT_SUCCESS( ntStatus))
9222 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
9225 try_return( ntStatus);
9230 // Add in the group and owner to the SD
9233 if( AFSRtlSetGroupSecurityDescriptor != NULL)
9235 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
9239 if( !NT_SUCCESS( ntStatus))
9242 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
9245 try_return( ntStatus);
9249 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
9253 if( !NT_SUCCESS( ntStatus))
9256 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
9259 try_return( ntStatus);
9262 if( !RtlValidSecurityDescriptor( pSecurityDescr))
9265 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
9267 try_return( ntStatus = STATUS_INVALID_PARAMETER);
9270 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
9272 AFS_GENERIC_MEMORY_27_TAG);
9274 if( pRelativeSecurityDescr == NULL)
9277 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9279 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9282 ulSDLength = PAGE_SIZE;
9284 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
9285 pRelativeSecurityDescr,
9288 if( !NT_SUCCESS( ntStatus))
9291 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
9294 try_return( ntStatus);
9297 AFSDefaultSD = pRelativeSecurityDescr;
9301 if( !NT_SUCCESS( ntStatus))
9304 if( pRelativeSecurityDescr != NULL)
9306 ExFreePool( pRelativeSecurityDescr);
9310 if( pSecurityDescr != NULL)
9312 ExFreePool( pSecurityDescr);
9325 if( pWorldSID != NULL)
9327 ExFreePool( pWorldSID);
9335 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
9336 OUT UNICODE_STRING *ParentPath)
9339 *ParentPath = *FullFileName;
9342 // If the final character is a \, jump over it
9345 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
9347 ParentPath->Length -= sizeof( WCHAR);
9350 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
9352 ParentPath->Length -= sizeof( WCHAR);
9356 // And the separator
9359 ParentPath->Length -= sizeof( WCHAR);
9365 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
9366 IN AFSObjectInfoCB *ObjectInfo,
9367 IN BOOLEAN WriteAccess,
9368 OUT GUID *AuthGroup)
9371 NTSTATUS ntStatus = STATUS_SUCCESS;
9372 GUID stAuthGroup, stZeroAuthGroup;
9373 BOOLEAN bFoundAuthGroup = FALSE;
9374 AFSCcb *pCcb = NULL;
9380 RtlZeroMemory( &stAuthGroup,
9383 RtlZeroMemory( &stZeroAuthGroup,
9389 if( ObjectInfo != NULL &&
9390 ObjectInfo->Fcb != NULL)
9392 pFcb = ObjectInfo->Fcb;
9399 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
9402 pCcb = Fcb->CcbListHead;
9404 while( pCcb != NULL)
9408 pCcb->GrantedAccess & FILE_WRITE_DATA)
9410 RtlCopyMemory( &stAuthGroup,
9414 bFoundAuthGroup = TRUE;
9418 else if( pCcb->GrantedAccess & FILE_READ_DATA)
9421 // At least get the read-only access
9424 RtlCopyMemory( &stAuthGroup,
9428 bFoundAuthGroup = TRUE;
9431 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9434 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9437 if( !bFoundAuthGroup)
9440 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9441 (ULONGLONG)PsGetCurrentThreadId(),
9444 if( RtlCompareMemory( &stZeroAuthGroup,
9446 sizeof( GUID)) == sizeof( GUID))
9449 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9451 try_return( ntStatus = STATUS_ACCESS_DENIED);
9455 RtlCopyMemory( AuthGroup,
9468 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9469 IN ULONG InvalidateReason)
9472 NTSTATUS ntStatus = STATUS_SUCCESS;
9475 ULONG ulProcessCount = 0;
9482 switch( InvalidateReason)
9485 case AFS_INVALIDATE_DELETED:
9488 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9489 ObjectInfo->Fcb != NULL)
9492 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9495 ObjectInfo->Links = 0;
9497 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9499 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9504 // Clear out the extents
9505 // And get rid of them (note this involves waiting
9506 // for any writes or reads to the cache to complete)
9509 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9512 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9518 case AFS_INVALIDATE_DATA_VERSION:
9521 LARGE_INTEGER liCurrentOffset = {0,0};
9522 LARGE_INTEGER liFlushLength = {0,0};
9523 ULONG ulFlushLength = 0;
9524 BOOLEAN bLocked = FALSE;
9525 BOOLEAN bExtentsLocked = FALSE;
9526 BOOLEAN bCleanExtents = FALSE;
9528 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9529 ObjectInfo->Fcb != NULL)
9532 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9537 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9538 AFS_TRACE_LEVEL_VERBOSE,
9539 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9540 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9541 PsGetCurrentThread()));
9543 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9546 bExtentsLocked = TRUE;
9549 // There are several possibilities here:
9551 // 0. If there are no extents or all of the extents are dirty, do nothing.
9553 // 1. There could be nothing dirty and an open reference count of zero
9554 // in which case we can just tear down all of the extents without
9555 // holding any resources.
9557 // 2. There could be nothing dirty and a non-zero open reference count
9558 // in which case we can issue a CcPurge against the entire file
9559 // while holding just the Fcb Resource.
9561 // 3. There can be dirty extents in which case we need to identify
9562 // the non-dirty ranges and then perform a CcPurge on just the
9563 // non-dirty ranges while holding just the Fcb Resource.
9566 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9569 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9572 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9574 bExtentsLocked = FALSE;
9576 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9579 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9583 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9589 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9590 AFS_TRACE_LEVEL_VERBOSE,
9591 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9592 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9593 PsGetCurrentThread()));
9595 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9598 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9605 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9606 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9612 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9613 AFS_TRACE_LEVEL_WARNING,
9614 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9615 ObjectInfo->FileId.Cell,
9616 ObjectInfo->FileId.Volume,
9617 ObjectInfo->FileId.Vnode,
9618 ObjectInfo->FileId.Unique));
9620 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9625 bCleanExtents = TRUE;
9628 __except( EXCEPTION_EXECUTE_HANDLER)
9631 ntStatus = GetExceptionCode();
9635 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9636 ObjectInfo->FileId.Cell,
9637 ObjectInfo->FileId.Volume,
9638 ObjectInfo->FileId.Vnode,
9639 ObjectInfo->FileId.Unique,
9642 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9645 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9646 AFS_TRACE_LEVEL_VERBOSE,
9647 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9648 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9649 PsGetCurrentThread()));
9651 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9657 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9659 bExtentsLocked = FALSE;
9661 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9662 AFS_TRACE_LEVEL_VERBOSE,
9663 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9664 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9665 PsGetCurrentThread()));
9667 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9670 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9675 // Must build a list of non-dirty ranges from the beginning of the file
9676 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9677 // ranges. In all but the most extreme random data write scenario there will
9678 // be significantly fewer.
9680 // For each range we need offset and size.
9683 AFSByteRange * ByteRangeList = NULL;
9684 ULONG ulByteRangeCount = 0;
9686 BOOLEAN bPurgeOnClose = FALSE;
9691 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9694 if ( ByteRangeList != NULL ||
9695 ulByteRangeCount == 0)
9698 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9705 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9707 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9708 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9709 &ByteRangeList[ulIndex].FileOffset,
9714 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9715 AFS_TRACE_LEVEL_WARNING,
9716 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9717 ObjectInfo->FileId.Cell,
9718 ObjectInfo->FileId.Volume,
9719 ObjectInfo->FileId.Vnode,
9720 ObjectInfo->FileId.Unique));
9722 bPurgeOnClose = TRUE;
9727 bCleanExtents = TRUE;
9730 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9732 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9734 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9741 // We couldn't allocate the memory to build the purge list
9742 // so just walk the extent list while holding the ExtentsList Resource.
9743 // This could deadlock but we do not have much choice.
9746 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9748 bExtentsLocked = TRUE;
9750 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9754 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9758 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9760 while( ulProcessCount < ulCount)
9762 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9764 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9766 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9767 &pEntry->FileOffset,
9772 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9773 AFS_TRACE_LEVEL_WARNING,
9774 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9775 ObjectInfo->FileId.Cell,
9776 ObjectInfo->FileId.Volume,
9777 ObjectInfo->FileId.Vnode,
9778 ObjectInfo->FileId.Unique));
9780 bPurgeOnClose = TRUE;
9785 bCleanExtents = TRUE;
9789 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9792 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9794 while( liFlushLength.QuadPart > 0)
9797 if( liFlushLength.QuadPart > 512 * 1024000)
9799 ulFlushLength = 512 * 1024000;
9803 ulFlushLength = liFlushLength.LowPart;
9806 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9812 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9813 AFS_TRACE_LEVEL_WARNING,
9814 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9815 ObjectInfo->FileId.Cell,
9816 ObjectInfo->FileId.Volume,
9817 ObjectInfo->FileId.Vnode,
9818 ObjectInfo->FileId.Unique));
9820 bPurgeOnClose = TRUE;
9825 bCleanExtents = TRUE;
9828 liFlushLength.QuadPart -= ulFlushLength;
9832 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9840 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9846 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9847 AFS_TRACE_LEVEL_WARNING,
9848 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9849 ObjectInfo->FileId.Cell,
9850 ObjectInfo->FileId.Volume,
9851 ObjectInfo->FileId.Vnode,
9852 ObjectInfo->FileId.Unique));
9854 bPurgeOnClose = TRUE;
9859 bCleanExtents = TRUE;
9866 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9870 __except( EXCEPTION_EXECUTE_HANDLER)
9873 ntStatus = GetExceptionCode();
9877 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9878 ObjectInfo->FileId.Cell,
9879 ObjectInfo->FileId.Volume,
9880 ObjectInfo->FileId.Vnode,
9881 ObjectInfo->FileId.Unique,
9885 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9886 AFS_TRACE_LEVEL_VERBOSE,
9887 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9888 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9889 PsGetCurrentThread()));
9891 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9895 if ( bExtentsLocked)
9898 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9904 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9910 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9920 // Destroy the reference passed in by the caller to AFSInvalidateObject
9921 // or AFSQueueInvalidateObject
9924 lCount = AFSObjectInfoDecrement( ObjectInfo,
9925 AFS_OBJECT_REFERENCE_INVALIDATION);
9927 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9928 AFS_TRACE_LEVEL_VERBOSE,
9929 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",