2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSGeneric.cpp
39 #include "AFSCommon.h"
42 // Function: AFSExceptionFilter
46 // This function is the exception handler
50 // A status is returned for the function
54 AFSExceptionFilter( IN CHAR *FunctionString,
56 IN PEXCEPTION_POINTERS ExceptPtrs)
59 UNREFERENCED_PARAMETER(Code);
60 PEXCEPTION_RECORD ExceptRec;
66 ExceptRec = ExceptPtrs->ExceptionRecord;
68 Context = ExceptPtrs->ContextRecord;
72 "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
76 ExceptRec->ExceptionCode,
77 ExceptRec->ExceptionAddress,
78 (void *)AFSExceptionFilter);
80 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
82 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
83 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
85 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
87 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
90 KeBugCheck( (ULONG)-2);
98 __except( EXCEPTION_EXECUTE_HANDLER)
104 return EXCEPTION_EXECUTE_HANDLER;
108 // Function: AFSLibExAllocatePoolWithTag()
110 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
111 // is configured on, then bugcheck the system if
112 // a memory allocation fails. The routine should be
113 // used for all memory allocations that are to be freed
114 // when the library is unloaded. Memory allocations that
115 // are to survive library unload and reload should be
116 // performed using AFSExAllocatePoolWithTag() which is
117 // provided by the AFS Framework.
120 // POOL_TYPE PoolType - Paged or NonPaged
121 // SIZE_T NumberOfBytes - requested allocation size
122 // ULONG Tag - Pool Allocation Tag to be applied for tracking
125 // void * - the memory allocation
129 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
130 IN SIZE_T NumberOfBytes,
134 void *pBuffer = NULL;
136 pBuffer = ExAllocatePoolWithTag( PoolType,
143 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
146 KeBugCheck( (ULONG)-2);
153 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
157 PsGetCurrentThread());
167 // Function: AFSAcquireExcl()
169 // Purpose: Called to acquire a resource exclusive with optional wait
172 // PERESOURCE Resource - Resource to acquire
173 // BOOLEAN Wait - Whether to block
176 // BOOLEAN - Whether the mask was acquired
180 AFSAcquireExcl( IN PERESOURCE Resource,
184 BOOLEAN bStatus = FALSE;
187 // Normal kernel APCs must be disabled before calling
188 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
191 KeEnterCriticalRegion();
193 bStatus = ExAcquireResourceExclusiveLite( Resource,
199 KeLeaveCriticalRegion();
206 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
210 BOOLEAN bStatus = FALSE;
212 KeEnterCriticalRegion();
214 bStatus = ExAcquireSharedStarveExclusive( Resource,
220 KeLeaveCriticalRegion();
227 // Function: AFSAcquireShared()
229 // Purpose: Called to acquire a resource shared with optional wait
232 // PERESOURCE Resource - Resource to acquire
233 // BOOLEAN Wait - Whether to block
236 // BOOLEAN - Whether the mask was acquired
240 AFSAcquireShared( IN PERESOURCE Resource,
244 BOOLEAN bStatus = FALSE;
246 KeEnterCriticalRegion();
248 bStatus = ExAcquireResourceSharedLite( Resource,
254 KeLeaveCriticalRegion();
261 // Function: AFSReleaseResource()
263 // Purpose: Called to release a resource
266 // PERESOURCE Resource - Resource to release
273 AFSReleaseResource( IN PERESOURCE Resource)
276 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
277 AFS_TRACE_LEVEL_VERBOSE,
278 "AFSReleaseResource Releasing lock %p Thread %08lX\n",
280 PsGetCurrentThread());
282 ExReleaseResourceLite( Resource);
284 KeLeaveCriticalRegion();
290 AFSConvertToShared( IN PERESOURCE Resource)
293 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
294 AFS_TRACE_LEVEL_VERBOSE,
295 "AFSConvertToShared Converting lock %p Thread %08lX\n",
297 PsGetCurrentThread());
299 ExConvertExclusiveToSharedLite( Resource);
305 // Function: AFSCompleteRequest
309 // This function completes irps
313 // A status is returned for the function
317 AFSCompleteRequest( IN PIRP Irp,
321 Irp->IoStatus.Status = Status;
323 IoCompleteRequest( Irp,
330 // Function: AFSGenerateCRC
334 // Given a device and filename this function generates a CRC
338 // A status is returned for the function
342 AFSGenerateCRC( IN PUNICODE_STRING FileName,
343 IN BOOLEAN UpperCaseName)
347 NTSTATUS ntStatus = STATUS_SUCCESS;
349 ntStatus = RtlHashUnicodeString( FileName,
351 HASH_STRING_ALGORITHM_DEFAULT,
354 if( !NT_SUCCESS( ntStatus))
363 AFSLockSystemBuffer( IN PIRP Irp,
367 void *pAddress = NULL;
369 if( Irp->MdlAddress != NULL)
372 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
375 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
378 pAddress = Irp->AssociatedIrp.SystemBuffer;
380 else if( Irp->UserBuffer != NULL)
383 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
389 if( Irp->MdlAddress != NULL)
393 // Lock the new Mdl in memory.
398 PIO_STACK_LOCATION pIoStack;
399 pIoStack = IoGetCurrentIrpStackLocation( Irp);
402 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
403 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
405 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
408 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
411 AFSDumpTraceFilesFnc();
413 IoFreeMdl( Irp->MdlAddress );
414 Irp->MdlAddress = NULL;
424 AFSLockUserBuffer( IN void *UserBuffer,
425 IN ULONG BufferLength,
429 NTSTATUS ntStatus = STATUS_SUCCESS;
430 void *pAddress = NULL;
436 pMdl = IoAllocateMdl( UserBuffer,
445 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
449 // Lock the new Mdl in memory.
455 MmProbeAndLockPages( pMdl,
459 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
462 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
465 AFSDumpTraceFilesFnc();
487 AFSMapToService( IN PIRP Irp,
491 NTSTATUS ntStatus = STATUS_SUCCESS;
492 void *pMappedBuffer = NULL;
493 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
499 if( pDevExt->Specific.Control.ServiceProcess == NULL)
502 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
505 if( Irp->MdlAddress == NULL)
508 if( AFSLockSystemBuffer( Irp,
512 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
517 // Attach to the service process for mapping
520 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
521 (PRKAPC_STATE)&stApcState);
523 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
530 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
537 return pMappedBuffer;
541 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
545 NTSTATUS ntStatus = STATUS_SUCCESS;
546 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
552 if( pDevExt->Specific.Control.ServiceProcess == NULL)
555 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
562 // Attach to the service process for mapping
565 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
566 (PRKAPC_STATE)&stApcState);
568 MmUnmapLockedPages( MappedBuffer,
571 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
583 AFSInitializeLibraryDevice()
586 NTSTATUS ntStatus = STATUS_SUCCESS;
587 AFSDeviceExt *pDeviceExt = NULL;
592 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
595 // The PIOCtl file name
598 RtlInitUnicodeString( &AFSPIOCtlName,
599 AFS_PIOCTL_FILE_INTERFACE_NAME);
602 // And the global root share name
605 RtlInitUnicodeString( &AFSGlobalRootName,
606 AFS_GLOBAL_ROOT_SHARE_NAME);
614 AFSRemoveLibraryDevice()
617 NTSTATUS ntStatus = STATUS_SUCCESS;
628 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
632 UNREFERENCED_PARAMETER(DeviceObject);
633 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
635 AFSCompleteRequest( Irp,
642 AFSInitializeGlobalDirectoryEntries()
645 NTSTATUS ntStatus = STATUS_SUCCESS;
646 AFSDirectoryCB *pDirNode = NULL;
647 ULONG ulEntryLength = 0;
648 AFSObjectInfoCB *pObjectInfoCB = NULL;
649 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
656 // Initialize the global . entry
659 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
662 if( pObjectInfoCB == NULL)
665 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
666 AFS_TRACE_LEVEL_ERROR,
667 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
670 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
673 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
674 AFS_OBJECT_REFERENCE_GLOBAL);
676 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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)
1145 pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1148 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1149 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1152 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1155 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1158 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1159 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1163 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1164 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1165 pObjectInfoCB->TargetFileId.Unique == 0 &&
1166 pDirNode->NameInformation.TargetName.Length == 0)
1170 // This will ensure we perform a validation on the node
1173 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1176 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1179 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1184 // Object specific information
1187 pObjectInfoCB->Links = DirEnumEntry->Links;
1189 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1191 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1195 if( !NT_SUCCESS( ntStatus))
1198 if( pNonPagedDirEntry != NULL)
1201 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1203 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1206 if( pDirNode != NULL)
1209 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1210 AFS_TRACE_LEVEL_VERBOSE,
1211 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1214 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1220 // Dereference our object info block if we have one
1223 if( pObjectInfoCB != NULL)
1226 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1227 AFS_OBJECT_REFERENCE_DIRENTRY);
1229 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1230 AFS_TRACE_LEVEL_VERBOSE,
1231 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1235 if( bAllocatedObjectCB)
1238 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1240 AFSDeleteObjectInfo( &pObjectInfoCB);
1250 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1251 IN BOOLEAN DirectoryEntry)
1254 BOOLEAN bReturn = TRUE;
1255 ACCESS_MASK stAccessMask = 0;
1258 // Get rid of anything we don't know about
1261 DesiredAccess = (DesiredAccess &
1267 ACCESS_SYSTEM_SECURITY |
1271 FILE_READ_ATTRIBUTES |
1272 FILE_WRITE_ATTRIBUTES |
1273 FILE_LIST_DIRECTORY |
1279 // Our 'read only' access mask. These are the accesses we will
1280 // allow for a read only file
1283 stAccessMask = DELETE |
1288 ACCESS_SYSTEM_SECURITY |
1292 FILE_READ_ATTRIBUTES |
1293 FILE_WRITE_ATTRIBUTES |
1295 FILE_LIST_DIRECTORY |
1299 // For a directory, add in the directory specific accesses
1305 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1310 if( FlagOn( DesiredAccess, ~stAccessMask))
1314 // A write access is set ...
1324 AFSEvaluateNode( IN GUID *AuthGroup,
1325 IN AFSDirectoryCB *DirEntry)
1328 NTSTATUS ntStatus = STATUS_SUCCESS;
1329 AFSDirEnumEntry *pDirEntry = NULL;
1330 UNICODE_STRING uniTargetName;
1335 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1340 if( !NT_SUCCESS( ntStatus))
1343 try_return( ntStatus);
1346 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1348 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1350 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1352 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1354 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1356 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1358 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1360 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1362 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1364 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1366 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1368 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1371 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1374 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1375 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1378 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1381 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1383 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1386 // If we have a target name then see if it needs updating ...
1389 if( pDirEntry->TargetNameLength > 0)
1393 // Update the target name information if needed
1396 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1398 uniTargetName.MaximumLength = uniTargetName.Length;
1400 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1402 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1405 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1406 RtlCompareUnicodeString( &uniTargetName,
1407 &DirEntry->NameInformation.TargetName,
1412 // Update the target name
1415 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1417 uniTargetName.Buffer,
1418 uniTargetName.Length);
1420 if( !NT_SUCCESS( ntStatus))
1423 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1425 try_return( ntStatus);
1429 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1434 if( pDirEntry != NULL)
1437 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1445 AFSValidateSymLink( IN GUID *AuthGroup,
1446 IN AFSDirectoryCB *DirEntry)
1449 NTSTATUS ntStatus = STATUS_SUCCESS;
1450 AFSDirEnumEntry *pDirEntry = NULL;
1451 UNICODE_STRING uniTargetName;
1456 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1461 if( !NT_SUCCESS( ntStatus))
1464 try_return( ntStatus);
1467 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1468 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1471 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1472 AFS_TRACE_LEVEL_VERBOSE_2,
1473 "AFSValidateSymLink Invalid type Status %08lX\n",
1474 STATUS_OBJECT_NAME_NOT_FOUND);
1476 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1479 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1481 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1483 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1486 // Update the target name information if needed
1489 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1491 uniTargetName.MaximumLength = uniTargetName.Length;
1493 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1495 if( uniTargetName.Length > 0)
1498 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1501 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1502 RtlCompareUnicodeString( &uniTargetName,
1503 &DirEntry->NameInformation.TargetName,
1508 // Update the target name
1511 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1513 uniTargetName.Buffer,
1514 uniTargetName.Length);
1516 if( !NT_SUCCESS( ntStatus))
1519 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1521 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1525 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1529 // If the FileType is the same then nothing to do since it IS
1533 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1536 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1538 try_return( ntStatus = STATUS_SUCCESS);
1541 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1543 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1545 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1547 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1549 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1551 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1553 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1555 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1557 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1560 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1563 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1564 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1567 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1570 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1572 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1576 if( pDirEntry != NULL)
1579 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1587 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1591 NTSTATUS ntStatus = STATUS_SUCCESS;
1592 IO_STATUS_BLOCK stIoStatus;
1594 AFSObjectInfoCB * pParentObjectInfo = NULL;
1596 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1597 AFS_TRACE_LEVEL_VERBOSE,
1598 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1599 (*ppObjectInfo)->FileType,
1600 (*ppObjectInfo)->FileId.Cell,
1601 (*ppObjectInfo)->FileId.Volume,
1602 (*ppObjectInfo)->FileId.Vnode,
1603 (*ppObjectInfo)->FileId.Unique,
1606 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1609 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1610 &(*ppObjectInfo)->ParentFileId);
1613 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1614 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1615 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1618 // We only act on the mount point itself, not the target. If the
1619 // node has been deleted then mark it as such otherwise indicate
1620 // it requires verification
1623 if( Reason == AFS_INVALIDATE_DELETED)
1625 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1630 if( Reason == AFS_INVALIDATE_FLUSHED)
1633 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1635 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1638 (*ppObjectInfo)->Expiration.QuadPart = 0;
1640 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1642 (*ppObjectInfo)->TargetFileId.Unique = 0;
1644 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1645 AFS_TRACE_LEVEL_VERBOSE,
1646 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1647 (*ppObjectInfo)->FileId.Cell,
1648 (*ppObjectInfo)->FileId.Volume,
1649 (*ppObjectInfo)->FileId.Vnode,
1650 (*ppObjectInfo)->FileId.Unique);
1652 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1655 if ( pParentObjectInfo != NULL)
1658 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1660 if( Reason == AFS_INVALIDATE_CREDS)
1662 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1665 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1666 Reason == AFS_INVALIDATE_FLUSHED)
1668 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1672 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1675 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1678 FILE_ACTION_MODIFIED);
1681 try_return( ntStatus);
1685 // Depending on the reason for invalidation then perform work on the node
1691 case AFS_INVALIDATE_DELETED:
1695 // Mark this node as invalid
1698 (*ppObjectInfo)->Links = 0;
1700 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1702 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1703 AFS_TRACE_LEVEL_VERBOSE,
1704 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1705 (*ppObjectInfo)->FileId.Cell,
1706 (*ppObjectInfo)->FileId.Volume,
1707 (*ppObjectInfo)->FileId.Vnode,
1708 (*ppObjectInfo)->FileId.Unique);
1710 if( pParentObjectInfo != NULL)
1713 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1714 AFS_TRACE_LEVEL_VERBOSE,
1715 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1716 pParentObjectInfo->FileId.Cell,
1717 pParentObjectInfo->FileId.Volume,
1718 pParentObjectInfo->FileId.Vnode,
1719 pParentObjectInfo->FileId.Unique);
1721 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1723 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1725 pParentObjectInfo->Expiration.QuadPart = 0;
1727 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1729 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1733 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1736 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1739 FILE_ACTION_REMOVED);
1742 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1745 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1751 case AFS_INVALIDATE_FLUSHED:
1754 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1755 (*ppObjectInfo)->Fcb != NULL)
1758 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1759 AFS_TRACE_LEVEL_VERBOSE,
1760 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1761 (*ppObjectInfo)->FileId.Cell,
1762 (*ppObjectInfo)->FileId.Volume,
1763 (*ppObjectInfo)->FileId.Vnode,
1764 (*ppObjectInfo)->FileId.Unique);
1766 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1772 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1777 if( !NT_SUCCESS( stIoStatus.Status))
1780 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1781 AFS_TRACE_LEVEL_ERROR,
1782 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1783 (*ppObjectInfo)->FileId.Cell,
1784 (*ppObjectInfo)->FileId.Volume,
1785 (*ppObjectInfo)->FileId.Vnode,
1786 (*ppObjectInfo)->FileId.Unique,
1788 stIoStatus.Information);
1790 ntStatus = stIoStatus.Status;
1794 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1797 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1803 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1804 AFS_TRACE_LEVEL_WARNING,
1805 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1806 (*ppObjectInfo)->FileId.Cell,
1807 (*ppObjectInfo)->FileId.Volume,
1808 (*ppObjectInfo)->FileId.Vnode,
1809 (*ppObjectInfo)->FileId.Unique);
1811 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1815 __except( EXCEPTION_EXECUTE_HANDLER)
1818 ntStatus = GetExceptionCode();
1822 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1823 (*ppObjectInfo)->FileId.Cell,
1824 (*ppObjectInfo)->FileId.Volume,
1825 (*ppObjectInfo)->FileId.Vnode,
1826 (*ppObjectInfo)->FileId.Unique,
1829 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1832 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1835 // Clear out the extents
1836 // Get rid of them (note this involves waiting
1837 // for any writes or reads to the cache to complete)
1840 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1844 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1847 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1850 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1851 AFS_TRACE_LEVEL_VERBOSE,
1852 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1853 (*ppObjectInfo)->FileId.Cell,
1854 (*ppObjectInfo)->FileId.Volume,
1855 (*ppObjectInfo)->FileId.Vnode,
1856 (*ppObjectInfo)->FileId.Unique);
1858 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1861 // Fall through to the default processing
1867 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1869 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1873 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1876 if( Reason == AFS_INVALIDATE_CREDS)
1878 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1881 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1883 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1887 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1890 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1893 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1896 FILE_ACTION_MODIFIED);
1898 else if ( pParentObjectInfo != NULL)
1901 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1904 FILE_ACTION_MODIFIED);
1908 // Indicate this node requires re-evaluation for the remaining reasons
1911 (*ppObjectInfo)->Expiration.QuadPart = 0;
1913 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1914 AFS_TRACE_LEVEL_VERBOSE,
1915 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1916 (*ppObjectInfo)->FileId.Cell,
1917 (*ppObjectInfo)->FileId.Volume,
1918 (*ppObjectInfo)->FileId.Vnode,
1919 (*ppObjectInfo)->FileId.Unique);
1921 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1923 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1924 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1925 ( Reason == AFS_INVALIDATE_CALLBACK ||
1926 Reason == AFS_INVALIDATE_EXPIRED))
1928 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1929 AFS_INVALIDATE_DATA_VERSION)))
1932 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1942 if ( pParentObjectInfo != NULL)
1945 AFSReleaseObjectInfo( &pParentObjectInfo);
1952 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1955 NTSTATUS ntStatus = STATUS_SUCCESS;
1956 AFSVolumeCB *pVolumeCB = NULL;
1957 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1958 ULONGLONG ullIndex = 0;
1959 AFSObjectInfoCB *pObjectInfo = NULL;
1965 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1966 AFS_TRACE_LEVEL_VERBOSE,
1967 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1968 InvalidateCB->FileID.Cell,
1969 InvalidateCB->FileID.Volume,
1970 InvalidateCB->FileID.Vnode,
1971 InvalidateCB->FileID.Unique,
1972 InvalidateCB->FileType,
1973 InvalidateCB->WholeVolume,
1974 InvalidateCB->Reason);
1977 // Need to locate the Fcb for the directory to purge
1980 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1981 AFS_TRACE_LEVEL_VERBOSE,
1982 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
1983 &pDevExt->Specific.RDR.VolumeTreeLock,
1984 PsGetCurrentThread());
1987 // Starve any exclusive waiters on this paticular call
1990 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1993 // Locate the volume node
1996 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1998 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2000 (AFSBTreeEntry **)&pVolumeCB);
2002 if( pVolumeCB != NULL)
2005 lCount = AFSVolumeIncrement( pVolumeCB,
2006 AFS_VOLUME_REFERENCE_INVALIDATE);
2008 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2009 AFS_TRACE_LEVEL_VERBOSE,
2010 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2015 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2017 if( !NT_SUCCESS( ntStatus) ||
2021 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2022 AFS_TRACE_LEVEL_WARNING,
2023 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2024 InvalidateCB->FileID.Cell,
2025 InvalidateCB->FileID.Volume,
2026 InvalidateCB->FileID.Vnode,
2027 InvalidateCB->FileID.Unique,
2030 try_return( ntStatus = STATUS_SUCCESS);
2034 // If this is a whole volume invalidation then go do it now
2037 if( InvalidateCB->WholeVolume)
2040 ntStatus = AFSInvalidateVolume( pVolumeCB,
2041 InvalidateCB->Reason);
2043 try_return( ntStatus);
2046 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
2049 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2052 pObjectInfo = &pVolumeCB->ObjectInformation;
2057 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2059 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2061 (AFSBTreeEntry **)&pObjectInfo);
2064 if( pObjectInfo != NULL)
2068 // Reference the node so it won't be torn down
2071 lCount = AFSObjectInfoIncrement( pObjectInfo,
2072 AFS_OBJECT_REFERENCE_INVALIDATION);
2074 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2075 AFS_TRACE_LEVEL_VERBOSE,
2076 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2081 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2083 if( !NT_SUCCESS( ntStatus) ||
2084 pObjectInfo == NULL)
2087 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2088 AFS_TRACE_LEVEL_VERBOSE,
2089 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2090 InvalidateCB->FileID.Cell,
2091 InvalidateCB->FileID.Volume,
2092 InvalidateCB->FileID.Vnode,
2093 InvalidateCB->FileID.Unique,
2096 try_return( ntStatus = STATUS_SUCCESS);
2099 AFSInvalidateObject( &pObjectInfo,
2100 InvalidateCB->Reason);
2104 if( pObjectInfo != NULL)
2107 lCount = AFSObjectInfoDecrement( pObjectInfo,
2108 AFS_OBJECT_REFERENCE_INVALIDATION);
2110 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2111 AFS_TRACE_LEVEL_VERBOSE,
2112 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2117 if ( pVolumeCB != NULL)
2120 lCount = AFSVolumeDecrement( pVolumeCB,
2121 AFS_VOLUME_REFERENCE_INVALIDATE);
2123 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2124 AFS_TRACE_LEVEL_VERBOSE,
2125 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2135 AFSIsChildOfParent( IN AFSFcb *Dcb,
2139 BOOLEAN bIsChild = FALSE;
2140 AFSFcb *pCurrentFcb = Fcb;
2141 AFSObjectInfoCB * pParentObjectInfo = NULL;
2143 while( pCurrentFcb != NULL)
2146 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2147 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2155 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2156 &pCurrentFcb->ObjectInformation->ParentFileId);
2158 if ( pParentObjectInfo != NULL)
2161 pCurrentFcb = pParentObjectInfo->Fcb;
2163 AFSReleaseObjectInfo( &pParentObjectInfo);
2177 AFSCreateHighIndex( IN AFSFileID *FileID)
2180 ULONGLONG ullIndex = 0;
2182 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2189 AFSCreateLowIndex( IN AFSFileID *FileID)
2192 ULONGLONG ullIndex = 0;
2194 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2200 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2201 IN ACCESS_MASK GrantedAccess,
2202 IN BOOLEAN DirectoryEntry)
2205 BOOLEAN bAccessGranted = TRUE;
2208 // Check if we are asking for read/write and granted only read only
2209 // NOTE: There will be more checks here
2212 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2214 AFSCheckForReadOnlyAccess( GrantedAccess,
2218 bAccessGranted = FALSE;
2221 return bAccessGranted;
2225 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2228 NTSTATUS ntStatus = STATUS_SUCCESS;
2229 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2235 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2237 if( AFSGlobalRoot == NULL)
2244 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2247 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2254 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2261 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2262 IN UNICODE_STRING *SubstituteName,
2263 IN ULONG StringIndex)
2266 NTSTATUS ntStatus = STATUS_SUCCESS;
2267 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2268 AFSSysNameCB *pSysName = NULL;
2269 ERESOURCE *pSysNameLock = NULL;
2272 UNICODE_STRING uniSysName;
2279 if( IoIs32bitProcess( NULL))
2282 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2284 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2289 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2291 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2295 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2297 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2301 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2302 AFS_TRACE_LEVEL_VERBOSE,
2303 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2305 PsGetCurrentThread());
2307 AFSAcquireShared( pSysNameLock,
2311 // Find where we are in the list
2314 while( pSysName != NULL &&
2315 ulIndex < StringIndex)
2318 pSysName = pSysName->fLink;
2323 if( pSysName == NULL)
2326 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2327 AFS_TRACE_LEVEL_VERBOSE_2,
2328 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2330 STATUS_OBJECT_NAME_NOT_FOUND);
2332 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2335 RtlInitUnicodeString( &uniSysName,
2338 // If it is a full component of @SYS then just substitue the
2342 if( RtlCompareUnicodeString( &uniSysName,
2347 SubstituteName->Length = pSysName->SysName.Length;
2348 SubstituteName->MaximumLength = SubstituteName->Length;
2350 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2351 SubstituteName->Length,
2352 AFS_SUBST_BUFFER_TAG);
2354 if( SubstituteName->Buffer == NULL)
2357 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2360 RtlCopyMemory( SubstituteName->Buffer,
2361 pSysName->SysName.Buffer,
2362 pSysName->SysName.Length);
2369 while( ComponentName->Buffer[ usIndex] != L'@')
2375 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2376 SubstituteName->MaximumLength = SubstituteName->Length;
2378 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2379 SubstituteName->Length,
2380 AFS_SUBST_BUFFER_TAG);
2382 if( SubstituteName->Buffer == NULL)
2385 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2388 RtlCopyMemory( SubstituteName->Buffer,
2389 ComponentName->Buffer,
2390 usIndex * sizeof( WCHAR));
2392 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2393 pSysName->SysName.Buffer,
2394 pSysName->SysName.Length);
2399 AFSReleaseResource( pSysNameLock);
2406 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2407 IN OUT UNICODE_STRING *ComponentName,
2408 IN UNICODE_STRING *SubstituteName,
2409 IN OUT UNICODE_STRING *RemainingPath,
2410 IN BOOLEAN FreePathName)
2413 NTSTATUS ntStatus = STATUS_SUCCESS;
2414 UNICODE_STRING uniPathName;
2415 USHORT usPrefixNameLen = 0;
2416 SHORT sNameLenDelta = 0;
2422 // If the passed in name can handle the additional length
2423 // then just moves things around
2426 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2428 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2430 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2433 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2436 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2437 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2438 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2441 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2442 SubstituteName->Buffer,
2443 SubstituteName->Length);
2445 FullPathName->Length += sNameLenDelta;
2447 ComponentName->Length += sNameLenDelta;
2449 ComponentName->MaximumLength = ComponentName->Length;
2451 if ( RemainingPath->Buffer)
2454 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2457 try_return( ntStatus);
2461 // Need to re-allocate the buffer
2464 uniPathName.Length = FullPathName->Length -
2465 ComponentName->Length +
2466 SubstituteName->Length;
2468 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2470 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2471 uniPathName.MaximumLength,
2472 AFS_NAME_BUFFER_FOUR_TAG);
2474 if( uniPathName.Buffer == NULL)
2477 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2480 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2482 usPrefixNameLen *= sizeof( WCHAR);
2484 RtlZeroMemory( uniPathName.Buffer,
2485 uniPathName.MaximumLength);
2487 RtlCopyMemory( uniPathName.Buffer,
2488 FullPathName->Buffer,
2491 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2492 SubstituteName->Buffer,
2493 SubstituteName->Length);
2495 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2498 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2499 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2500 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2503 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2505 ComponentName->Length += sNameLenDelta;
2507 ComponentName->MaximumLength = ComponentName->Length;
2509 if ( RemainingPath->Buffer)
2512 RemainingPath->Buffer = uniPathName.Buffer
2513 + (RemainingPath->Buffer - FullPathName->Buffer)
2514 + sNameLenDelta/sizeof( WCHAR);
2519 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2522 *FullPathName = uniPathName;
2533 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2537 NTSTATUS ntStatus = STATUS_SUCCESS;
2538 AFSObjectInfoCB *pCurrentObject = NULL;
2539 AFSObjectInfoCB *pNextObject = NULL;
2545 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2546 AFS_TRACE_LEVEL_VERBOSE,
2547 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2548 VolumeCB->ObjectInformation.FileId.Cell,
2549 VolumeCB->ObjectInformation.FileId.Volume,
2550 VolumeCB->ObjectInformation.FileId.Vnode,
2551 VolumeCB->ObjectInformation.FileId.Unique,
2555 // Depending on the reason for invalidation then perform work on the node
2561 case AFS_INVALIDATE_DELETED:
2565 // Mark this volume as invalid
2568 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2570 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2577 // Invalidate the volume root directory
2580 pCurrentObject = &VolumeCB->ObjectInformation;
2582 if ( pCurrentObject )
2585 lCount = AFSObjectInfoIncrement( pCurrentObject,
2586 AFS_OBJECT_REFERENCE_INVALIDATION);
2588 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2589 AFS_TRACE_LEVEL_VERBOSE,
2590 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2594 AFSInvalidateObject( &pCurrentObject,
2597 if ( pCurrentObject)
2600 lCount = AFSObjectInfoDecrement( pCurrentObject,
2601 AFS_OBJECT_REFERENCE_INVALIDATION);
2603 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2604 AFS_TRACE_LEVEL_VERBOSE,
2605 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2612 // Apply invalidation to all other volume objects
2615 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2618 pCurrentObject = VolumeCB->ObjectInfoListHead;
2620 if ( pCurrentObject)
2624 // Reference the node so it won't be torn down
2627 lCount = AFSObjectInfoIncrement( pCurrentObject,
2628 AFS_OBJECT_REFERENCE_INVALIDATION);
2630 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2631 AFS_TRACE_LEVEL_VERBOSE,
2632 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2637 while( pCurrentObject != NULL)
2640 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2646 // Reference the node so it won't be torn down
2649 lCount = AFSObjectInfoIncrement( pNextObject,
2650 AFS_OBJECT_REFERENCE_INVALIDATION);
2652 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2653 AFS_TRACE_LEVEL_VERBOSE,
2654 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2659 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2661 AFSInvalidateObject( &pCurrentObject,
2664 if ( pCurrentObject )
2667 lCount = AFSObjectInfoDecrement( pCurrentObject,
2668 AFS_OBJECT_REFERENCE_INVALIDATION);
2670 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2671 AFS_TRACE_LEVEL_VERBOSE,
2672 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2677 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2680 pCurrentObject = pNextObject;
2683 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2690 AFSInvalidateAllVolumes( VOID)
2692 AFSVolumeCB *pVolumeCB = NULL;
2693 AFSVolumeCB *pNextVolumeCB = NULL;
2694 AFSDeviceExt *pRDRDeviceExt = NULL;
2697 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2699 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2700 AFS_TRACE_LEVEL_VERBOSE,
2701 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2702 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2703 PsGetCurrentThread());
2705 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2708 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2713 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2714 AFS_TRACE_LEVEL_VERBOSE,
2715 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2716 pVolumeCB->ObjectInfoTree.TreeLock,
2717 PsGetCurrentThread());
2719 lCount = AFSVolumeIncrement( pVolumeCB,
2720 AFS_VOLUME_REFERENCE_INVALIDATE);
2722 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2723 AFS_TRACE_LEVEL_VERBOSE,
2724 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2729 while( pVolumeCB != NULL)
2732 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2737 lCount = AFSVolumeIncrement( pNextVolumeCB,
2738 AFS_VOLUME_REFERENCE_INVALIDATE);
2740 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2741 AFS_TRACE_LEVEL_VERBOSE,
2742 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2747 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2749 // do I need to hold the volume lock here?
2751 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2753 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2756 lCount = AFSVolumeDecrement( pVolumeCB,
2757 AFS_VOLUME_REFERENCE_INVALIDATE);
2759 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2760 AFS_TRACE_LEVEL_VERBOSE,
2761 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2765 pVolumeCB = pNextVolumeCB;
2768 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2772 AFSVerifyEntry( IN GUID *AuthGroup,
2773 IN AFSDirectoryCB *DirEntry)
2776 NTSTATUS ntStatus = STATUS_SUCCESS;
2777 AFSDirEnumEntry *pDirEnumEntry = NULL;
2778 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2779 IO_STATUS_BLOCK stIoStatus;
2784 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2785 AFS_TRACE_LEVEL_VERBOSE_2,
2786 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2787 &DirEntry->NameInformation.FileName,
2788 pObjectInfo->FileId.Cell,
2789 pObjectInfo->FileId.Volume,
2790 pObjectInfo->FileId.Vnode,
2791 pObjectInfo->FileId.Unique);
2793 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2798 if( !NT_SUCCESS( ntStatus))
2801 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2802 AFS_TRACE_LEVEL_ERROR,
2803 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2804 &DirEntry->NameInformation.FileName,
2805 pObjectInfo->FileId.Cell,
2806 pObjectInfo->FileId.Volume,
2807 pObjectInfo->FileId.Vnode,
2808 pObjectInfo->FileId.Unique,
2811 try_return( ntStatus);
2815 // Check the data version of the file
2818 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2820 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2823 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2824 AFS_TRACE_LEVEL_VERBOSE,
2825 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2826 pObjectInfo->DataVersion.QuadPart,
2827 &DirEntry->NameInformation.FileName,
2828 pObjectInfo->FileId.Cell,
2829 pObjectInfo->FileId.Volume,
2830 pObjectInfo->FileId.Vnode,
2831 pObjectInfo->FileId.Unique);
2834 // We are ok, just get out
2837 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2839 try_return( ntStatus = STATUS_SUCCESS);
2844 // New data version so we will need to process the node based on the type
2847 switch( pDirEnumEntry->FileType)
2850 case AFS_FILE_TYPE_MOUNTPOINT:
2854 // For a mount point we need to ensure the target is the same
2857 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2858 &pDirEnumEntry->TargetFileId))
2864 // Update the metadata for the entry
2867 ntStatus = AFSUpdateMetaData( DirEntry,
2870 if( NT_SUCCESS( ntStatus))
2873 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2879 case AFS_FILE_TYPE_SYMLINK:
2883 // Update the metadata for the entry
2886 ntStatus = AFSUpdateMetaData( DirEntry,
2889 if( NT_SUCCESS( ntStatus))
2892 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2898 case AFS_FILE_TYPE_FILE:
2900 FILE_OBJECT * pCCFileObject = NULL;
2901 BOOLEAN bPurgeExtents = FALSE;
2903 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
2906 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2907 AFS_TRACE_LEVEL_VERBOSE,
2908 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
2909 &DirEntry->NameInformation.FileName,
2910 pObjectInfo->FileId.Cell,
2911 pObjectInfo->FileId.Volume,
2912 pObjectInfo->FileId.Vnode,
2913 pObjectInfo->FileId.Unique,
2914 pObjectInfo->DataVersion.LowPart,
2915 pDirEnumEntry->DataVersion.LowPart
2918 bPurgeExtents = TRUE;
2921 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2924 bPurgeExtents = TRUE;
2926 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2927 AFS_TRACE_LEVEL_VERBOSE,
2928 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2929 &DirEntry->NameInformation.FileName,
2930 pObjectInfo->FileId.Cell,
2931 pObjectInfo->FileId.Volume,
2932 pObjectInfo->FileId.Vnode,
2933 pObjectInfo->FileId.Unique);
2935 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2938 if( pObjectInfo->Fcb != NULL)
2941 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2942 AFS_TRACE_LEVEL_VERBOSE,
2943 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2944 &DirEntry->NameInformation.FileName,
2945 pObjectInfo->FileId.Cell,
2946 pObjectInfo->FileId.Volume,
2947 pObjectInfo->FileId.Vnode,
2948 pObjectInfo->FileId.Unique);
2950 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2956 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2961 if( !NT_SUCCESS( stIoStatus.Status))
2964 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2965 AFS_TRACE_LEVEL_ERROR,
2966 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2967 &DirEntry->NameInformation.FileName,
2968 pObjectInfo->FileId.Cell,
2969 pObjectInfo->FileId.Volume,
2970 pObjectInfo->FileId.Vnode,
2971 pObjectInfo->FileId.Unique,
2973 stIoStatus.Information);
2975 ntStatus = stIoStatus.Status;
2978 if ( bPurgeExtents &&
2979 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2982 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2988 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2989 AFS_TRACE_LEVEL_WARNING,
2990 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2991 &DirEntry->NameInformation.FileName,
2992 pObjectInfo->FileId.Cell,
2993 pObjectInfo->FileId.Volume,
2994 pObjectInfo->FileId.Vnode,
2995 pObjectInfo->FileId.Unique);
2997 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3001 __except( EXCEPTION_EXECUTE_HANDLER)
3003 ntStatus = GetExceptionCode();
3007 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3008 &DirEntry->NameInformation.FileName,
3009 pObjectInfo->FileId.Cell,
3010 pObjectInfo->FileId.Volume,
3011 pObjectInfo->FileId.Vnode,
3012 pObjectInfo->FileId.Unique,
3015 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3018 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3022 AFSFlushExtents( pObjectInfo->Fcb,
3027 // Reacquire the Fcb to purge the cache
3030 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3031 AFS_TRACE_LEVEL_VERBOSE,
3032 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3033 &pObjectInfo->Fcb->NPFcb->Resource,
3034 PsGetCurrentThread());
3036 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3040 // Update the metadata for the entry
3043 ntStatus = AFSUpdateMetaData( DirEntry,
3046 if( !NT_SUCCESS( ntStatus))
3049 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3050 AFS_TRACE_LEVEL_ERROR,
3051 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3052 &DirEntry->NameInformation.FileName,
3053 pObjectInfo->FileId.Cell,
3054 pObjectInfo->FileId.Volume,
3055 pObjectInfo->FileId.Vnode,
3056 pObjectInfo->FileId.Unique,
3063 // Update file sizes
3066 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3067 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3068 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3070 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3071 AFS_TRACE_LEVEL_VERBOSE,
3072 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3073 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3074 PsGetCurrentThread());
3076 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3079 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3081 if ( pCCFileObject != NULL)
3083 CcSetFileSizes( pCCFileObject,
3084 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3087 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3088 AFS_TRACE_LEVEL_VERBOSE,
3089 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3090 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3091 PsGetCurrentThread());
3093 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3095 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3101 // Update the metadata for the entry
3104 ntStatus = AFSUpdateMetaData( DirEntry,
3107 if( !NT_SUCCESS( ntStatus))
3110 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3111 AFS_TRACE_LEVEL_ERROR,
3112 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3113 &DirEntry->NameInformation.FileName,
3114 pObjectInfo->FileId.Cell,
3115 pObjectInfo->FileId.Volume,
3116 pObjectInfo->FileId.Vnode,
3117 pObjectInfo->FileId.Unique,
3123 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3124 AFS_TRACE_LEVEL_WARNING,
3125 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3126 &DirEntry->NameInformation.FileName,
3127 pObjectInfo->FileId.Cell,
3128 pObjectInfo->FileId.Volume,
3129 pObjectInfo->FileId.Vnode,
3130 pObjectInfo->FileId.Unique);
3133 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3138 case AFS_FILE_TYPE_DIRECTORY:
3142 // For a directory or root entry flush the content of
3143 // the directory enumeration.
3146 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3149 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3150 AFS_TRACE_LEVEL_VERBOSE_2,
3151 "AFSVerifyEntry Validating directory content for entry %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);
3158 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3161 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3164 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3166 if ( !NT_SUCCESS( ntStatus))
3169 try_return( ntStatus);
3174 // Update the metadata for the entry
3177 ntStatus = AFSUpdateMetaData( DirEntry,
3180 if( NT_SUCCESS( ntStatus))
3183 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3189 case AFS_FILE_TYPE_DFSLINK:
3192 UNICODE_STRING uniTargetName;
3195 // For a DFS link need to check the target name has not changed
3198 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3200 uniTargetName.MaximumLength = uniTargetName.Length;
3202 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3204 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3207 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3208 RtlCompareUnicodeString( &uniTargetName,
3209 &DirEntry->NameInformation.TargetName,
3214 // Update the target name
3217 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3219 uniTargetName.Buffer,
3220 uniTargetName.Length);
3222 if( !NT_SUCCESS( ntStatus))
3225 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3231 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3234 // Update the metadata for the entry
3237 ntStatus = AFSUpdateMetaData( DirEntry,
3240 if( NT_SUCCESS( ntStatus))
3243 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3251 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3252 AFS_TRACE_LEVEL_WARNING,
3253 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3254 pObjectInfo->FileType,
3255 &DirEntry->NameInformation.FileName,
3256 pObjectInfo->FileId.Cell,
3257 pObjectInfo->FileId.Volume,
3258 pObjectInfo->FileId.Vnode,
3259 pObjectInfo->FileId.Unique);
3266 if( pDirEnumEntry != NULL)
3269 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3277 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3280 NTSTATUS ntStatus = STATUS_SUCCESS;
3281 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3282 ULONGLONG ullIndex = 0;
3283 AFSVolumeCB *pVolumeCB = NULL;
3289 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3290 AFS_TRACE_LEVEL_VERBOSE,
3291 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3292 VolumeStatus->Online,
3293 VolumeStatus->FileID.Cell,
3294 VolumeStatus->FileID.Volume);
3297 // Need to locate the Fcb for the directory to purge
3300 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3301 AFS_TRACE_LEVEL_VERBOSE,
3302 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3303 &pDevExt->Specific.RDR.VolumeTreeLock,
3304 PsGetCurrentThread());
3306 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3309 // Locate the volume node
3312 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3314 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3316 (AFSBTreeEntry **)&pVolumeCB);
3318 if( pVolumeCB != NULL)
3321 lCount = AFSVolumeIncrement( pVolumeCB,
3322 AFS_VOLUME_REFERENCE_INVALIDATE);
3324 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3325 AFS_TRACE_LEVEL_VERBOSE,
3326 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3330 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3333 // Set the volume state accordingly
3336 if( VolumeStatus->Online)
3339 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3344 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3353 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3356 NTSTATUS ntStatus = STATUS_SUCCESS;
3361 if( AFSGlobalRoot == NULL)
3364 try_return( ntStatus);
3367 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3371 // Set the network state according to the information
3374 if( NetworkStatus->Online)
3377 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3382 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3385 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3396 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3400 NTSTATUS ntStatus = STATUS_SUCCESS;
3401 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3402 BOOLEAN bAcquiredLock = FALSE;
3403 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3408 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3409 AFS_TRACE_LEVEL_VERBOSE,
3410 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3411 ObjectInfo->FileId.Cell,
3412 ObjectInfo->FileId.Volume,
3413 ObjectInfo->FileId.Vnode,
3414 ObjectInfo->FileId.Unique);
3416 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3419 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3420 AFS_TRACE_LEVEL_VERBOSE,
3421 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3422 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3423 PsGetCurrentThread());
3425 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3428 bAcquiredLock = TRUE;
3432 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3435 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3436 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3439 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3440 AFS_TRACE_LEVEL_ERROR,
3441 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3442 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3443 ObjectInfo->FileId.Cell,
3444 ObjectInfo->FileId.Volume,
3445 ObjectInfo->FileId.Vnode,
3446 ObjectInfo->FileId.Unique);
3450 // Reset the directory list information by clearing all valid entries
3453 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3455 while( pCurrentDirEntry != NULL)
3458 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3460 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3464 // If this entry has been deleted then process it here
3467 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3468 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3469 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3472 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3473 AFS_TRACE_LEVEL_VERBOSE,
3474 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3476 &pCurrentDirEntry->NameInformation.FileName);
3478 AFSDeleteDirEntry( ObjectInfo,
3484 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3486 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3487 AFS_TRACE_LEVEL_VERBOSE,
3488 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3490 pCurrentDirEntry->DirOpenReferenceCount);
3493 // We pull the short name from the parent tree since it could change below
3496 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3499 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3500 AFS_TRACE_LEVEL_VERBOSE,
3501 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3503 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3504 &pCurrentDirEntry->NameInformation.FileName);
3506 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3509 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3514 pCurrentDirEntry = pNextDirEntry;
3518 // Reget the directory contents
3521 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3524 if ( !NT_SUCCESS( ntStatus))
3526 try_return( ntStatus);
3530 // Now start again and tear down any entries not valid
3533 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3535 while( pCurrentDirEntry != NULL)
3538 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3540 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3543 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3544 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3545 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3548 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3551 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3553 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3554 AFS_TRACE_LEVEL_VERBOSE,
3555 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3557 &pCurrentDirEntry->NameInformation.FileName);
3559 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3564 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3567 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3568 AFS_TRACE_LEVEL_VERBOSE,
3569 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3571 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3572 &pCurrentDirEntry->NameInformation.FileName);
3576 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3578 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3579 AFS_TRACE_LEVEL_VERBOSE,
3580 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3582 &pCurrentDirEntry->NameInformation.FileName);
3587 pCurrentDirEntry = pNextDirEntry;
3592 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3593 AFS_TRACE_LEVEL_VERBOSE,
3594 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3596 pCurrentDirEntry->DirOpenReferenceCount);
3598 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3599 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3602 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3603 AFS_TRACE_LEVEL_VERBOSE,
3604 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3605 &pCurrentDirEntry->NameInformation.FileName,
3606 ObjectInfo->FileId.Cell,
3607 ObjectInfo->FileId.Volume,
3608 ObjectInfo->FileId.Vnode,
3609 ObjectInfo->FileId.Unique);
3611 AFSDeleteDirEntry( ObjectInfo,
3617 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3618 AFS_TRACE_LEVEL_VERBOSE,
3619 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3621 &pCurrentDirEntry->NameInformation.FileName,
3622 ObjectInfo->FileId.Cell,
3623 ObjectInfo->FileId.Volume,
3624 ObjectInfo->FileId.Vnode,
3625 ObjectInfo->FileId.Unique);
3627 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3629 AFSRemoveNameEntry( ObjectInfo,
3633 pCurrentDirEntry = pNextDirEntry;
3637 if( !AFSValidateDirList( ObjectInfo))
3640 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3649 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3657 AFSIsVolumeFID( IN AFSFileID *FileID)
3660 BOOLEAN bIsVolume = FALSE;
3662 if( FileID->Vnode == 1 &&
3663 FileID->Unique == 1)
3673 AFSIsFinalNode( IN AFSFcb *Fcb)
3676 BOOLEAN bIsFinalNode = FALSE;
3678 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3679 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3680 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3681 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3682 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3685 bIsFinalNode = TRUE;
3690 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3691 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3694 return bIsFinalNode;
3698 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3699 IN AFSDirEnumEntry *DirEnumEntry)
3702 NTSTATUS ntStatus = STATUS_SUCCESS;
3703 UNICODE_STRING uniTargetName;
3704 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3709 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3711 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3713 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3715 pObjectInfo->FileType = DirEnumEntry->FileType;
3717 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3719 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3721 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3723 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3725 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3727 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3729 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3731 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3734 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3737 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3738 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3741 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3744 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3746 pObjectInfo->Links = DirEnumEntry->Links;
3748 if( DirEnumEntry->TargetNameLength > 0 &&
3749 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3750 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3754 // Update the target name information if needed
3757 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3759 uniTargetName.MaximumLength = uniTargetName.Length;
3761 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3763 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3766 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3767 RtlCompareUnicodeString( &uniTargetName,
3768 &DirEntry->NameInformation.TargetName,
3773 // Update the target name
3776 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3778 uniTargetName.Buffer,
3779 uniTargetName.Length);
3781 if( !NT_SUCCESS( ntStatus))
3784 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3786 try_return( ntStatus);
3790 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3792 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3793 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3796 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3799 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3800 DirEntry->NameInformation.TargetName.Buffer != NULL)
3802 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3805 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3807 DirEntry->NameInformation.TargetName.Length = 0;
3808 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3809 DirEntry->NameInformation.TargetName.Buffer = NULL;
3811 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3823 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3825 IN BOOLEAN FastCall,
3826 IN BOOLEAN bSafeToPurge)
3829 NTSTATUS ntStatus = STATUS_SUCCESS;
3830 LARGE_INTEGER liSystemTime;
3831 AFSDirEnumEntry *pDirEnumEntry = NULL;
3832 AFSFcb *pCurrentFcb = NULL;
3833 BOOLEAN bReleaseFcb = FALSE;
3834 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3840 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3844 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3845 AFS_TRACE_LEVEL_VERBOSE_2,
3846 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3847 &DirEntry->NameInformation.FileName,
3848 pObjectInfo->FileId.Cell,
3849 pObjectInfo->FileId.Volume,
3850 pObjectInfo->FileId.Vnode,
3851 pObjectInfo->FileId.Unique,
3855 // If this is a fake node then bail since the service knows nothing about it
3858 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3861 try_return( ntStatus);
3865 // This routine ensures that the current entry is valid by:
3867 // 1) Checking that the expiration time is non-zero and after where we
3871 KeQuerySystemTime( &liSystemTime);
3873 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3874 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3875 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3876 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3879 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3880 AFS_TRACE_LEVEL_VERBOSE_2,
3881 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3882 &DirEntry->NameInformation.FileName,
3883 pObjectInfo->FileId.Cell,
3884 pObjectInfo->FileId.Volume,
3885 pObjectInfo->FileId.Vnode,
3886 pObjectInfo->FileId.Unique);
3888 try_return( ntStatus);
3892 // This node requires updating
3895 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3900 if( !NT_SUCCESS( ntStatus))
3903 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3904 AFS_TRACE_LEVEL_ERROR,
3905 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3907 &DirEntry->NameInformation.FileName,
3908 pObjectInfo->FileId.Cell,
3909 pObjectInfo->FileId.Volume,
3910 pObjectInfo->FileId.Vnode,
3911 pObjectInfo->FileId.Unique,
3915 // Failed validation of node so return access-denied
3918 try_return( ntStatus);
3921 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3922 AFS_TRACE_LEVEL_VERBOSE,
3923 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3925 &DirEntry->NameInformation.FileName,
3926 pObjectInfo->FileId.Cell,
3927 pObjectInfo->FileId.Volume,
3928 pObjectInfo->FileId.Vnode,
3929 pObjectInfo->FileId.Unique,
3930 pObjectInfo->DataVersion.QuadPart,
3931 pDirEnumEntry->DataVersion.QuadPart,
3932 pDirEnumEntry->FileType);
3936 // Based on the file type, process the node
3939 switch( pDirEnumEntry->FileType)
3942 case AFS_FILE_TYPE_MOUNTPOINT:
3946 // Update the metadata for the entry
3949 ntStatus = AFSUpdateMetaData( DirEntry,
3952 if( NT_SUCCESS( ntStatus))
3955 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3961 case AFS_FILE_TYPE_SYMLINK:
3962 case AFS_FILE_TYPE_DFSLINK:
3966 // Update the metadata for the entry
3969 ntStatus = AFSUpdateMetaData( DirEntry,
3972 if( NT_SUCCESS( ntStatus))
3975 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3981 case AFS_FILE_TYPE_FILE:
3984 BOOLEAN bPurgeExtents = FALSE;
3987 // For a file where the data version has become invalid we need to
3988 // fail any current extent requests and purge the cache for the file
3989 // Can't hold the Fcb resource while doing this
3992 if( pObjectInfo->Fcb != NULL &&
3993 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3994 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3997 pCurrentFcb = pObjectInfo->Fcb;
3999 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4002 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4003 AFS_TRACE_LEVEL_VERBOSE,
4004 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4005 &pCurrentFcb->NPFcb->Resource,
4006 PsGetCurrentThread());
4008 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4014 if( pCurrentFcb != NULL)
4017 IO_STATUS_BLOCK stIoStatus;
4019 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4020 AFS_TRACE_LEVEL_VERBOSE_2,
4021 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4022 &DirEntry->NameInformation.FileName,
4023 pObjectInfo->FileId.Cell,
4024 pObjectInfo->FileId.Volume,
4025 pObjectInfo->FileId.Vnode,
4026 pObjectInfo->FileId.Unique);
4028 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4031 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4032 AFS_TRACE_LEVEL_VERBOSE,
4033 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4034 &DirEntry->NameInformation.FileName,
4035 pObjectInfo->FileId.Cell,
4036 pObjectInfo->FileId.Volume,
4037 pObjectInfo->FileId.Vnode,
4038 pObjectInfo->FileId.Unique,
4039 pObjectInfo->DataVersion.LowPart,
4040 pDirEnumEntry->DataVersion.LowPart
4043 bPurgeExtents = TRUE;
4049 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4051 bPurgeExtents = TRUE;
4053 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4054 AFS_TRACE_LEVEL_VERBOSE,
4055 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4056 &DirEntry->NameInformation.FileName,
4057 pObjectInfo->FileId.Cell,
4058 pObjectInfo->FileId.Volume,
4059 pObjectInfo->FileId.Vnode,
4060 pObjectInfo->FileId.Unique);
4062 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4065 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4066 AFS_TRACE_LEVEL_VERBOSE,
4067 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4068 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4069 PsGetCurrentThread());
4071 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4075 // Release Fcb->Resource to avoid Trend Micro deadlock
4078 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
4083 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4088 if( !NT_SUCCESS( stIoStatus.Status))
4091 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4092 AFS_TRACE_LEVEL_ERROR,
4093 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4094 &DirEntry->NameInformation.FileName,
4095 pObjectInfo->FileId.Cell,
4096 pObjectInfo->FileId.Volume,
4097 pObjectInfo->FileId.Vnode,
4098 pObjectInfo->FileId.Unique,
4100 stIoStatus.Information);
4102 ntStatus = stIoStatus.Status;
4105 if ( bPurgeExtents &&
4106 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4109 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4115 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4116 AFS_TRACE_LEVEL_WARNING,
4117 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4118 &DirEntry->NameInformation.FileName,
4119 pObjectInfo->FileId.Cell,
4120 pObjectInfo->FileId.Volume,
4121 pObjectInfo->FileId.Vnode,
4122 pObjectInfo->FileId.Unique);
4124 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4128 __except( EXCEPTION_EXECUTE_HANDLER)
4130 ntStatus = GetExceptionCode();
4134 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4135 &DirEntry->NameInformation.FileName,
4136 pObjectInfo->FileId.Cell,
4137 pObjectInfo->FileId.Volume,
4138 pObjectInfo->FileId.Vnode,
4139 pObjectInfo->FileId.Unique,
4142 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4145 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4146 AFS_TRACE_LEVEL_VERBOSE,
4147 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4148 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4149 PsGetCurrentThread());
4151 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4153 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4162 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4167 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4169 bReleaseFcb = FALSE;
4171 if ( bPurgeExtents &&
4174 AFSFlushExtents( pCurrentFcb,
4181 // Update the metadata for the entry but only if it is safe to do so.
4182 // If it was determined that a data version change has occurred or
4183 // that a pending data verification was required, do not update the
4184 // ObjectInfo meta data or the FileObject size information. That
4185 // way it is consistent for the next time that the data is verified
4189 if ( !(bPurgeExtents && bSafeToPurge))
4192 ntStatus = AFSUpdateMetaData( DirEntry,
4195 if( !NT_SUCCESS( ntStatus))
4198 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4199 AFS_TRACE_LEVEL_ERROR,
4200 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4201 &DirEntry->NameInformation.FileName,
4202 pObjectInfo->FileId.Cell,
4203 pObjectInfo->FileId.Volume,
4204 pObjectInfo->FileId.Vnode,
4205 pObjectInfo->FileId.Unique,
4211 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4214 // Update file sizes
4217 if( pObjectInfo->Fcb != NULL)
4219 FILE_OBJECT *pCCFileObject;
4221 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4222 AFS_TRACE_LEVEL_VERBOSE,
4223 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4224 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4225 PsGetCurrentThread());
4227 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4230 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4232 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4233 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4234 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4236 if ( pCCFileObject != NULL)
4238 CcSetFileSizes( pCCFileObject,
4239 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4242 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4243 AFS_TRACE_LEVEL_VERBOSE,
4244 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4245 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4246 PsGetCurrentThread());
4248 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4254 case AFS_FILE_TYPE_DIRECTORY:
4257 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4261 // For a directory or root entry flush the content of
4262 // the directory enumeration.
4265 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4266 AFS_TRACE_LEVEL_VERBOSE,
4267 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4268 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4269 PsGetCurrentThread());
4271 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4274 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4275 AFS_TRACE_LEVEL_VERBOSE_2,
4276 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4277 &DirEntry->NameInformation.FileName,
4278 pObjectInfo->FileId.Cell,
4279 pObjectInfo->FileId.Volume,
4280 pObjectInfo->FileId.Vnode,
4281 pObjectInfo->FileId.Unique);
4283 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4286 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4289 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4292 if( !NT_SUCCESS( ntStatus))
4295 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4296 AFS_TRACE_LEVEL_ERROR,
4297 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4298 &DirEntry->NameInformation.FileName,
4299 pObjectInfo->FileId.Cell,
4300 pObjectInfo->FileId.Volume,
4301 pObjectInfo->FileId.Vnode,
4302 pObjectInfo->FileId.Unique,
4310 // Update the metadata for the entry
4313 ntStatus = AFSUpdateMetaData( DirEntry,
4316 if( NT_SUCCESS( ntStatus))
4319 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4327 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4328 AFS_TRACE_LEVEL_WARNING,
4329 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4330 pObjectInfo->FileType,
4332 &DirEntry->NameInformation.FileName,
4333 pObjectInfo->FileId.Cell,
4334 pObjectInfo->FileId.Volume,
4335 pObjectInfo->FileId.Vnode,
4336 pObjectInfo->FileId.Unique);
4346 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4349 if( pDirEnumEntry != NULL)
4352 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4360 AFSInitializeSpecialShareNameList()
4363 NTSTATUS ntStatus = STATUS_SUCCESS;
4364 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4365 AFSObjectInfoCB *pObjectInfoCB = NULL;
4366 UNICODE_STRING uniShareName;
4367 ULONG ulEntryLength = 0;
4368 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4374 RtlInitUnicodeString( &uniShareName,
4377 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4380 if( pObjectInfoCB == NULL)
4383 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4386 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4387 AFS_OBJECT_REFERENCE_GLOBAL);
4389 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4390 AFS_TRACE_LEVEL_VERBOSE,
4391 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4395 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4397 ulEntryLength = sizeof( AFSDirectoryCB) +
4398 uniShareName.Length;
4400 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4404 if( pDirNode == NULL)
4407 AFSDeleteObjectInfo( &pObjectInfoCB);
4409 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4412 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4413 AFS_TRACE_LEVEL_VERBOSE,
4414 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4417 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4418 sizeof( AFSNonPagedDirectoryCB),
4419 AFS_DIR_ENTRY_NP_TAG);
4421 if( pNonPagedDirEntry == NULL)
4424 ExFreePool( pDirNode);
4426 AFSDeleteObjectInfo( &pObjectInfoCB);
4428 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4431 RtlZeroMemory( pDirNode,
4434 RtlZeroMemory( pNonPagedDirEntry,
4435 sizeof( AFSNonPagedDirectoryCB));
4437 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4439 pDirNode->NonPaged = pNonPagedDirEntry;
4441 pDirNode->ObjectInformation = pObjectInfoCB;
4447 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4449 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4451 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4453 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4455 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4456 uniShareName.Buffer,
4457 pDirNode->NameInformation.FileName.Length);
4459 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4462 AFSSpecialShareNames = pDirNode;
4464 pLastDirNode = pDirNode;
4467 RtlInitUnicodeString( &uniShareName,
4470 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4473 if( pObjectInfoCB == NULL)
4476 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4479 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4480 AFS_OBJECT_REFERENCE_GLOBAL);
4482 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4483 AFS_TRACE_LEVEL_VERBOSE,
4484 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4488 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4490 ulEntryLength = sizeof( AFSDirectoryCB) +
4491 uniShareName.Length;
4493 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4497 if( pDirNode == NULL)
4500 AFSDeleteObjectInfo( &pObjectInfoCB);
4502 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4505 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4506 AFS_TRACE_LEVEL_VERBOSE,
4507 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4510 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4511 sizeof( AFSNonPagedDirectoryCB),
4512 AFS_DIR_ENTRY_NP_TAG);
4514 if( pNonPagedDirEntry == NULL)
4517 ExFreePool( pDirNode);
4519 AFSDeleteObjectInfo( &pObjectInfoCB);
4521 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4524 RtlZeroMemory( pDirNode,
4527 RtlZeroMemory( pNonPagedDirEntry,
4528 sizeof( AFSNonPagedDirectoryCB));
4530 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4532 pDirNode->NonPaged = pNonPagedDirEntry;
4534 pDirNode->ObjectInformation = pObjectInfoCB;
4540 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4542 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4544 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4546 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4548 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4549 uniShareName.Buffer,
4550 pDirNode->NameInformation.FileName.Length);
4552 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4555 pLastDirNode->ListEntry.fLink = pDirNode;
4557 pDirNode->ListEntry.bLink = pLastDirNode;
4561 if( !NT_SUCCESS( ntStatus))
4564 if( AFSSpecialShareNames != NULL)
4567 pDirNode = AFSSpecialShareNames;
4569 while( pDirNode != NULL)
4572 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4574 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4576 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4578 ExFreePool( pDirNode->NonPaged);
4580 ExFreePool( pDirNode);
4582 pDirNode = pLastDirNode;
4585 AFSSpecialShareNames = NULL;
4594 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4595 IN UNICODE_STRING *SecondaryName)
4598 AFSDirectoryCB *pDirectoryCB = NULL;
4599 ULONGLONG ullHash = 0;
4600 UNICODE_STRING uniFullShareName;
4606 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4607 AFS_TRACE_LEVEL_VERBOSE_2,
4608 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4612 uniFullShareName = *ShareName;
4615 // Generate our hash value
4618 ullHash = AFSGenerateCRC( &uniFullShareName,
4622 // Loop through our special share names to see if this is one of them
4625 pDirectoryCB = AFSSpecialShareNames;
4627 while( pDirectoryCB != NULL)
4630 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4636 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4640 return pDirectoryCB;
4644 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4648 // Block on the queue flush event
4651 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4661 AFSWaitOnQueuedReleases()
4664 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4667 // Block on the queue flush event
4670 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4680 AFSIsEqualFID( IN AFSFileID *FileId1,
4681 IN AFSFileID *FileId2)
4684 BOOLEAN bIsEqual = FALSE;
4686 if( FileId1->Hash == FileId2->Hash &&
4687 FileId1->Unique == FileId2->Unique &&
4688 FileId1->Vnode == FileId2->Vnode &&
4689 FileId1->Volume == FileId2->Volume &&
4690 FileId1->Cell == FileId2->Cell)
4700 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4703 NTSTATUS ntStatus = STATUS_SUCCESS;
4704 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4709 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4712 // Reset the directory list information
4715 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4717 while( pCurrentDirEntry != NULL)
4720 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4722 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
4723 pCurrentDirEntry->NameArrayReferenceCount <= 0)
4726 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4727 AFS_TRACE_LEVEL_VERBOSE,
4728 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4730 &pCurrentDirEntry->NameInformation.FileName);
4732 AFSDeleteDirEntry( ObjectInfoCB,
4738 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4739 AFS_TRACE_LEVEL_VERBOSE,
4740 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4742 &pCurrentDirEntry->NameInformation.FileName);
4744 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4746 AFSRemoveNameEntry( ObjectInfoCB,
4750 pCurrentDirEntry = pNextDirEntry;
4753 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4755 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4757 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4759 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4761 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4763 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4765 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4766 AFS_TRACE_LEVEL_VERBOSE,
4767 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4768 ObjectInfoCB->FileId.Cell,
4769 ObjectInfoCB->FileId.Volume,
4770 ObjectInfoCB->FileId.Vnode,
4771 ObjectInfoCB->FileId.Unique);
4778 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4781 NTSTATUS ntStatus = STATUS_SUCCESS;
4782 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4783 UNICODE_STRING uniFullName;
4788 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4789 AFS_TRACE_LEVEL_VERBOSE,
4790 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4791 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4792 PsGetCurrentThread());
4794 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4797 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4800 try_return( ntStatus);
4804 // Initialize the root information
4807 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4810 // Enumerate the shares in the volume
4813 ntStatus = AFSEnumerateDirectory( AuthGroup,
4814 &AFSGlobalRoot->ObjectInformation,
4817 if( !NT_SUCCESS( ntStatus))
4820 try_return( ntStatus);
4823 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4825 uniFullName.MaximumLength = PAGE_SIZE;
4826 uniFullName.Length = 0;
4828 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4829 uniFullName.MaximumLength,
4830 AFS_GENERIC_MEMORY_12_TAG);
4832 if( uniFullName.Buffer == NULL)
4836 // Reset the directory content
4839 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4841 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4843 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4847 // Populate our list of entries in the NP enumeration list
4850 while( pDirGlobalDirNode != NULL)
4853 uniFullName.Buffer[ 0] = L'\\';
4854 uniFullName.Buffer[ 1] = L'\\';
4856 uniFullName.Length = 2 * sizeof( WCHAR);
4858 RtlCopyMemory( &uniFullName.Buffer[ 2],
4859 AFSServerName.Buffer,
4860 AFSServerName.Length);
4862 uniFullName.Length += AFSServerName.Length;
4864 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4866 uniFullName.Length += sizeof( WCHAR);
4868 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4869 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4870 pDirGlobalDirNode->NameInformation.FileName.Length);
4872 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4874 AFSAddConnectionEx( &uniFullName,
4875 RESOURCEDISPLAYTYPE_SHARE,
4878 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4881 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
4885 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4892 AFSIsRelativeName( IN UNICODE_STRING *Name)
4895 BOOLEAN bIsRelative = FALSE;
4897 if( Name->Length > 0 &&
4898 Name->Buffer[ 0] != L'\\')
4908 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
4910 UNICODE_STRING uniTempName;
4911 BOOLEAN bIsAbsolute = FALSE;
4914 // An absolute AFS path must begin with \afs\... or equivalent
4917 if ( Name->Length == 0 ||
4918 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
4919 Name->Buffer[ 0] != L'\\' ||
4920 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
4926 uniTempName.Length = AFSMountRootName.Length;
4927 uniTempName.MaximumLength = AFSMountRootName.Length;
4929 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4930 uniTempName.MaximumLength,
4931 AFS_NAME_BUFFER_TWO_TAG);
4933 if( uniTempName.Buffer == NULL)
4939 RtlCopyMemory( uniTempName.Buffer,
4941 AFSMountRootName.Length);
4943 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
4947 AFSExFreePoolWithTag( uniTempName.Buffer,
4948 AFS_NAME_BUFFER_TWO_TAG);
4955 AFSUpdateName( IN UNICODE_STRING *Name)
4960 while( usIndex < Name->Length/sizeof( WCHAR))
4963 if( Name->Buffer[ usIndex] == L'/')
4966 Name->Buffer[ usIndex] = L'\\';
4976 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4977 IN OUT ULONG *Flags,
4978 IN WCHAR *NameBuffer,
4979 IN USHORT NameLength)
4982 NTSTATUS ntStatus = STATUS_SUCCESS;
4983 WCHAR *pTmpBuffer = NULL;
4989 // If we have enough space then just move in the name otherwise
4990 // allocate a new buffer
4993 if( TargetName->Length < NameLength)
4996 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4998 AFS_NAME_BUFFER_FIVE_TAG);
5000 if( pTmpBuffer == NULL)
5003 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5006 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5009 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5012 TargetName->MaximumLength = NameLength;
5014 TargetName->Buffer = pTmpBuffer;
5016 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5019 TargetName->Length = NameLength;
5021 RtlCopyMemory( TargetName->Buffer,
5023 TargetName->Length);
5026 // Update the name in the buffer
5029 AFSUpdateName( TargetName);
5040 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
5041 IN ULONG InitialElementCount)
5044 AFSNameArrayHdr *pNameArray = NULL;
5045 AFSNameArrayCB *pCurrentElement = NULL;
5046 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5052 if( InitialElementCount == 0)
5055 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
5058 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
5059 sizeof( AFSNameArrayHdr) +
5060 (InitialElementCount * sizeof( AFSNameArrayCB)),
5061 AFS_NAME_ARRAY_TAG);
5063 if( pNameArray == NULL)
5066 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5067 AFS_TRACE_LEVEL_ERROR,
5068 "AFSInitNameArray Failed to allocate name array\n");
5070 try_return( pNameArray);
5073 RtlZeroMemory( pNameArray,
5074 sizeof( AFSNameArrayHdr) +
5075 (InitialElementCount * sizeof( AFSNameArrayCB)));
5077 pNameArray->MaxElementCount = InitialElementCount;
5079 if( DirectoryCB != NULL)
5082 pCurrentElement = &pNameArray->ElementArray[ 0];
5084 pNameArray->CurrentEntry = pCurrentElement;
5086 pNameArray->Count = 1;
5088 pNameArray->LinkCount = 0;
5090 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5092 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5093 AFS_TRACE_LEVEL_VERBOSE,
5094 "AFSInitNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5096 &DirectoryCB->NameInformation.FileName,
5100 pCurrentElement->DirectoryCB = DirectoryCB;
5102 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5104 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5106 if( pCurrentElement->FileId.Vnode == 1)
5109 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5112 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5113 AFS_TRACE_LEVEL_VERBOSE,
5114 "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5116 pCurrentElement->DirectoryCB,
5117 pCurrentElement->FileId.Cell,
5118 pCurrentElement->FileId.Volume,
5119 pCurrentElement->FileId.Vnode,
5120 pCurrentElement->FileId.Unique,
5121 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5122 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5134 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
5135 IN UNICODE_STRING *Path,
5136 IN AFSDirectoryCB *DirectoryCB)
5139 NTSTATUS ntStatus = STATUS_SUCCESS;
5140 AFSNameArrayCB *pCurrentElement = NULL;
5146 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5147 AFS_TRACE_LEVEL_VERBOSE,
5148 "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5152 DirectoryCB->ObjectInformation->FileId.Cell,
5153 DirectoryCB->ObjectInformation->FileId.Volume,
5154 DirectoryCB->ObjectInformation->FileId.Vnode,
5155 DirectoryCB->ObjectInformation->FileId.Unique,
5156 &DirectoryCB->NameInformation.FileName,
5157 DirectoryCB->ObjectInformation->FileType);
5160 // Init some info in the header
5163 pCurrentElement = &NameArray->ElementArray[ 0];
5165 NameArray->CurrentEntry = pCurrentElement;
5168 // The first entry points at the root
5171 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
5173 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5175 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5176 AFS_TRACE_LEVEL_VERBOSE,
5177 "AFSPopulateNameArray [NA:%p] Increment count on volume %wZ DE %p Cnt %d\n",
5179 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5180 pCurrentElement->DirectoryCB,
5183 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
5185 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
5187 pCurrentElement->Flags = 0;
5189 if( pCurrentElement->FileId.Vnode == 1)
5192 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5195 NameArray->Count = 1;
5197 NameArray->LinkCount = 0;
5199 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5200 AFS_TRACE_LEVEL_VERBOSE,
5201 "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5203 pCurrentElement->DirectoryCB,
5204 pCurrentElement->FileId.Cell,
5205 pCurrentElement->FileId.Volume,
5206 pCurrentElement->FileId.Vnode,
5207 pCurrentElement->FileId.Unique,
5208 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5209 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5212 // If the root is the parent then we are done ...
5215 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
5217 try_return( ntStatus);
5229 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
5230 IN AFSNameArrayHdr *RelatedNameArray,
5231 IN AFSDirectoryCB *DirectoryCB)
5234 NTSTATUS ntStatus = STATUS_SUCCESS;
5235 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
5244 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5245 AFS_TRACE_LEVEL_VERBOSE,
5246 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5250 DirectoryCB->ObjectInformation->FileId.Cell,
5251 DirectoryCB->ObjectInformation->FileId.Volume,
5252 DirectoryCB->ObjectInformation->FileId.Vnode,
5253 DirectoryCB->ObjectInformation->FileId.Unique,
5254 &DirectoryCB->NameInformation.FileName,
5255 DirectoryCB->ObjectInformation->FileType);
5260 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5261 AFS_TRACE_LEVEL_VERBOSE,
5262 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE NULL\n",
5268 // Init some info in the header
5271 pCurrentElement = &NameArray->ElementArray[ 0];
5273 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5275 NameArray->Count = 0;
5277 NameArray->LinkCount = RelatedNameArray->LinkCount;
5280 // Populate the name array with the data from the related array
5286 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5288 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5290 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5292 pCurrentElement->Flags = 0;
5294 if( pCurrentElement->FileId.Vnode == 1)
5297 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5300 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5302 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5303 AFS_TRACE_LEVEL_VERBOSE,
5304 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5306 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5307 pCurrentElement->DirectoryCB,
5310 lCount = InterlockedIncrement( &NameArray->Count);
5312 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5313 AFS_TRACE_LEVEL_VERBOSE,
5314 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5317 pCurrentElement->DirectoryCB,
5318 pCurrentElement->FileId.Cell,
5319 pCurrentElement->FileId.Volume,
5320 pCurrentElement->FileId.Vnode,
5321 pCurrentElement->FileId.Unique,
5322 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5323 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5325 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5326 NameArray->Count == RelatedNameArray->Count)
5338 pCurrentRelatedElement++;
5341 NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
5348 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5351 NTSTATUS ntStatus = STATUS_SUCCESS;
5352 AFSNameArrayCB *pCurrentElement = NULL;
5353 LONG lCount, lElement;
5358 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5359 AFS_TRACE_LEVEL_VERBOSE,
5360 "AFSFreeNameArray [NA:%p]\n",
5363 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5366 pCurrentElement = &NameArray->ElementArray[ lElement];
5368 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5370 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5371 AFS_TRACE_LEVEL_VERBOSE,
5372 "AFSFreeNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5374 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5375 pCurrentElement->DirectoryCB,
5378 ASSERT( lCount >= 0);
5381 AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
5388 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5389 IN AFSDirectoryCB *DirectoryCB)
5392 NTSTATUS ntStatus = STATUS_SUCCESS;
5393 AFSNameArrayCB *pCurrentElement = NULL;
5399 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5400 AFS_TRACE_LEVEL_VERBOSE,
5401 "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5404 DirectoryCB->ObjectInformation->FileId.Cell,
5405 DirectoryCB->ObjectInformation->FileId.Volume,
5406 DirectoryCB->ObjectInformation->FileId.Vnode,
5407 DirectoryCB->ObjectInformation->FileId.Unique,
5408 &DirectoryCB->NameInformation.FileName,
5409 DirectoryCB->ObjectInformation->FileType);
5411 if( NameArray->Count == (LONG) NameArray->MaxElementCount)
5414 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5415 AFS_TRACE_LEVEL_ERROR,
5416 "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
5419 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5422 for ( lCount = 0; lCount < NameArray->Count; lCount++)
5425 if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
5426 &DirectoryCB->ObjectInformation->FileId) )
5429 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5430 AFS_TRACE_LEVEL_WARNING,
5431 "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
5434 STATUS_ACCESS_DENIED);
5436 try_return( ntStatus = STATUS_ACCESS_DENIED);
5440 if( NameArray->Count > 0)
5443 NameArray->CurrentEntry++;
5447 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5450 pCurrentElement = NameArray->CurrentEntry;
5452 lCount = InterlockedIncrement( &NameArray->Count);
5454 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5456 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5457 AFS_TRACE_LEVEL_VERBOSE,
5458 "AFSInsertNextElement [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5460 &DirectoryCB->NameInformation.FileName,
5464 ASSERT( lCount > 0);
5466 pCurrentElement->DirectoryCB = DirectoryCB;
5468 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5470 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5472 pCurrentElement->Flags = 0;
5474 if( pCurrentElement->FileId.Vnode == 1)
5477 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5480 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5481 AFS_TRACE_LEVEL_VERBOSE,
5482 "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5484 NameArray->Count - 1,
5485 pCurrentElement->DirectoryCB,
5486 pCurrentElement->FileId.Cell,
5487 pCurrentElement->FileId.Volume,
5488 pCurrentElement->FileId.Vnode,
5489 pCurrentElement->FileId.Unique,
5490 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5491 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5502 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5505 AFSDirectoryCB *pDirectoryCB = NULL;
5506 AFSNameArrayCB *pCurrentElement = NULL;
5507 BOOLEAN bVolumeRoot = FALSE;
5513 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5514 AFS_TRACE_LEVEL_VERBOSE,
5515 "AFSBackupEntry [NA:%p]\n",
5518 if( NameArray->Count == 0)
5521 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5522 AFS_TRACE_LEVEL_ERROR,
5523 "AFSBackupEntry [NA:%p] No more entries\n",
5526 try_return( pCurrentElement);
5529 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->NameArrayReferenceCount);
5531 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5532 AFS_TRACE_LEVEL_VERBOSE,
5533 "AFSBackupEntry [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5535 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5536 NameArray->CurrentEntry->DirectoryCB,
5539 ASSERT( lCount >= 0);
5541 NameArray->CurrentEntry->DirectoryCB = NULL;
5543 lCount = InterlockedDecrement( &NameArray->Count);
5547 NameArray->CurrentEntry = NULL;
5549 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5550 AFS_TRACE_LEVEL_ERROR,
5551 "AFSBackupEntry [NA:%p] No more entries\n",
5557 bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5559 NameArray->CurrentEntry--;
5561 pCurrentElement = NameArray->CurrentEntry;
5563 pDirectoryCB = pCurrentElement->DirectoryCB;
5565 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5566 AFS_TRACE_LEVEL_VERBOSE,
5567 "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5569 NameArray->Count - 1,
5570 pCurrentElement->DirectoryCB,
5571 pCurrentElement->FileId.Cell,
5572 pCurrentElement->FileId.Volume,
5573 pCurrentElement->FileId.Vnode,
5574 pCurrentElement->FileId.Unique,
5575 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5576 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5579 // If the entry we are removing is a volume root,
5580 // we must remove the mount point entry as well.
5581 // If the NameArray was constructed by checking the
5582 // share name via the service, the name array can
5583 // contain two volume roots in sequence without a
5584 // mount point separating them.
5588 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
5591 pDirectoryCB = AFSBackupEntry( NameArray);
5601 return pDirectoryCB;
5605 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5608 AFSDirectoryCB *pDirEntry = NULL;
5609 AFSNameArrayCB *pElement = NULL;
5614 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5615 AFS_TRACE_LEVEL_VERBOSE,
5616 "AFSGetParentEntry [NA:%p]\n",
5619 if( NameArray->Count == 0 ||
5620 NameArray->Count == 1)
5623 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5624 AFS_TRACE_LEVEL_ERROR,
5625 "AFSGetParentEntry [NA:%p] No more entries\n",
5628 try_return( pDirEntry = NULL);
5631 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5633 pDirEntry = pElement->DirectoryCB;
5635 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5636 AFS_TRACE_LEVEL_VERBOSE,
5637 "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5639 NameArray->Count - 2,
5640 pElement->DirectoryCB,
5641 pElement->FileId.Cell,
5642 pElement->FileId.Volume,
5643 pElement->FileId.Vnode,
5644 pElement->FileId.Unique,
5645 &pElement->DirectoryCB->NameInformation.FileName,
5646 pElement->DirectoryCB->ObjectInformation->FileType);
5657 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5658 IN AFSDirectoryCB *DirectoryCB)
5661 AFSNameArrayCB *pCurrentElement = NULL;
5662 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5663 LONG lCount, lElement;
5668 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5669 AFS_TRACE_LEVEL_VERBOSE,
5670 "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5673 DirectoryCB->ObjectInformation->FileId.Cell,
5674 DirectoryCB->ObjectInformation->FileId.Volume,
5675 DirectoryCB->ObjectInformation->FileId.Vnode,
5676 DirectoryCB->ObjectInformation->FileId.Unique,
5677 &DirectoryCB->NameInformation.FileName,
5678 DirectoryCB->ObjectInformation->FileType);
5680 // Dereference previous name array contents
5683 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5686 pCurrentElement = &NameArray->ElementArray[ lElement];
5688 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5690 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5691 AFS_TRACE_LEVEL_VERBOSE,
5692 "AFSResetNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5694 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5695 pCurrentElement->DirectoryCB,
5698 ASSERT( lCount >= 0);
5701 RtlZeroMemory( NameArray,
5702 sizeof( AFSNameArrayHdr) +
5703 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5705 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5707 if( DirectoryCB != NULL)
5710 pCurrentElement = &NameArray->ElementArray[ 0];
5712 NameArray->CurrentEntry = pCurrentElement;
5714 NameArray->Count = 1;
5716 NameArray->LinkCount = 0;
5718 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5720 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5721 AFS_TRACE_LEVEL_VERBOSE,
5722 "AFSResetNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5724 &DirectoryCB->NameInformation.FileName,
5728 pCurrentElement->DirectoryCB = DirectoryCB;
5730 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5732 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5734 pCurrentElement->Flags = 0;
5736 if( pCurrentElement->FileId.Vnode == 1)
5739 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5742 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5743 AFS_TRACE_LEVEL_VERBOSE,
5744 "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5746 pCurrentElement->DirectoryCB,
5747 pCurrentElement->FileId.Cell,
5748 pCurrentElement->FileId.Volume,
5749 pCurrentElement->FileId.Vnode,
5750 pCurrentElement->FileId.Unique,
5751 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5752 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5760 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5763 AFSNameArrayCB *pCurrentElement = NULL;
5765 pCurrentElement = &NameArray->ElementArray[ 0];
5767 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5769 while( pCurrentElement->DirectoryCB != NULL)
5772 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5773 pCurrentElement->FileId.Cell,
5774 pCurrentElement->FileId.Volume,
5775 pCurrentElement->FileId.Vnode,
5776 pCurrentElement->FileId.Unique,
5777 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5782 AFSPrint("AFSDumpNameArray End\n\n");
5788 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5793 // Depending on the type of node, set the event
5796 switch( Fcb->Header.NodeTypeCode)
5799 case AFS_DIRECTORY_FCB:
5804 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5814 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5820 // Depending on the type of node, set the event
5823 switch( Fcb->Header.NodeTypeCode)
5826 case AFS_DIRECTORY_FCB:
5831 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5833 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5843 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5846 BOOLEAN bIsInProcess = FALSE;
5851 if( ObjectInfo->Fcb == NULL)
5854 try_return( bIsInProcess);
5857 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5860 case AFS_DIRECTORY_FCB:
5865 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5868 bIsInProcess = TRUE;
5880 return bIsInProcess;
5884 AFSVerifyVolume( IN ULONGLONG ProcessId,
5885 IN AFSVolumeCB *VolumeCB)
5888 UNREFERENCED_PARAMETER(ProcessId);
5889 UNREFERENCED_PARAMETER(VolumeCB);
5890 NTSTATUS ntStatus = STATUS_SUCCESS;
5897 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5900 NTSTATUS ntStatus = STATUS_SUCCESS;
5901 AFSObjectInfoCB *pObjectInfoCB = NULL;
5902 AFSDirectoryCB *pDirNode = NULL;
5903 ULONG ulEntryLength = 0;
5904 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5910 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5913 if( pObjectInfoCB == NULL)
5916 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5919 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5920 AFS_OBJECT_REFERENCE_DIRENTRY);
5922 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5923 AFS_TRACE_LEVEL_VERBOSE,
5924 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5928 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5930 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5932 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5934 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5938 if( pDirNode == NULL)
5941 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5944 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5945 AFS_TRACE_LEVEL_VERBOSE,
5946 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5949 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5950 sizeof( AFSNonPagedDirectoryCB),
5951 AFS_DIR_ENTRY_NP_TAG);
5953 if( pNonPagedDirEntry == NULL)
5956 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5959 RtlZeroMemory( pDirNode,
5962 RtlZeroMemory( pNonPagedDirEntry,
5963 sizeof( AFSNonPagedDirectoryCB));
5965 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5967 pDirNode->NonPaged = pNonPagedDirEntry;
5969 pDirNode->ObjectInformation = pObjectInfoCB;
5971 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5977 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5979 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5981 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5983 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5985 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5986 AFSPIOCtlName.Buffer,
5987 pDirNode->NameInformation.FileName.Length);
5989 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5992 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5995 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5996 AFS_TRACE_LEVEL_WARNING,
5997 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5998 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
6001 try_return( ntStatus = STATUS_REPARSE);
6006 if ( ntStatus != STATUS_SUCCESS)
6009 if ( pDirNode != NULL)
6012 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
6013 AFS_TRACE_LEVEL_VERBOSE,
6014 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
6017 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
6020 if( pNonPagedDirEntry != NULL)
6023 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
6025 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
6028 if ( pObjectInfoCB != NULL)
6031 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
6032 AFS_OBJECT_REFERENCE_DIRENTRY);
6034 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6035 AFS_TRACE_LEVEL_VERBOSE,
6036 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
6040 AFSDeleteObjectInfo( &pObjectInfoCB);
6049 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
6050 IN AFSDirectoryCB *DirectoryCB,
6051 IN UNICODE_STRING *ParentPathName,
6052 IN AFSNameArrayHdr *RelatedNameArray,
6054 OUT AFSFileInfoCB *FileInfo)
6057 NTSTATUS ntStatus = STATUS_SUCCESS;
6058 AFSDirEnumEntry *pDirEntry = NULL;
6059 UNICODE_STRING uniFullPathName = {0};
6060 AFSNameArrayHdr *pNameArray = NULL;
6061 AFSVolumeCB *pVolumeCB = NULL;
6062 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6063 AFSVolumeCB *pNewVolumeCB = NULL;
6064 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6065 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6066 AFSDirectoryCB *pNewParentDirEntry = NULL;
6067 WCHAR *pwchBuffer = NULL;
6068 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6069 ULONG ulNameDifference = 0;
6076 // Retrieve a target name for the entry
6079 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6082 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6085 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6087 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6092 if( !NT_SUCCESS( ntStatus) ||
6093 pDirEntry->TargetNameLength == 0)
6096 if( pDirEntry != NULL)
6099 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6102 try_return( ntStatus);
6105 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6108 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6112 // Update the target name
6115 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6116 &DirectoryCB->Flags,
6117 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6118 (USHORT)pDirEntry->TargetNameLength);
6120 if( !NT_SUCCESS( ntStatus))
6123 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6125 try_return( ntStatus);
6129 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6133 // Need to pass the full path in for parsing.
6136 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
6139 uniFullPathName.Length = 0;
6140 uniFullPathName.MaximumLength = ParentPathName->Length +
6142 DirectoryCB->NameInformation.TargetName.Length;
6144 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6145 uniFullPathName.MaximumLength,
6146 AFS_NAME_BUFFER_SIX_TAG);
6148 if( uniFullPathName.Buffer == NULL)
6151 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6153 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6156 pwchBuffer = uniFullPathName.Buffer;
6158 RtlZeroMemory( uniFullPathName.Buffer,
6159 uniFullPathName.MaximumLength);
6161 RtlCopyMemory( uniFullPathName.Buffer,
6162 ParentPathName->Buffer,
6163 ParentPathName->Length);
6165 uniFullPathName.Length = ParentPathName->Length;
6167 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
6168 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
6171 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
6173 uniFullPathName.Length += sizeof( WCHAR);
6176 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
6177 DirectoryCB->NameInformation.TargetName.Buffer,
6178 DirectoryCB->NameInformation.TargetName.Length);
6180 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
6182 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
6183 uniParsedName.MaximumLength = uniParsedName.Length;
6185 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
6187 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6190 // We populate up to the current parent
6193 if( RelatedNameArray != NULL)
6196 pNameArray = AFSInitNameArray( NULL,
6197 RelatedNameArray->MaxElementCount);
6199 if( pNameArray == NULL)
6202 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6205 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
6212 pNameArray = AFSInitNameArray( NULL,
6215 if( pNameArray == NULL)
6218 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6221 ntStatus = AFSPopulateNameArray( pNameArray,
6226 if( !NT_SUCCESS( ntStatus))
6229 try_return( ntStatus);
6232 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
6234 pParentDirEntry = ParentDirectoryCB;
6239 uniFullPathName.Length = 0;
6240 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6242 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6243 uniFullPathName.MaximumLength,
6244 AFS_NAME_BUFFER_SEVEN_TAG);
6246 if( uniFullPathName.Buffer == NULL)
6249 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6251 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6254 pwchBuffer = uniFullPathName.Buffer;
6256 RtlZeroMemory( uniFullPathName.Buffer,
6257 uniFullPathName.MaximumLength);
6259 RtlCopyMemory( uniFullPathName.Buffer,
6260 DirectoryCB->NameInformation.TargetName.Buffer,
6261 DirectoryCB->NameInformation.TargetName.Length);
6263 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6266 // This name should begin with the \afs server so parse it off and check it
6269 FsRtlDissectName( uniFullPathName,
6273 if( RtlCompareUnicodeString( &uniComponentName,
6278 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6280 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6281 AFS_TRACE_LEVEL_ERROR,
6282 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
6285 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
6288 uniFullPathName = uniRemainingPath;
6290 uniParsedName = uniFullPathName;
6292 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6294 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6300 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6303 if( pNameArray == NULL)
6306 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6309 pVolumeCB = AFSGlobalRoot;
6311 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6315 // Increment the ref count on the volume and dir entry for correct processing below
6318 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
6320 lCount = AFSVolumeIncrement( pVolumeCB,
6321 VolumeReferenceReason);
6323 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6324 AFS_TRACE_LEVEL_VERBOSE,
6325 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
6327 VolumeReferenceReason,
6330 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6332 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6333 AFS_TRACE_LEVEL_VERBOSE,
6334 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6335 &pParentDirEntry->NameInformation.FileName,
6340 ntStatus = AFSLocateNameEntry( NULL,
6345 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
6349 &NewVolumeReferenceReason,
6350 &pNewParentDirEntry,
6354 if ( pNewVolumeCB != NULL)
6357 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6358 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6359 // the reference on pVolumeCB that was held prior to the call.
6360 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6361 // will be released second.
6364 lCount = AFSVolumeDecrement( pVolumeCB,
6365 VolumeReferenceReason);
6367 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6368 AFS_TRACE_LEVEL_VERBOSE,
6369 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
6371 VolumeReferenceReason,
6374 pVolumeCB = pNewVolumeCB;
6376 pNewVolumeCB = NULL;
6378 VolumeReferenceReason = NewVolumeReferenceReason;
6380 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6384 // AFSLocateNameEntry does not alter the reference count of
6385 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6386 // a reference held.
6389 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6391 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6392 AFS_TRACE_LEVEL_VERBOSE,
6393 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
6394 &pParentDirEntry->NameInformation.FileName,
6398 pParentDirEntry = pNewParentDirEntry;
6400 pNewParentDirEntry = NULL;
6402 if( !NT_SUCCESS( ntStatus) ||
6403 ntStatus == STATUS_REPARSE)
6406 try_return( ntStatus);
6410 // Store off the information
6413 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6416 // Check for the mount point being returned
6419 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
6422 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6424 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
6425 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6428 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6431 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6436 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6440 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6442 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6444 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6446 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6448 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6450 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6454 if( pDirEntry != NULL)
6457 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6460 if( pDirectoryEntry != NULL)
6463 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6465 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6466 AFS_TRACE_LEVEL_VERBOSE,
6467 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6468 &pDirectoryEntry->NameInformation.FileName,
6473 ASSERT( lCount >= 0);
6476 if ( pParentDirEntry != NULL)
6479 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6481 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6482 AFS_TRACE_LEVEL_VERBOSE,
6483 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6484 &pParentDirEntry->NameInformation.FileName,
6489 ASSERT( lCount >= 0);
6492 if( pVolumeCB != NULL)
6495 lCount = AFSVolumeDecrement( pVolumeCB,
6496 VolumeReferenceReason);
6498 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6499 AFS_TRACE_LEVEL_VERBOSE,
6500 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
6502 VolumeReferenceReason,
6506 if( pNameArray != NULL)
6509 AFSFreeNameArray( pNameArray);
6512 if( pwchBuffer != NULL)
6516 // Always free the buffer that we allocated as AFSLocateNameEntry
6517 // will not free it. If uniFullPathName.Buffer was allocated by
6518 // AFSLocateNameEntry, then we must free that as well.
6519 // Check that the uniFullPathName.Buffer in the string is not the same
6520 // offset by the length of the server name
6523 if( uniFullPathName.Length > 0 &&
6524 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6527 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6530 AFSExFreePoolWithTag( pwchBuffer, 0);
6538 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6539 IN ULONGLONG HashIndex)
6542 NTSTATUS ntStatus = STATUS_SUCCESS;
6543 AFSObjectInfoCB *pObjectInfo = NULL;
6549 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6550 sizeof( AFSObjectInfoCB),
6551 AFS_OBJECT_INFO_TAG);
6553 if( pObjectInfo == NULL)
6556 try_return( pObjectInfo);
6559 RtlZeroMemory( pObjectInfo,
6560 sizeof( AFSObjectInfoCB));
6562 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6563 sizeof( AFSNonPagedObjectInfoCB),
6564 AFS_NP_OBJECT_INFO_TAG);
6566 if( pObjectInfo->NonPagedInfo == NULL)
6569 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6571 try_return( pObjectInfo = NULL);
6574 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6576 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6578 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6580 if( ParentObjectInfo != NULL)
6583 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6585 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6587 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6589 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6590 AFS_OBJECT_REFERENCE_CHILD);
6592 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6593 AFS_TRACE_LEVEL_VERBOSE,
6594 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6600 // Initialize the access time
6603 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6608 ASSERT( ParentObjectInfo);
6611 // Insert the entry into the object tree and list
6614 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6616 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6619 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6624 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6625 &pObjectInfo->TreeEntry);
6627 ASSERT( NT_SUCCESS( ntStatus));
6631 // And the object list in the volume
6634 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6637 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6642 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6644 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6647 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6650 // Indicate the object is in the hash tree and linked list in the volume
6653 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6665 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6671 if ( ObjectInfo->ObjectReferenceCount == 0)
6674 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6677 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6682 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6685 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6690 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6692 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6697 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6699 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6705 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6709 LONG lCount, lCount2;
6711 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6714 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6719 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6721 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6723 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6726 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6729 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6731 ASSERT( lCount2 >= 0);
6733 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6739 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6740 IN AFSFileID *FileId)
6742 DWORD ntStatus = STATUS_SUCCESS;
6744 AFSObjectInfoCB *pObjectInfo = NULL;
6746 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6749 pObjectInfo = &VolumeCB->ObjectInformation;
6754 AFSAcquireExcl( VolumeCB->ObjectInfoTree.TreeLock,
6757 ullIndex = AFSCreateLowIndex( FileId);
6759 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6761 (AFSBTreeEntry **)&pObjectInfo);
6763 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6766 if ( NT_SUCCESS( ntStatus)) {
6768 AFSObjectInfoIncrement( pObjectInfo,
6769 AFS_OBJECT_REFERENCE_FIND);
6776 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6779 AFSObjectInfoDecrement( *ppObjectInfo,
6780 AFS_OBJECT_REFERENCE_FIND);
6782 *ppObjectInfo = NULL;
6786 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6789 BOOLEAN bAcquiredTreeLock = FALSE;
6790 AFSObjectInfoCB *pObjectInfo = (*ppObjectInfo);
6791 BOOLEAN bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6792 AFSObjectInfoCB * pParentObjectInfo = NULL;
6796 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_ROOT_VOLUME))
6800 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6801 // embedded in the VolumeCB.
6809 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6811 (*ppObjectInfo) = NULL;
6813 if( !ExIsResourceAcquiredExclusiveLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6816 ASSERT( !ExIsResourceAcquiredLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6818 AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6821 bAcquiredTreeLock = TRUE;
6824 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6827 pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
6828 &pObjectInfo->ParentFileId);
6832 // Remove it from the tree and list if it was inserted
6835 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6838 AFSRemoveHashEntry( &pObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6839 &pObjectInfo->TreeEntry);
6842 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6845 if( pObjectInfo->ListEntry.fLink == NULL)
6848 pObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6850 if( pObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6853 pObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6859 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6862 if( pObjectInfo->ListEntry.bLink == NULL)
6865 pObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6867 if( pObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6870 pObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6876 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6880 if( pParentObjectInfo != NULL)
6883 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6885 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6886 AFS_OBJECT_REFERENCE_CHILD);
6888 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6889 AFS_TRACE_LEVEL_VERBOSE,
6890 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6894 AFSReleaseObjectInfo( &pParentObjectInfo);
6897 if( bAcquiredTreeLock)
6900 AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6906 FileId = pObjectInfo->FileId;
6909 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6911 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6913 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6915 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6918 // Release the fid in the service
6924 AFSReleaseFid( &FileId);
6931 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6932 OUT AFSDirectoryCB **TargetDirEntry)
6935 NTSTATUS ntStatus = STATUS_SUCCESS;
6936 AFSDirEnumEntry *pDirEntry = NULL;
6937 UNICODE_STRING uniFullPathName = {0};
6938 AFSNameArrayHdr *pNameArray = NULL;
6939 AFSVolumeCB *pVolumeCB = NULL;
6940 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6941 AFSVolumeCB *pNewVolumeCB = NULL;
6942 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6943 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6944 AFSDirectoryCB *pNewParentDirEntry = NULL;
6945 WCHAR *pwchBuffer = NULL;
6946 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6947 ULONG ulNameDifference = 0;
6954 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6955 DirectoryCB->ObjectInformation,
6959 if( !NT_SUCCESS( ntStatus))
6961 try_return( ntStatus);
6965 // Retrieve a target name for the entry
6968 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6971 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6974 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6976 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6981 if( !NT_SUCCESS( ntStatus) ||
6982 pDirEntry->TargetNameLength == 0)
6985 if( pDirEntry != NULL)
6988 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6991 try_return( ntStatus);
6994 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6997 if( DirectoryCB->NameInformation.TargetName.Length == 0)
7001 // Update the target name
7004 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
7005 &DirectoryCB->Flags,
7006 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
7007 (USHORT)pDirEntry->TargetNameLength);
7009 if( !NT_SUCCESS( ntStatus))
7012 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7014 try_return( ntStatus);
7018 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
7022 // Need to pass the full path in for parsing.
7025 uniFullPathName.Length = 0;
7026 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
7028 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7029 uniFullPathName.MaximumLength,
7030 AFS_NAME_BUFFER_EIGHT_TAG);
7032 if( uniFullPathName.Buffer == NULL)
7035 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7037 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7040 pwchBuffer = uniFullPathName.Buffer;
7042 RtlZeroMemory( uniFullPathName.Buffer,
7043 uniFullPathName.MaximumLength);
7045 RtlCopyMemory( uniFullPathName.Buffer,
7046 DirectoryCB->NameInformation.TargetName.Buffer,
7047 DirectoryCB->NameInformation.TargetName.Length);
7049 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
7052 // This name should begin with the \afs server so parse it off and chech it
7055 FsRtlDissectName( uniFullPathName,
7059 if( RtlCompareUnicodeString( &uniComponentName,
7065 // Try evaluating the full path
7068 uniFullPathName.Buffer = pwchBuffer;
7070 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
7072 uniFullPathName.MaximumLength = uniFullPathName.Length;
7077 uniFullPathName = uniRemainingPath;
7080 uniParsedName = uniFullPathName;
7082 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
7084 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7090 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7093 if( pNameArray == NULL)
7096 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7099 pVolumeCB = AFSGlobalRoot;
7101 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7103 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
7105 lCount = AFSVolumeIncrement( pVolumeCB,
7106 VolumeReferenceReason);
7108 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7109 AFS_TRACE_LEVEL_VERBOSE,
7110 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
7112 VolumeReferenceReason,
7115 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
7117 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7118 AFS_TRACE_LEVEL_VERBOSE,
7119 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7120 &pParentDirEntry->NameInformation.FileName,
7125 ntStatus = AFSLocateNameEntry( NULL,
7134 &VolumeReferenceReason,
7135 &pNewParentDirEntry,
7139 if ( pNewVolumeCB != NULL)
7142 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
7143 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
7144 // the reference on pVolumeCB that was held prior to the call.
7145 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
7146 // will be released second.
7149 lCount = AFSVolumeDecrement( pVolumeCB,
7150 VolumeReferenceReason);
7152 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7153 AFS_TRACE_LEVEL_VERBOSE,
7154 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
7156 VolumeReferenceReason,
7159 pVolumeCB = pNewVolumeCB;
7161 pNewVolumeCB = NULL;
7163 VolumeReferenceReason = NewVolumeReferenceReason;
7165 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7169 // AFSLocateNameEntry does not alter the reference count of
7170 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
7171 // a reference held.
7174 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
7176 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7177 AFS_TRACE_LEVEL_VERBOSE,
7178 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
7179 &pParentDirEntry->NameInformation.FileName,
7183 pParentDirEntry = pNewParentDirEntry;
7185 pNewParentDirEntry = NULL;
7187 if( !NT_SUCCESS( ntStatus) ||
7188 ntStatus == STATUS_REPARSE)
7193 try_return( ntStatus);
7197 // Pass back the target dir entry for this request
7198 // The caller must release the DirOpenReferenceCount
7201 *TargetDirEntry = pDirectoryEntry;
7203 pDirectoryEntry = NULL;
7207 if( pDirectoryEntry != NULL)
7210 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
7212 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7213 AFS_TRACE_LEVEL_VERBOSE,
7214 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7215 &pDirectoryEntry->NameInformation.FileName,
7220 ASSERT( lCount >= 0);
7223 if ( pParentDirEntry != NULL)
7226 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
7228 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7229 AFS_TRACE_LEVEL_VERBOSE,
7230 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7231 &pParentDirEntry->NameInformation.FileName,
7236 ASSERT( lCount >= 0);
7239 if( pDirEntry != NULL)
7242 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
7245 if( pVolumeCB != NULL)
7248 lCount = AFSVolumeDecrement( pVolumeCB,
7249 VolumeReferenceReason);
7251 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7252 AFS_TRACE_LEVEL_VERBOSE,
7253 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
7255 VolumeReferenceReason,
7259 if( pNameArray != NULL)
7262 AFSFreeNameArray( pNameArray);
7265 if( pwchBuffer != NULL)
7269 // Always free the buffer that we allocated as AFSLocateNameEntry
7270 // will not free it. If uniFullPathName.Buffer was allocated by
7271 // AFSLocateNameEntry, then we must free that as well.
7272 // Check that the uniFullPathName.Buffer in the string is not the same
7273 // offset by the length of the server name
7276 if( uniFullPathName.Length > 0 &&
7277 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
7280 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
7283 AFSExFreePoolWithTag( pwchBuffer, 0);
7291 AFSCleanupFcb( IN AFSFcb *Fcb,
7292 IN BOOLEAN ForceFlush)
7295 NTSTATUS ntStatus = STATUS_SUCCESS;
7296 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
7297 LARGE_INTEGER liTime;
7298 IO_STATUS_BLOCK stIoStatus;
7303 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7305 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7307 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
7310 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
7311 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7314 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7315 AFS_TRACE_LEVEL_VERBOSE,
7316 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
7317 &Fcb->NPFcb->Resource,
7318 PsGetCurrentThread());
7320 AFSAcquireShared( &Fcb->NPFcb->Resource,
7323 if( Fcb->OpenReferenceCount > 0)
7326 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7327 AFS_TRACE_LEVEL_VERBOSE,
7328 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7329 &Fcb->NPFcb->SectionObjectResource,
7330 PsGetCurrentThread());
7332 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
7338 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7343 if( !NT_SUCCESS( stIoStatus.Status))
7346 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7347 AFS_TRACE_LEVEL_ERROR,
7348 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7349 Fcb->ObjectInformation->FileId.Cell,
7350 Fcb->ObjectInformation->FileId.Volume,
7351 Fcb->ObjectInformation->FileId.Vnode,
7352 Fcb->ObjectInformation->FileId.Unique,
7354 stIoStatus.Information);
7356 ntStatus = stIoStatus.Status;
7359 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7362 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7368 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7369 AFS_TRACE_LEVEL_WARNING,
7370 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
7371 Fcb->ObjectInformation->FileId.Cell,
7372 Fcb->ObjectInformation->FileId.Volume,
7373 Fcb->ObjectInformation->FileId.Vnode,
7374 Fcb->ObjectInformation->FileId.Unique);
7376 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7380 __except( EXCEPTION_EXECUTE_HANDLER)
7383 ntStatus = GetExceptionCode();
7387 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7388 Fcb->ObjectInformation->FileId.Cell,
7389 Fcb->ObjectInformation->FileId.Volume,
7390 Fcb->ObjectInformation->FileId.Vnode,
7391 Fcb->ObjectInformation->FileId.Unique,
7394 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7397 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7398 AFS_TRACE_LEVEL_VERBOSE,
7399 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7400 &Fcb->NPFcb->SectionObjectResource,
7401 PsGetCurrentThread());
7403 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7406 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7407 AFS_TRACE_LEVEL_VERBOSE,
7408 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
7409 &Fcb->NPFcb->Resource,
7410 PsGetCurrentThread());
7412 AFSReleaseResource( &Fcb->NPFcb->Resource);
7415 // Wait for any currently running flush or release requests to complete
7418 AFSWaitOnQueuedFlushes( Fcb);
7421 // Now perform another flush on the file
7424 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7428 AFSReleaseExtentsWithFlush( Fcb,
7434 if( Fcb->OpenReferenceCount == 0 ||
7435 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7436 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7439 AFSTearDownFcbExtents( Fcb,
7443 try_return( ntStatus);
7446 KeQueryTickCount( &liTime);
7449 // First up are there dirty extents in the cache to flush?
7452 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7453 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7457 // The file has been marked as invalid. Dump it
7460 AFSTearDownFcbExtents( Fcb,
7463 else if( ForceFlush ||
7464 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7465 Fcb->Specific.File.ExtentCount) &&
7466 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7467 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7469 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7471 Fcb->OpenReferenceCount == 0)
7474 AFSReleaseExtentsWithFlush( Fcb,
7481 // If there are extents and they haven't been used recently *and*
7482 // are not being used
7486 ( 0 != Fcb->Specific.File.ExtentCount &&
7487 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7488 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7489 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7492 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7493 AFS_TRACE_LEVEL_VERBOSE,
7494 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7495 &Fcb->NPFcb->SectionObjectResource,
7496 PsGetCurrentThread());
7498 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7504 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7509 if( !NT_SUCCESS( stIoStatus.Status))
7512 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7513 AFS_TRACE_LEVEL_ERROR,
7514 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7515 Fcb->ObjectInformation->FileId.Cell,
7516 Fcb->ObjectInformation->FileId.Volume,
7517 Fcb->ObjectInformation->FileId.Vnode,
7518 Fcb->ObjectInformation->FileId.Unique,
7520 stIoStatus.Information);
7522 ntStatus = stIoStatus.Status;
7526 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7529 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7535 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7536 AFS_TRACE_LEVEL_WARNING,
7537 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7538 Fcb->ObjectInformation->FileId.Cell,
7539 Fcb->ObjectInformation->FileId.Volume,
7540 Fcb->ObjectInformation->FileId.Vnode,
7541 Fcb->ObjectInformation->FileId.Unique);
7543 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7547 __except( EXCEPTION_EXECUTE_HANDLER)
7550 ntStatus = GetExceptionCode();
7554 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7555 Fcb->ObjectInformation->FileId.Cell,
7556 Fcb->ObjectInformation->FileId.Volume,
7557 Fcb->ObjectInformation->FileId.Vnode,
7558 Fcb->ObjectInformation->FileId.Unique,
7562 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7563 AFS_TRACE_LEVEL_VERBOSE,
7564 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7565 &Fcb->NPFcb->SectionObjectResource,
7566 PsGetCurrentThread());
7568 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7570 if( Fcb->OpenReferenceCount <= 0)
7574 // Tear em down we'll not be needing them again
7577 AFSTearDownFcbExtents( Fcb,
7584 ntStatus = STATUS_RETRY;
7597 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7598 IN UNICODE_STRING *NewFileName)
7601 NTSTATUS ntStatus = STATUS_SUCCESS;
7602 WCHAR *pTmpBuffer = NULL;
7607 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7610 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7613 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7615 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7617 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7621 // OK, we need to allocate a new name buffer
7624 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7625 NewFileName->Length,
7626 AFS_NAME_BUFFER_NINE_TAG);
7628 if( pTmpBuffer == NULL)
7631 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7634 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7636 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7638 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7641 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7643 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7644 NewFileName->Buffer,
7645 NewFileName->Length);
7656 AFSReadCacheFile( IN void *ReadBuffer,
7657 IN LARGE_INTEGER *ReadOffset,
7658 IN ULONG RequestedDataLength,
7659 IN OUT PULONG BytesRead)
7662 NTSTATUS ntStatus = STATUS_SUCCESS;
7665 PIO_STACK_LOCATION pIoStackLocation = NULL;
7666 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7667 FILE_OBJECT *pCacheFileObject = NULL;
7672 pCacheFileObject = AFSReferenceCacheFileObject();
7674 if( pCacheFileObject == NULL)
7676 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7679 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7682 // Initialize the event
7685 KeInitializeEvent( &kEvent,
7686 SynchronizationEvent,
7690 // Allocate an irp for this request. This could also come from a
7691 // private pool, for instance.
7694 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7700 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7704 // Build the IRP's main body
7707 pIrp->UserBuffer = ReadBuffer;
7709 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7710 pIrp->RequestorMode = KernelMode;
7711 pIrp->Flags |= IRP_READ_OPERATION;
7714 // Set up the I/O stack location.
7717 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7718 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7719 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7720 pIoStackLocation->FileObject = pCacheFileObject;
7721 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7723 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7726 // Set the completion routine.
7729 IoSetCompletionRoutine( pIrp,
7737 // Send it to the FSD
7740 ntStatus = IoCallDriver( pTargetDeviceObject,
7743 if( NT_SUCCESS( ntStatus))
7750 ntStatus = KeWaitForSingleObject( &kEvent,
7756 if( NT_SUCCESS( ntStatus))
7759 ntStatus = pIrp->IoStatus.Status;
7761 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7767 if( pCacheFileObject != NULL)
7769 AFSReleaseCacheFileObject( pCacheFileObject);
7775 if( pIrp->MdlAddress != NULL)
7778 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7781 MmUnlockPages( pIrp->MdlAddress);
7784 IoFreeMdl( pIrp->MdlAddress);
7787 pIrp->MdlAddress = NULL;
7801 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7806 UNREFERENCED_PARAMETER(Irp);
7807 UNREFERENCED_PARAMETER(DeviceObject);
7808 KEVENT *pEvent = (KEVENT *)Context;
7814 return STATUS_MORE_PROCESSING_REQUIRED;
7818 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7821 BOOLEAN bIsEmpty = FALSE;
7822 AFSDirectoryCB *pDirEntry = NULL;
7827 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7832 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7835 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7837 while( pDirEntry != NULL)
7840 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7841 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7849 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7854 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7861 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7862 IN AFSDirectoryCB *DirEntry)
7865 NTSTATUS ntStatus = STATUS_SUCCESS;
7870 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7873 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7874 AFS_TRACE_LEVEL_VERBOSE,
7875 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7877 &DirEntry->NameInformation.FileName);
7879 try_return( ntStatus);
7882 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7885 // Remove the entry from the parent tree
7888 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7889 AFS_TRACE_LEVEL_VERBOSE,
7890 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7892 &DirEntry->NameInformation.FileName);
7894 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7897 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7898 AFS_TRACE_LEVEL_VERBOSE,
7899 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7901 &DirEntry->NameInformation.FileName);
7903 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7906 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7910 // From the short name tree
7913 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7914 AFS_TRACE_LEVEL_VERBOSE,
7915 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7917 &DirEntry->NameInformation.FileName);
7919 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7922 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7925 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7926 AFS_TRACE_LEVEL_VERBOSE,
7927 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7929 &DirEntry->NameInformation.FileName);
7931 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7933 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7944 AFSGetAuthenticationId()
7947 LARGE_INTEGER liAuthId = {0,0};
7948 NTSTATUS ntStatus = STATUS_SUCCESS;
7949 PACCESS_TOKEN hToken = NULL;
7950 PTOKEN_STATISTICS pTokenInfo = NULL;
7951 BOOLEAN bCopyOnOpen = FALSE;
7952 BOOLEAN bEffectiveOnly = FALSE;
7953 BOOLEAN bPrimaryToken = FALSE;
7954 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7959 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7962 &stImpersonationLevel);
7967 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7972 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7973 AFS_TRACE_LEVEL_ERROR,
7974 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7976 try_return( ntStatus);
7979 bPrimaryToken = TRUE;
7982 ntStatus = SeQueryInformationToken( hToken,
7984 (PVOID *)&pTokenInfo);
7986 if( !NT_SUCCESS( ntStatus))
7989 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7990 AFS_TRACE_LEVEL_ERROR,
7991 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7993 try_return( ntStatus);
7996 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7997 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7999 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
8000 AFS_TRACE_LEVEL_VERBOSE,
8001 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
8012 PsDereferenceImpersonationToken( hToken);
8017 PsDereferencePrimaryToken( hToken);
8021 if( pTokenInfo != NULL)
8024 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
8032 AFSUnwindFileInfo( IN AFSFcb *Fcb,
8036 UNREFERENCED_PARAMETER(Fcb);
8037 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
8039 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
8042 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
8044 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
8047 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
8049 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
8052 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
8054 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
8057 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
8059 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
8066 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
8069 BOOLEAN bIsValid = TRUE;
8071 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
8073 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
8075 while( pCurrentDirEntry != NULL)
8078 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
8082 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
8087 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8088 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
8091 if( pDirEntry == NULL)
8098 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
8101 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
8104 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
8106 ObjectInfo->Specific.Directory.DirectoryNodeCount);
8108 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
8117 AFSReferenceCacheFileObject()
8120 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8121 FILE_OBJECT *pCacheFileObject = NULL;
8123 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
8126 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
8128 if( pCacheFileObject != NULL)
8130 ObReferenceObject( pCacheFileObject);
8133 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
8135 return pCacheFileObject;
8139 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
8142 ASSERT( CacheFileObject != NULL);
8144 ObDereferenceObject( CacheFileObject);
8150 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
8153 NTSTATUS ntStatus = STATUS_SUCCESS;
8154 AFSDeviceExt *pControlDevExt = NULL;
8155 ULONG ulTimeIncrement = 0;
8161 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
8163 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
8165 AFSServerName = LibraryInit->AFSServerName;
8167 AFSMountRootName = LibraryInit->AFSMountRootName;
8169 AFSDebugFlags = LibraryInit->AFSDebugFlags;
8172 // Callbacks in the framework
8175 AFSProcessRequest = LibraryInit->AFSProcessRequest;
8177 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
8179 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
8181 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
8183 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
8185 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
8187 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
8189 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
8191 if( LibraryInit->AFSCacheBaseAddress != NULL)
8194 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
8196 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
8198 AFSLibCacheLength = LibraryInit->AFSCacheLength;
8202 // Initialize some flush parameters
8205 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
8207 ulTimeIncrement = KeQueryTimeIncrement();
8209 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
8210 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
8211 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
8212 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
8213 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
8216 // Initialize the global root entry
8219 ntStatus = AFSInitVolume( NULL,
8220 &LibraryInit->GlobalRootFid,
8221 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
8224 if( !NT_SUCCESS( ntStatus))
8227 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8228 AFS_TRACE_LEVEL_ERROR,
8229 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
8232 try_return( ntStatus);
8235 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
8238 if( !NT_SUCCESS( ntStatus))
8241 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8242 AFS_TRACE_LEVEL_ERROR,
8243 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
8246 lCount = AFSVolumeDecrement( AFSGlobalRoot,
8247 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
8249 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8250 AFS_TRACE_LEVEL_VERBOSE,
8251 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8255 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8257 try_return( ntStatus);
8261 // Update the node type code to AFS_ROOT_ALL
8264 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
8266 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
8269 // Invalidate all known volumes since contact with the service and therefore
8270 // the file server was lost.
8273 AFSInvalidateAllVolumes();
8276 // Drop the locks acquired above
8279 AFSInitVolumeWorker( AFSGlobalRoot);
8281 lCount = AFSVolumeDecrement( AFSGlobalRoot,
8282 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
8284 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8285 AFS_TRACE_LEVEL_VERBOSE,
8286 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8290 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8292 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
8306 NTSTATUS ntStatus = STATUS_SUCCESS;
8307 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
8313 if( AFSGlobalDotDirEntry != NULL)
8316 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
8317 AFS_OBJECT_REFERENCE_GLOBAL);
8319 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
8321 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
8323 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
8325 ExFreePool( AFSGlobalDotDirEntry);
8327 AFSGlobalDotDirEntry = NULL;
8330 if( AFSGlobalDotDotDirEntry != NULL)
8333 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
8334 AFS_OBJECT_REFERENCE_GLOBAL);
8336 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
8338 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
8340 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
8342 ExFreePool( AFSGlobalDotDotDirEntry);
8344 AFSGlobalDotDotDirEntry = NULL;
8347 if( AFSSpecialShareNames != NULL)
8350 pDirNode = AFSSpecialShareNames;
8352 while( pDirNode != NULL)
8355 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
8357 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
8358 AFS_OBJECT_REFERENCE_GLOBAL);
8360 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
8362 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
8364 ExFreePool( pDirNode->NonPaged);
8366 ExFreePool( pDirNode);
8368 pDirNode = pLastDirNode;
8371 AFSSpecialShareNames = NULL;
8379 AFSDefaultLogMsg( IN ULONG Subsystem,
8385 UNREFERENCED_PARAMETER(Subsystem);
8386 UNREFERENCED_PARAMETER(Level);
8387 NTSTATUS ntStatus = STATUS_SUCCESS;
8389 char chDebugBuffer[ 256];
8394 va_start( va_args, Format);
8396 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8401 if( NT_SUCCESS( ntStatus))
8403 DbgPrint( chDebugBuffer);
8413 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8414 IN ULONG InputBufferLength,
8415 IN AFSStatusInfoCB *StatusInfo,
8416 OUT ULONG *ReturnLength)
8419 NTSTATUS ntStatus = STATUS_SUCCESS;
8420 AFSVolumeCB *pVolumeCB = NULL;
8421 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8422 AFSVolumeCB *pNewVolumeCB = NULL;
8423 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8424 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8425 AFSObjectInfoCB *pObjectInfo = NULL;
8426 ULONGLONG ullIndex = 0;
8427 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8428 AFSNameArrayHdr *pNameArray = NULL;
8429 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8430 AFSDirectoryCB *pNewParentDirEntry = NULL;
8437 // If we are given a FID then look up the entry by that, otherwise
8441 if( GetStatusInfo->FileID.Cell != 0 &&
8442 GetStatusInfo->FileID.Volume != 0 &&
8443 GetStatusInfo->FileID.Vnode != 0 &&
8444 GetStatusInfo->FileID.Unique != 0)
8447 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8450 // Locate the volume node
8453 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8455 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8457 (AFSBTreeEntry **)&pVolumeCB);
8459 if( pVolumeCB != NULL)
8462 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8464 lCount = AFSVolumeIncrement( pVolumeCB,
8465 VolumeReferenceReason);
8467 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8468 AFS_TRACE_LEVEL_VERBOSE,
8469 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
8471 VolumeReferenceReason,
8475 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8477 if( !NT_SUCCESS( ntStatus) ||
8480 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8483 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8486 pObjectInfo = &pVolumeCB->ObjectInformation;
8488 lCount = AFSObjectInfoIncrement( pObjectInfo,
8489 AFS_OBJECT_REFERENCE_STATUS);
8491 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8492 AFS_TRACE_LEVEL_VERBOSE,
8493 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8500 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8503 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8505 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8507 (AFSBTreeEntry **)&pObjectInfo);
8509 if( pObjectInfo != NULL)
8513 // Reference the node so it won't be torn down
8516 lCount = AFSObjectInfoIncrement( pObjectInfo,
8517 AFS_OBJECT_REFERENCE_STATUS);
8519 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8520 AFS_TRACE_LEVEL_VERBOSE,
8521 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8526 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8528 if( !NT_SUCCESS( ntStatus) ||
8529 pObjectInfo == NULL)
8531 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8538 if( GetStatusInfo->FileNameLength == 0 ||
8539 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8541 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8544 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8545 uniFullPathName.MaximumLength = uniFullPathName.Length;
8547 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8550 // This name should begin with the \afs server so parse it off and check it
8553 FsRtlDissectName( uniFullPathName,
8557 if( RtlCompareUnicodeString( &uniComponentName,
8561 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8562 AFS_TRACE_LEVEL_ERROR,
8563 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8566 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8569 uniFullPathName = uniRemainingPath;
8571 uniParsedName = uniFullPathName;
8577 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8580 if( pNameArray == NULL)
8582 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8585 pVolumeCB = AFSGlobalRoot;
8587 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8590 // Increment the ref count on the volume and dir entry for correct processing below
8593 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8595 lCount = AFSVolumeIncrement( pVolumeCB,
8596 VolumeReferenceReason);
8598 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8599 AFS_TRACE_LEVEL_VERBOSE,
8600 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8602 VolumeReferenceReason,
8605 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8607 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8608 AFS_TRACE_LEVEL_VERBOSE,
8609 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8610 &pParentDirEntry->NameInformation.FileName,
8615 ntStatus = AFSLocateNameEntry( NULL,
8620 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8621 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8625 &NewVolumeReferenceReason,
8626 &pNewParentDirEntry,
8630 if ( pNewVolumeCB != NULL)
8634 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8635 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8636 // the reference on pVolumeCB that was held prior to the call.
8637 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8638 // will be released second.
8641 lCount = AFSVolumeDecrement( pVolumeCB,
8642 VolumeReferenceReason);
8644 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8645 AFS_TRACE_LEVEL_VERBOSE,
8646 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8648 VolumeReferenceReason,
8651 pVolumeCB = pNewVolumeCB;
8653 pNewVolumeCB = NULL;
8655 VolumeReferenceReason = NewVolumeReferenceReason;
8657 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8661 // AFSLocateNameEntry does not alter the reference count of
8662 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8663 // a reference held.
8666 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8668 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8669 AFS_TRACE_LEVEL_VERBOSE,
8670 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8671 &pParentDirEntry->NameInformation.FileName,
8675 pParentDirEntry = pNewParentDirEntry;
8677 pNewParentDirEntry = NULL;
8679 if( !NT_SUCCESS( ntStatus) ||
8680 ntStatus == STATUS_REPARSE)
8685 try_return( ntStatus);
8688 pObjectInfo = pDirectoryEntry->ObjectInformation;
8690 lCount = AFSObjectInfoIncrement( pObjectInfo,
8691 AFS_OBJECT_REFERENCE_STATUS);
8693 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8694 AFS_TRACE_LEVEL_VERBOSE,
8695 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8701 // At this point we have an object info block, return the information
8704 StatusInfo->FileId = pObjectInfo->FileId;
8706 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8708 StatusInfo->Expiration = pObjectInfo->Expiration;
8710 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8712 StatusInfo->FileType = pObjectInfo->FileType;
8714 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8716 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8718 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8720 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8722 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8724 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8726 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8728 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8730 StatusInfo->EaSize = pObjectInfo->EaSize;
8732 StatusInfo->Links = pObjectInfo->Links;
8735 // Return the information length
8738 *ReturnLength = sizeof( AFSStatusInfoCB);
8742 if( pDirectoryEntry != NULL)
8745 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8747 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8748 AFS_TRACE_LEVEL_VERBOSE,
8749 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8750 &pDirectoryEntry->NameInformation.FileName,
8755 ASSERT( lCount >= 0);
8758 if ( pParentDirEntry != NULL)
8761 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8763 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8764 AFS_TRACE_LEVEL_VERBOSE,
8765 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8766 &pParentDirEntry->NameInformation.FileName,
8771 ASSERT( lCount >= 0);
8774 if( pObjectInfo != NULL)
8777 lCount = AFSObjectInfoDecrement( pObjectInfo,
8778 AFS_OBJECT_REFERENCE_STATUS);
8780 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8781 AFS_TRACE_LEVEL_VERBOSE,
8782 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8787 if( pVolumeCB != NULL)
8790 lCount = AFSVolumeDecrement( pVolumeCB,
8791 VolumeReferenceReason);
8793 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8794 AFS_TRACE_LEVEL_VERBOSE,
8795 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8797 VolumeReferenceReason,
8801 if( pNameArray != NULL)
8804 AFSFreeNameArray( pNameArray);
8812 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8813 IN UNICODE_STRING *ComponentName)
8816 NTSTATUS ntStatus = STATUS_SUCCESS;
8817 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8818 AFSDirectoryCB *pDirEntry = NULL;
8826 // Search for the entry in the parent
8829 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8830 AFS_TRACE_LEVEL_VERBOSE_2,
8831 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8834 ulCRC = AFSGenerateCRC( ComponentName,
8837 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8840 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8844 if( pDirEntry == NULL)
8848 // Missed so perform a case insensitive lookup
8851 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8852 AFS_TRACE_LEVEL_VERBOSE_2,
8853 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8856 ulCRC = AFSGenerateCRC( ComponentName,
8859 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8863 if( pDirEntry == NULL)
8867 // OK, if this component is a valid short name then try
8868 // a lookup in the short name tree
8871 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8872 RtlIsNameLegalDOS8Dot3( ComponentName,
8877 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8878 AFS_TRACE_LEVEL_VERBOSE_2,
8879 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8882 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8889 if( pDirEntry != NULL)
8891 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8893 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8894 AFS_TRACE_LEVEL_VERBOSE,
8895 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8896 &pDirEntry->NameInformation.FileName,
8901 ASSERT( lCount >= 0);
8904 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8906 if( pDirEntry == NULL)
8909 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8910 AFS_TRACE_LEVEL_VERBOSE_2,
8911 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8913 STATUS_OBJECT_NAME_NOT_FOUND);
8915 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8919 // We have the symlink object but previously failed to process it so return access
8923 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8924 AFS_TRACE_LEVEL_VERBOSE_2,
8925 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8928 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8930 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8932 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8933 AFS_TRACE_LEVEL_VERBOSE,
8934 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8935 &pDirEntry->NameInformation.FileName,
8940 ASSERT( lCount >= 0);
8951 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8952 OUT UNICODE_STRING *ComponentName)
8955 NTSTATUS ntStatus = STATUS_SUCCESS;
8956 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8958 uniFullPathName = *FullPathName;
8963 FsRtlDissectName( uniFullPathName,
8967 if( uniRemainingPath.Length == 0)
8972 uniFullPathName = uniRemainingPath;
8975 if( uniComponentName.Length > 0)
8977 *ComponentName = uniComponentName;
8984 AFSDumpTraceFiles_Default()
8990 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8993 BOOLEAN bIsValidName = TRUE;
8999 while( usIndex < FileName->Length/sizeof( WCHAR))
9002 if( FileName->Buffer[ usIndex] == L':' ||
9003 FileName->Buffer[ usIndex] == L'*' ||
9004 FileName->Buffer[ usIndex] == L'?' ||
9005 FileName->Buffer[ usIndex] == L'"' ||
9006 FileName->Buffer[ usIndex] == L'<' ||
9007 FileName->Buffer[ usIndex] == L'>')
9009 bIsValidName = FALSE;
9017 return bIsValidName;
9021 AFSCreateDefaultSecurityDescriptor()
9024 NTSTATUS ntStatus = STATUS_SUCCESS;
9026 ULONG ulSACLSize = 0;
9027 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
9028 ULONG ulACESize = 0;
9029 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
9030 ULONG ulSDLength = 0;
9031 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
9032 PSID pWorldSID = NULL;
9033 ULONG *pulSubAuthority = NULL;
9034 ULONG ulWorldSIDLEngth = 0;
9039 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
9041 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
9043 AFS_GENERIC_MEMORY_29_TAG);
9045 if( pWorldSID == NULL)
9047 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
9048 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9051 RtlZeroMemory( pWorldSID,
9054 RtlInitializeSid( pWorldSID,
9055 &SeWorldSidAuthority,
9058 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
9059 *pulSubAuthority = SECURITY_WORLD_RID;
9061 if( AFSRtlSetSaclSecurityDescriptor == NULL)
9064 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
9069 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
9071 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
9073 AFS_GENERIC_MEMORY_29_TAG);
9078 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
9080 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9083 RtlZeroMemory( pACE,
9086 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
9087 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
9088 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
9089 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
9091 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
9093 SeExports->SeLowMandatorySid);
9095 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
9096 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
9098 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
9100 AFS_GENERIC_MEMORY_29_TAG);
9105 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
9107 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9110 ntStatus = RtlCreateAcl( pSACL,
9114 if( !NT_SUCCESS( ntStatus))
9117 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
9120 try_return( ntStatus);
9123 ntStatus = RtlAddAce( pSACL,
9127 pACE->Header.AceSize);
9129 if( !NT_SUCCESS( ntStatus))
9132 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
9135 try_return( ntStatus);
9139 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
9140 sizeof( SECURITY_DESCRIPTOR),
9141 AFS_GENERIC_MEMORY_27_TAG);
9143 if( pSecurityDescr == NULL)
9146 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9148 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9151 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
9152 SECURITY_DESCRIPTOR_REVISION);
9154 if( !NT_SUCCESS( ntStatus))
9157 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
9160 try_return( ntStatus);
9163 if( AFSRtlSetSaclSecurityDescriptor != NULL)
9165 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
9170 if( !NT_SUCCESS( ntStatus))
9173 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
9176 try_return( ntStatus);
9181 // Add in the group and owner to the SD
9184 if( AFSRtlSetGroupSecurityDescriptor != NULL)
9186 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
9190 if( !NT_SUCCESS( ntStatus))
9193 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
9196 try_return( ntStatus);
9200 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
9204 if( !NT_SUCCESS( ntStatus))
9207 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
9210 try_return( ntStatus);
9213 if( !RtlValidSecurityDescriptor( pSecurityDescr))
9216 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
9218 try_return( ntStatus = STATUS_INVALID_PARAMETER);
9221 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
9223 AFS_GENERIC_MEMORY_27_TAG);
9225 if( pRelativeSecurityDescr == NULL)
9228 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9230 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9233 ulSDLength = PAGE_SIZE;
9235 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
9236 pRelativeSecurityDescr,
9239 if( !NT_SUCCESS( ntStatus))
9242 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
9245 try_return( ntStatus);
9248 AFSDefaultSD = pRelativeSecurityDescr;
9252 if( !NT_SUCCESS( ntStatus))
9255 if( pRelativeSecurityDescr != NULL)
9257 ExFreePool( pRelativeSecurityDescr);
9261 if( pSecurityDescr != NULL)
9263 ExFreePool( pSecurityDescr);
9276 if( pWorldSID != NULL)
9278 ExFreePool( pWorldSID);
9286 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
9287 OUT UNICODE_STRING *ParentPath)
9290 *ParentPath = *FullFileName;
9293 // If the final character is a \, jump over it
9296 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
9298 ParentPath->Length -= sizeof( WCHAR);
9301 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
9303 ParentPath->Length -= sizeof( WCHAR);
9307 // And the separator
9310 ParentPath->Length -= sizeof( WCHAR);
9316 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
9317 IN AFSObjectInfoCB *ObjectInfo,
9318 IN BOOLEAN WriteAccess,
9319 OUT GUID *AuthGroup)
9322 NTSTATUS ntStatus = STATUS_SUCCESS;
9323 GUID stAuthGroup, stZeroAuthGroup;
9324 BOOLEAN bFoundAuthGroup = FALSE;
9325 AFSCcb *pCcb = NULL;
9331 RtlZeroMemory( &stAuthGroup,
9334 RtlZeroMemory( &stZeroAuthGroup,
9340 if( ObjectInfo != NULL &&
9341 ObjectInfo->Fcb != NULL)
9343 pFcb = ObjectInfo->Fcb;
9350 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
9353 pCcb = Fcb->CcbListHead;
9355 while( pCcb != NULL)
9359 pCcb->GrantedAccess & FILE_WRITE_DATA)
9361 RtlCopyMemory( &stAuthGroup,
9365 bFoundAuthGroup = TRUE;
9369 else if( pCcb->GrantedAccess & FILE_READ_DATA)
9372 // At least get the read-only access
9375 RtlCopyMemory( &stAuthGroup,
9379 bFoundAuthGroup = TRUE;
9382 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9385 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9388 if( !bFoundAuthGroup)
9391 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9392 (ULONGLONG)PsGetCurrentThreadId(),
9395 if( RtlCompareMemory( &stZeroAuthGroup,
9397 sizeof( GUID)) == sizeof( GUID))
9400 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9402 try_return( ntStatus = STATUS_ACCESS_DENIED);
9406 RtlCopyMemory( AuthGroup,
9419 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9420 IN ULONG InvalidateReason)
9423 NTSTATUS ntStatus = STATUS_SUCCESS;
9426 ULONG ulProcessCount = 0;
9433 switch( InvalidateReason)
9436 case AFS_INVALIDATE_DELETED:
9439 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9440 ObjectInfo->Fcb != NULL)
9443 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9446 ObjectInfo->Links = 0;
9448 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9450 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9455 // Clear out the extents
9456 // And get rid of them (note this involves waiting
9457 // for any writes or reads to the cache to complete)
9460 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9463 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9469 case AFS_INVALIDATE_DATA_VERSION:
9472 LARGE_INTEGER liCurrentOffset = {0,0};
9473 LARGE_INTEGER liFlushLength = {0,0};
9474 ULONG ulFlushLength = 0;
9475 BOOLEAN bLocked = FALSE;
9476 BOOLEAN bExtentsLocked = FALSE;
9477 BOOLEAN bCleanExtents = FALSE;
9479 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9480 ObjectInfo->Fcb != NULL)
9483 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9488 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9489 AFS_TRACE_LEVEL_VERBOSE,
9490 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9491 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9492 PsGetCurrentThread());
9494 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9497 bExtentsLocked = TRUE;
9500 // There are several possibilities here:
9502 // 0. If there are no extents or all of the extents are dirty, do nothing.
9504 // 1. There could be nothing dirty and an open reference count of zero
9505 // in which case we can just tear down all of the extents without
9506 // holding any resources.
9508 // 2. There could be nothing dirty and a non-zero open reference count
9509 // in which case we can issue a CcPurge against the entire file
9510 // while holding just the Fcb Resource.
9512 // 3. There can be dirty extents in which case we need to identify
9513 // the non-dirty ranges and then perform a CcPurge on just the
9514 // non-dirty ranges while holding just the Fcb Resource.
9517 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9520 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9523 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9525 bExtentsLocked = FALSE;
9527 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9530 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9534 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9540 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9541 AFS_TRACE_LEVEL_VERBOSE,
9542 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9543 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9544 PsGetCurrentThread());
9546 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9549 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9556 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9557 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9563 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9564 AFS_TRACE_LEVEL_WARNING,
9565 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9566 ObjectInfo->FileId.Cell,
9567 ObjectInfo->FileId.Volume,
9568 ObjectInfo->FileId.Vnode,
9569 ObjectInfo->FileId.Unique);
9571 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9576 bCleanExtents = TRUE;
9579 __except( EXCEPTION_EXECUTE_HANDLER)
9582 ntStatus = GetExceptionCode();
9586 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9587 ObjectInfo->FileId.Cell,
9588 ObjectInfo->FileId.Volume,
9589 ObjectInfo->FileId.Vnode,
9590 ObjectInfo->FileId.Unique,
9593 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9596 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9597 AFS_TRACE_LEVEL_VERBOSE,
9598 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9599 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9600 PsGetCurrentThread());
9602 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9608 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9610 bExtentsLocked = FALSE;
9612 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9613 AFS_TRACE_LEVEL_VERBOSE,
9614 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9615 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9616 PsGetCurrentThread());
9618 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9621 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9626 // Must build a list of non-dirty ranges from the beginning of the file
9627 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9628 // ranges. In all but the most extreme random data write scenario there will
9629 // be significantly fewer.
9631 // For each range we need offset and size.
9634 AFSByteRange * ByteRangeList = NULL;
9635 ULONG ulByteRangeCount = 0;
9637 BOOLEAN bPurgeOnClose = FALSE;
9642 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9645 if ( ByteRangeList != NULL ||
9646 ulByteRangeCount == 0)
9649 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9656 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9658 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9659 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9660 &ByteRangeList[ulIndex].FileOffset,
9665 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9666 AFS_TRACE_LEVEL_WARNING,
9667 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9668 ObjectInfo->FileId.Cell,
9669 ObjectInfo->FileId.Volume,
9670 ObjectInfo->FileId.Vnode,
9671 ObjectInfo->FileId.Unique);
9673 bPurgeOnClose = TRUE;
9678 bCleanExtents = TRUE;
9681 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9683 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9685 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9692 // We couldn't allocate the memory to build the purge list
9693 // so just walk the extent list while holding the ExtentsList Resource.
9694 // This could deadlock but we do not have much choice.
9697 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9699 bExtentsLocked = TRUE;
9701 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9705 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9709 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9711 while( ulProcessCount < ulCount)
9713 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9715 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9717 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9718 &pEntry->FileOffset,
9723 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9724 AFS_TRACE_LEVEL_WARNING,
9725 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9726 ObjectInfo->FileId.Cell,
9727 ObjectInfo->FileId.Volume,
9728 ObjectInfo->FileId.Vnode,
9729 ObjectInfo->FileId.Unique);
9731 bPurgeOnClose = TRUE;
9736 bCleanExtents = TRUE;
9740 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9743 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9745 while( liFlushLength.QuadPart > 0)
9748 if( liFlushLength.QuadPart > 512 * 1024000)
9750 ulFlushLength = 512 * 1024000;
9754 ulFlushLength = liFlushLength.LowPart;
9757 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9763 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9764 AFS_TRACE_LEVEL_WARNING,
9765 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9766 ObjectInfo->FileId.Cell,
9767 ObjectInfo->FileId.Volume,
9768 ObjectInfo->FileId.Vnode,
9769 ObjectInfo->FileId.Unique);
9771 bPurgeOnClose = TRUE;
9776 bCleanExtents = TRUE;
9779 liFlushLength.QuadPart -= ulFlushLength;
9783 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9791 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9797 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9798 AFS_TRACE_LEVEL_WARNING,
9799 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9800 ObjectInfo->FileId.Cell,
9801 ObjectInfo->FileId.Volume,
9802 ObjectInfo->FileId.Vnode,
9803 ObjectInfo->FileId.Unique);
9805 bPurgeOnClose = TRUE;
9810 bCleanExtents = TRUE;
9817 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9821 __except( EXCEPTION_EXECUTE_HANDLER)
9824 ntStatus = GetExceptionCode();
9828 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9829 ObjectInfo->FileId.Cell,
9830 ObjectInfo->FileId.Volume,
9831 ObjectInfo->FileId.Vnode,
9832 ObjectInfo->FileId.Unique,
9836 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9837 AFS_TRACE_LEVEL_VERBOSE,
9838 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9839 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9840 PsGetCurrentThread());
9842 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9846 if ( bExtentsLocked)
9849 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9855 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9861 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9871 // Destroy the reference passed in by the caller to AFSInvalidateObject
9872 // or AFSQueueInvalidateObject
9875 lCount = AFSObjectInfoDecrement( ObjectInfo,
9876 AFS_OBJECT_REFERENCE_INVALIDATION);
9878 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9879 AFS_TRACE_LEVEL_VERBOSE,
9880 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",