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)
3471 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3472 AFS_TRACE_LEVEL_VERBOSE,
3473 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3475 &pCurrentDirEntry->NameInformation.FileName);
3477 AFSDeleteDirEntry( ObjectInfo,
3483 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3485 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3486 AFS_TRACE_LEVEL_VERBOSE,
3487 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3489 pCurrentDirEntry->DirOpenReferenceCount);
3492 // We pull the short name from the parent tree since it could change below
3495 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3498 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3499 AFS_TRACE_LEVEL_VERBOSE,
3500 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3502 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3503 &pCurrentDirEntry->NameInformation.FileName);
3505 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3508 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3513 pCurrentDirEntry = pNextDirEntry;
3517 // Reget the directory contents
3520 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3523 if ( !NT_SUCCESS( ntStatus))
3525 try_return( ntStatus);
3529 // Now start again and tear down any entries not valid
3532 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3534 while( pCurrentDirEntry != NULL)
3537 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3539 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3542 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3543 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3544 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3547 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3550 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3552 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3553 AFS_TRACE_LEVEL_VERBOSE,
3554 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3556 &pCurrentDirEntry->NameInformation.FileName);
3558 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3563 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3566 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3567 AFS_TRACE_LEVEL_VERBOSE,
3568 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3570 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3571 &pCurrentDirEntry->NameInformation.FileName);
3575 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3577 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3578 AFS_TRACE_LEVEL_VERBOSE,
3579 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3581 &pCurrentDirEntry->NameInformation.FileName);
3586 pCurrentDirEntry = pNextDirEntry;
3591 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3592 AFS_TRACE_LEVEL_VERBOSE,
3593 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3595 pCurrentDirEntry->DirOpenReferenceCount);
3597 if( pCurrentDirEntry->DirOpenReferenceCount <= 0)
3600 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3601 AFS_TRACE_LEVEL_VERBOSE,
3602 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3603 &pCurrentDirEntry->NameInformation.FileName,
3604 ObjectInfo->FileId.Cell,
3605 ObjectInfo->FileId.Volume,
3606 ObjectInfo->FileId.Vnode,
3607 ObjectInfo->FileId.Unique);
3609 AFSDeleteDirEntry( ObjectInfo,
3615 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3616 AFS_TRACE_LEVEL_VERBOSE,
3617 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3619 &pCurrentDirEntry->NameInformation.FileName,
3620 ObjectInfo->FileId.Cell,
3621 ObjectInfo->FileId.Volume,
3622 ObjectInfo->FileId.Vnode,
3623 ObjectInfo->FileId.Unique);
3625 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3627 AFSRemoveNameEntry( ObjectInfo,
3631 pCurrentDirEntry = pNextDirEntry;
3635 if( !AFSValidateDirList( ObjectInfo))
3638 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3647 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3655 AFSIsVolumeFID( IN AFSFileID *FileID)
3658 BOOLEAN bIsVolume = FALSE;
3660 if( FileID->Vnode == 1 &&
3661 FileID->Unique == 1)
3671 AFSIsFinalNode( IN AFSFcb *Fcb)
3674 BOOLEAN bIsFinalNode = FALSE;
3676 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3677 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3678 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3679 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3680 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3683 bIsFinalNode = TRUE;
3688 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3689 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3692 return bIsFinalNode;
3696 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3697 IN AFSDirEnumEntry *DirEnumEntry)
3700 NTSTATUS ntStatus = STATUS_SUCCESS;
3701 UNICODE_STRING uniTargetName;
3702 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3707 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3709 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3711 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3713 pObjectInfo->FileType = DirEnumEntry->FileType;
3715 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3717 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3719 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3721 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3723 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3725 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3727 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3729 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3732 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3735 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3736 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3739 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3742 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3744 pObjectInfo->Links = DirEnumEntry->Links;
3746 if( DirEnumEntry->TargetNameLength > 0 &&
3747 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||