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 ||
1143 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1146 pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1149 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
1152 if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1155 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1160 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1164 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1167 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1168 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1172 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1173 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1174 pObjectInfoCB->TargetFileId.Unique == 0 &&
1175 pDirNode->NameInformation.TargetName.Length == 0)
1179 // This will ensure we perform a validation on the node
1182 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1185 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1188 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1193 // Object specific information
1196 pObjectInfoCB->Links = DirEnumEntry->Links;
1198 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1200 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1204 if( !NT_SUCCESS( ntStatus))
1207 if( pNonPagedDirEntry != NULL)
1210 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1212 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1215 if( pDirNode != NULL)
1218 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1219 AFS_TRACE_LEVEL_VERBOSE,
1220 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1223 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1229 // Dereference our object info block if we have one
1232 if( pObjectInfoCB != NULL)
1235 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1236 AFS_OBJECT_REFERENCE_DIRENTRY);
1238 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1239 AFS_TRACE_LEVEL_VERBOSE,
1240 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1244 if( bAllocatedObjectCB)
1247 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1249 AFSDeleteObjectInfo( &pObjectInfoCB);
1259 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1260 IN BOOLEAN DirectoryEntry)
1263 BOOLEAN bReturn = TRUE;
1264 ACCESS_MASK stAccessMask = 0;
1267 // Get rid of anything we don't know about
1270 DesiredAccess = (DesiredAccess &
1276 ACCESS_SYSTEM_SECURITY |
1280 FILE_READ_ATTRIBUTES |
1281 FILE_WRITE_ATTRIBUTES |
1282 FILE_LIST_DIRECTORY |
1288 // Our 'read only' access mask. These are the accesses we will
1289 // allow for a read only file
1292 stAccessMask = DELETE |
1297 ACCESS_SYSTEM_SECURITY |
1301 FILE_READ_ATTRIBUTES |
1302 FILE_WRITE_ATTRIBUTES |
1304 FILE_LIST_DIRECTORY |
1308 // For a directory, add in the directory specific accesses
1314 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1319 if( FlagOn( DesiredAccess, ~stAccessMask))
1323 // A write access is set ...
1333 AFSEvaluateNode( IN GUID *AuthGroup,
1334 IN AFSDirectoryCB *DirEntry)
1337 NTSTATUS ntStatus = STATUS_SUCCESS;
1338 AFSDirEnumEntry *pDirEntry = NULL;
1339 UNICODE_STRING uniTargetName;
1344 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1349 if( !NT_SUCCESS( ntStatus))
1352 try_return( ntStatus);
1355 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1357 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1359 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1361 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1363 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1365 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1367 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1369 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1371 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1373 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1375 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1377 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1378 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1381 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1384 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1387 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1390 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1395 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1399 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1401 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1404 // If we have a target name then see if it needs updating ...
1407 if( pDirEntry->TargetNameLength > 0)
1411 // Update the target name information if needed
1414 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1416 uniTargetName.MaximumLength = uniTargetName.Length;
1418 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1420 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1423 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1424 RtlCompareUnicodeString( &uniTargetName,
1425 &DirEntry->NameInformation.TargetName,
1430 // Update the target name
1433 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1435 uniTargetName.Buffer,
1436 uniTargetName.Length);
1438 if( !NT_SUCCESS( ntStatus))
1441 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1443 try_return( ntStatus);
1447 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1452 if( pDirEntry != NULL)
1455 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1463 AFSValidateSymLink( IN GUID *AuthGroup,
1464 IN AFSDirectoryCB *DirEntry)
1467 NTSTATUS ntStatus = STATUS_SUCCESS;
1468 AFSDirEnumEntry *pDirEntry = NULL;
1469 UNICODE_STRING uniTargetName;
1474 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1479 if( !NT_SUCCESS( ntStatus))
1482 try_return( ntStatus);
1485 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1486 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1489 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1490 AFS_TRACE_LEVEL_VERBOSE_2,
1491 "AFSValidateSymLink Invalid type Status %08lX\n",
1492 STATUS_OBJECT_NAME_NOT_FOUND);
1494 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1497 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1499 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1501 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1504 // Update the target name information if needed
1507 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1509 uniTargetName.MaximumLength = uniTargetName.Length;
1511 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1513 if( uniTargetName.Length > 0)
1516 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1519 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1520 RtlCompareUnicodeString( &uniTargetName,
1521 &DirEntry->NameInformation.TargetName,
1526 // Update the target name
1529 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1531 uniTargetName.Buffer,
1532 uniTargetName.Length);
1534 if( !NT_SUCCESS( ntStatus))
1537 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1539 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1543 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1547 // If the FileType is the same then nothing to do since it IS
1551 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1554 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1556 try_return( ntStatus = STATUS_SUCCESS);
1559 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1561 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1563 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1565 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1567 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1569 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1571 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1573 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1575 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1576 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1579 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1582 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1585 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1588 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1593 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1597 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1599 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1603 if( pDirEntry != NULL)
1606 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1614 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1618 NTSTATUS ntStatus = STATUS_SUCCESS;
1619 IO_STATUS_BLOCK stIoStatus;
1621 AFSObjectInfoCB * pParentObjectInfo = NULL;
1623 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1624 AFS_TRACE_LEVEL_VERBOSE,
1625 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1626 (*ppObjectInfo)->FileType,
1627 (*ppObjectInfo)->FileId.Cell,
1628 (*ppObjectInfo)->FileId.Volume,
1629 (*ppObjectInfo)->FileId.Vnode,
1630 (*ppObjectInfo)->FileId.Unique,
1633 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1636 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1637 &(*ppObjectInfo)->ParentFileId);
1640 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1641 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1642 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1645 // We only act on the mount point itself, not the target. If the
1646 // node has been deleted then mark it as such otherwise indicate
1647 // it requires verification
1650 if( Reason == AFS_INVALIDATE_DELETED)
1652 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1657 if( Reason == AFS_INVALIDATE_FLUSHED)
1660 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1662 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1665 (*ppObjectInfo)->Expiration.QuadPart = 0;
1667 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1669 (*ppObjectInfo)->TargetFileId.Unique = 0;
1671 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1672 AFS_TRACE_LEVEL_VERBOSE,
1673 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1674 (*ppObjectInfo)->FileId.Cell,
1675 (*ppObjectInfo)->FileId.Volume,
1676 (*ppObjectInfo)->FileId.Vnode,
1677 (*ppObjectInfo)->FileId.Unique);
1679 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1682 if ( pParentObjectInfo != NULL)
1685 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1687 if( Reason == AFS_INVALIDATE_CREDS)
1689 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1692 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1693 Reason == AFS_INVALIDATE_FLUSHED)
1695 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1699 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1702 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1705 FILE_ACTION_MODIFIED);
1708 try_return( ntStatus);
1712 // Depending on the reason for invalidation then perform work on the node
1718 case AFS_INVALIDATE_DELETED:
1722 // Mark this node as invalid
1725 (*ppObjectInfo)->Links = 0;
1727 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1729 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1730 AFS_TRACE_LEVEL_VERBOSE,
1731 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1732 (*ppObjectInfo)->FileId.Cell,
1733 (*ppObjectInfo)->FileId.Volume,
1734 (*ppObjectInfo)->FileId.Vnode,
1735 (*ppObjectInfo)->FileId.Unique);
1737 if( pParentObjectInfo != NULL)
1740 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1741 AFS_TRACE_LEVEL_VERBOSE,
1742 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1743 pParentObjectInfo->FileId.Cell,
1744 pParentObjectInfo->FileId.Volume,
1745 pParentObjectInfo->FileId.Vnode,
1746 pParentObjectInfo->FileId.Unique);
1748 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1750 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1752 pParentObjectInfo->Expiration.QuadPart = 0;
1754 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1756 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1760 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1763 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1766 FILE_ACTION_REMOVED);
1769 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1772 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1778 case AFS_INVALIDATE_FLUSHED:
1781 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1782 (*ppObjectInfo)->Fcb != NULL)
1785 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1786 AFS_TRACE_LEVEL_VERBOSE,
1787 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1788 (*ppObjectInfo)->FileId.Cell,
1789 (*ppObjectInfo)->FileId.Volume,
1790 (*ppObjectInfo)->FileId.Vnode,
1791 (*ppObjectInfo)->FileId.Unique);
1793 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1799 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1804 if( !NT_SUCCESS( stIoStatus.Status))
1807 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1808 AFS_TRACE_LEVEL_ERROR,
1809 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1810 (*ppObjectInfo)->FileId.Cell,
1811 (*ppObjectInfo)->FileId.Volume,
1812 (*ppObjectInfo)->FileId.Vnode,
1813 (*ppObjectInfo)->FileId.Unique,
1815 stIoStatus.Information);
1817 ntStatus = stIoStatus.Status;
1821 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1824 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1830 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1831 AFS_TRACE_LEVEL_WARNING,
1832 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1833 (*ppObjectInfo)->FileId.Cell,
1834 (*ppObjectInfo)->FileId.Volume,
1835 (*ppObjectInfo)->FileId.Vnode,
1836 (*ppObjectInfo)->FileId.Unique);
1838 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1842 __except( EXCEPTION_EXECUTE_HANDLER)
1845 ntStatus = GetExceptionCode();
1849 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1850 (*ppObjectInfo)->FileId.Cell,
1851 (*ppObjectInfo)->FileId.Volume,
1852 (*ppObjectInfo)->FileId.Vnode,
1853 (*ppObjectInfo)->FileId.Unique,
1856 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1859 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1862 // Clear out the extents
1863 // Get rid of them (note this involves waiting
1864 // for any writes or reads to the cache to complete)
1867 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1871 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1874 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1877 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1878 AFS_TRACE_LEVEL_VERBOSE,
1879 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1880 (*ppObjectInfo)->FileId.Cell,
1881 (*ppObjectInfo)->FileId.Volume,
1882 (*ppObjectInfo)->FileId.Vnode,
1883 (*ppObjectInfo)->FileId.Unique);
1885 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1888 // Fall through to the default processing
1894 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1896 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1900 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1903 if( Reason == AFS_INVALIDATE_CREDS)
1905 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1908 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1910 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1914 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1917 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1920 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1923 FILE_ACTION_MODIFIED);
1925 else if ( pParentObjectInfo != NULL)
1928 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1931 FILE_ACTION_MODIFIED);
1935 // Indicate this node requires re-evaluation for the remaining reasons
1938 (*ppObjectInfo)->Expiration.QuadPart = 0;
1940 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1941 AFS_TRACE_LEVEL_VERBOSE,
1942 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1943 (*ppObjectInfo)->FileId.Cell,
1944 (*ppObjectInfo)->FileId.Volume,
1945 (*ppObjectInfo)->FileId.Vnode,
1946 (*ppObjectInfo)->FileId.Unique);
1948 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1950 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1951 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1952 ( Reason == AFS_INVALIDATE_CALLBACK ||
1953 Reason == AFS_INVALIDATE_EXPIRED))
1955 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1956 AFS_INVALIDATE_DATA_VERSION)))
1959 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1969 if ( pParentObjectInfo != NULL)
1972 AFSReleaseObjectInfo( &pParentObjectInfo);
1979 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1982 NTSTATUS ntStatus = STATUS_SUCCESS;
1983 AFSVolumeCB *pVolumeCB = NULL;
1984 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1985 ULONGLONG ullIndex = 0;
1986 AFSObjectInfoCB *pObjectInfo = NULL;
1992 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1993 AFS_TRACE_LEVEL_VERBOSE,
1994 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1995 InvalidateCB->FileID.Cell,
1996 InvalidateCB->FileID.Volume,
1997 InvalidateCB->FileID.Vnode,
1998 InvalidateCB->FileID.Unique,
1999 InvalidateCB->FileType,
2000 InvalidateCB->WholeVolume,
2001 InvalidateCB->Reason);
2004 // Need to locate the Fcb for the directory to purge
2007 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2008 AFS_TRACE_LEVEL_VERBOSE,
2009 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2010 &pDevExt->Specific.RDR.VolumeTreeLock,
2011 PsGetCurrentThread());
2014 // Starve any exclusive waiters on this paticular call
2017 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2020 // Locate the volume node
2023 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2025 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2027 (AFSBTreeEntry **)&pVolumeCB);
2029 if( pVolumeCB != NULL)
2032 lCount = AFSVolumeIncrement( pVolumeCB,
2033 AFS_VOLUME_REFERENCE_INVALIDATE);
2035 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2036 AFS_TRACE_LEVEL_VERBOSE,
2037 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2042 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2044 if( !NT_SUCCESS( ntStatus) ||
2048 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2049 AFS_TRACE_LEVEL_WARNING,
2050 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2051 InvalidateCB->FileID.Cell,
2052 InvalidateCB->FileID.Volume,
2053 InvalidateCB->FileID.Vnode,
2054 InvalidateCB->FileID.Unique,
2057 try_return( ntStatus = STATUS_SUCCESS);
2061 // If this is a whole volume invalidation then go do it now
2064 if( InvalidateCB->WholeVolume)
2067 ntStatus = AFSInvalidateVolume( pVolumeCB,
2068 InvalidateCB->Reason);
2070 try_return( ntStatus);
2073 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
2076 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2079 pObjectInfo = &pVolumeCB->ObjectInformation;
2084 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2086 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2088 (AFSBTreeEntry **)&pObjectInfo);
2091 if( pObjectInfo != NULL)
2095 // Reference the node so it won't be torn down
2098 lCount = AFSObjectInfoIncrement( pObjectInfo,
2099 AFS_OBJECT_REFERENCE_INVALIDATION);
2101 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2102 AFS_TRACE_LEVEL_VERBOSE,
2103 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2108 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2110 if( !NT_SUCCESS( ntStatus) ||
2111 pObjectInfo == NULL)
2114 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2115 AFS_TRACE_LEVEL_VERBOSE,
2116 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2117 InvalidateCB->FileID.Cell,
2118 InvalidateCB->FileID.Volume,
2119 InvalidateCB->FileID.Vnode,
2120 InvalidateCB->FileID.Unique,
2123 try_return( ntStatus = STATUS_SUCCESS);
2126 AFSInvalidateObject( &pObjectInfo,
2127 InvalidateCB->Reason);
2131 if( pObjectInfo != NULL)
2134 lCount = AFSObjectInfoDecrement( pObjectInfo,
2135 AFS_OBJECT_REFERENCE_INVALIDATION);
2137 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2138 AFS_TRACE_LEVEL_VERBOSE,
2139 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2144 if ( pVolumeCB != NULL)
2147 lCount = AFSVolumeDecrement( pVolumeCB,
2148 AFS_VOLUME_REFERENCE_INVALIDATE);
2150 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2151 AFS_TRACE_LEVEL_VERBOSE,
2152 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2162 AFSIsChildOfParent( IN AFSFcb *Dcb,
2166 BOOLEAN bIsChild = FALSE;
2167 AFSFcb *pCurrentFcb = Fcb;
2168 AFSObjectInfoCB * pParentObjectInfo = NULL;
2170 while( pCurrentFcb != NULL)
2173 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2174 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2182 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2183 &pCurrentFcb->ObjectInformation->ParentFileId);
2185 if ( pParentObjectInfo != NULL)
2188 pCurrentFcb = pParentObjectInfo->Fcb;
2190 AFSReleaseObjectInfo( &pParentObjectInfo);
2204 AFSCreateHighIndex( IN AFSFileID *FileID)
2207 ULONGLONG ullIndex = 0;
2209 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2216 AFSCreateLowIndex( IN AFSFileID *FileID)
2219 ULONGLONG ullIndex = 0;
2221 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2227 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2228 IN ACCESS_MASK GrantedAccess,
2229 IN BOOLEAN DirectoryEntry)
2232 BOOLEAN bAccessGranted = TRUE;
2235 // Check if we are asking for read/write and granted only read only
2236 // NOTE: There will be more checks here
2239 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2241 AFSCheckForReadOnlyAccess( GrantedAccess,
2245 bAccessGranted = FALSE;
2248 return bAccessGranted;
2252 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2255 NTSTATUS ntStatus = STATUS_SUCCESS;
2256 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2262 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2264 if( AFSGlobalRoot == NULL)
2271 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2274 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2281 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2288 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2289 IN UNICODE_STRING *SubstituteName,
2290 IN ULONG StringIndex)
2293 NTSTATUS ntStatus = STATUS_SUCCESS;
2294 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2295 AFSSysNameCB *pSysName = NULL;
2296 ERESOURCE *pSysNameLock = NULL;
2299 UNICODE_STRING uniSysName;
2306 if( IoIs32bitProcess( NULL))
2309 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2311 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2316 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2318 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2322 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2324 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2328 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2329 AFS_TRACE_LEVEL_VERBOSE,
2330 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2332 PsGetCurrentThread());
2334 AFSAcquireShared( pSysNameLock,
2338 // Find where we are in the list
2341 while( pSysName != NULL &&
2342 ulIndex < StringIndex)
2345 pSysName = pSysName->fLink;
2350 if( pSysName == NULL)
2353 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2354 AFS_TRACE_LEVEL_VERBOSE_2,
2355 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2357 STATUS_OBJECT_NAME_NOT_FOUND);
2359 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2362 RtlInitUnicodeString( &uniSysName,
2365 // If it is a full component of @SYS then just substitue the
2369 if( RtlCompareUnicodeString( &uniSysName,
2374 SubstituteName->Length = pSysName->SysName.Length;
2375 SubstituteName->MaximumLength = SubstituteName->Length;
2377 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2378 SubstituteName->Length,
2379 AFS_SUBST_BUFFER_TAG);
2381 if( SubstituteName->Buffer == NULL)
2384 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2387 RtlCopyMemory( SubstituteName->Buffer,
2388 pSysName->SysName.Buffer,
2389 pSysName->SysName.Length);
2396 while( ComponentName->Buffer[ usIndex] != L'@')
2402 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2403 SubstituteName->MaximumLength = SubstituteName->Length;
2405 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2406 SubstituteName->Length,
2407 AFS_SUBST_BUFFER_TAG);
2409 if( SubstituteName->Buffer == NULL)
2412 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2415 RtlCopyMemory( SubstituteName->Buffer,
2416 ComponentName->Buffer,
2417 usIndex * sizeof( WCHAR));
2419 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2420 pSysName->SysName.Buffer,
2421 pSysName->SysName.Length);
2426 AFSReleaseResource( pSysNameLock);
2433 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2434 IN OUT UNICODE_STRING *ComponentName,
2435 IN UNICODE_STRING *SubstituteName,
2436 IN OUT UNICODE_STRING *RemainingPath,
2437 IN BOOLEAN FreePathName)
2440 NTSTATUS ntStatus = STATUS_SUCCESS;
2441 UNICODE_STRING uniPathName;
2442 USHORT usPrefixNameLen = 0;
2443 SHORT sNameLenDelta = 0;
2449 // If the passed in name can handle the additional length
2450 // then just moves things around
2453 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2455 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2457 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2460 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2463 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2464 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2465 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2468 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2469 SubstituteName->Buffer,
2470 SubstituteName->Length);
2472 FullPathName->Length += sNameLenDelta;
2474 ComponentName->Length += sNameLenDelta;
2476 ComponentName->MaximumLength = ComponentName->Length;
2478 if ( RemainingPath->Buffer)
2481 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2484 try_return( ntStatus);
2488 // Need to re-allocate the buffer
2491 uniPathName.Length = FullPathName->Length -
2492 ComponentName->Length +
2493 SubstituteName->Length;
2495 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2497 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2498 uniPathName.MaximumLength,
2499 AFS_NAME_BUFFER_FOUR_TAG);
2501 if( uniPathName.Buffer == NULL)
2504 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2507 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2509 usPrefixNameLen *= sizeof( WCHAR);
2511 RtlZeroMemory( uniPathName.Buffer,
2512 uniPathName.MaximumLength);
2514 RtlCopyMemory( uniPathName.Buffer,
2515 FullPathName->Buffer,
2518 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2519 SubstituteName->Buffer,
2520 SubstituteName->Length);
2522 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2525 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2526 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2527 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2530 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2532 ComponentName->Length += sNameLenDelta;
2534 ComponentName->MaximumLength = ComponentName->Length;
2536 if ( RemainingPath->Buffer)
2539 RemainingPath->Buffer = uniPathName.Buffer
2540 + (RemainingPath->Buffer - FullPathName->Buffer)
2541 + sNameLenDelta/sizeof( WCHAR);
2546 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2549 *FullPathName = uniPathName;
2560 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2564 NTSTATUS ntStatus = STATUS_SUCCESS;
2565 AFSObjectInfoCB *pCurrentObject = NULL;
2566 AFSObjectInfoCB *pNextObject = NULL;
2572 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2573 AFS_TRACE_LEVEL_VERBOSE,
2574 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2575 VolumeCB->ObjectInformation.FileId.Cell,
2576 VolumeCB->ObjectInformation.FileId.Volume,
2577 VolumeCB->ObjectInformation.FileId.Vnode,
2578 VolumeCB->ObjectInformation.FileId.Unique,
2582 // Depending on the reason for invalidation then perform work on the node
2588 case AFS_INVALIDATE_DELETED:
2592 // Mark this volume as invalid
2595 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2597 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2604 // Invalidate the volume root directory
2607 pCurrentObject = &VolumeCB->ObjectInformation;
2609 if ( pCurrentObject )
2612 lCount = AFSObjectInfoIncrement( pCurrentObject,
2613 AFS_OBJECT_REFERENCE_INVALIDATION);
2615 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2616 AFS_TRACE_LEVEL_VERBOSE,
2617 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2621 AFSInvalidateObject( &pCurrentObject,
2624 if ( pCurrentObject)
2627 lCount = AFSObjectInfoDecrement( pCurrentObject,
2628 AFS_OBJECT_REFERENCE_INVALIDATION);
2630 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2631 AFS_TRACE_LEVEL_VERBOSE,
2632 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2639 // Apply invalidation to all other volume objects
2642 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2645 pCurrentObject = VolumeCB->ObjectInfoListHead;
2647 if ( pCurrentObject)
2651 // Reference the node so it won't be torn down
2654 lCount = AFSObjectInfoIncrement( pCurrentObject,
2655 AFS_OBJECT_REFERENCE_INVALIDATION);
2657 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2658 AFS_TRACE_LEVEL_VERBOSE,
2659 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2664 while( pCurrentObject != NULL)
2667 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2673 // Reference the node so it won't be torn down
2676 lCount = AFSObjectInfoIncrement( pNextObject,
2677 AFS_OBJECT_REFERENCE_INVALIDATION);
2679 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2680 AFS_TRACE_LEVEL_VERBOSE,
2681 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2686 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2688 AFSInvalidateObject( &pCurrentObject,
2691 if ( pCurrentObject )
2694 lCount = AFSObjectInfoDecrement( pCurrentObject,
2695 AFS_OBJECT_REFERENCE_INVALIDATION);
2697 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2698 AFS_TRACE_LEVEL_VERBOSE,
2699 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2704 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2707 pCurrentObject = pNextObject;
2710 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2717 AFSInvalidateAllVolumes( VOID)
2719 AFSVolumeCB *pVolumeCB = NULL;
2720 AFSVolumeCB *pNextVolumeCB = NULL;
2721 AFSDeviceExt *pRDRDeviceExt = NULL;
2724 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2726 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2727 AFS_TRACE_LEVEL_VERBOSE,
2728 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2729 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2730 PsGetCurrentThread());
2732 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2735 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2740 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2741 AFS_TRACE_LEVEL_VERBOSE,
2742 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2743 pVolumeCB->ObjectInfoTree.TreeLock,
2744 PsGetCurrentThread());
2746 lCount = AFSVolumeIncrement( pVolumeCB,
2747 AFS_VOLUME_REFERENCE_INVALIDATE);
2749 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2750 AFS_TRACE_LEVEL_VERBOSE,
2751 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2756 while( pVolumeCB != NULL)
2759 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2764 lCount = AFSVolumeIncrement( pNextVolumeCB,
2765 AFS_VOLUME_REFERENCE_INVALIDATE);
2767 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2768 AFS_TRACE_LEVEL_VERBOSE,
2769 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2774 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2776 // do I need to hold the volume lock here?
2778 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2780 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2783 lCount = AFSVolumeDecrement( pVolumeCB,
2784 AFS_VOLUME_REFERENCE_INVALIDATE);
2786 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2787 AFS_TRACE_LEVEL_VERBOSE,
2788 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2792 pVolumeCB = pNextVolumeCB;
2795 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2799 AFSVerifyEntry( IN GUID *AuthGroup,
2800 IN AFSDirectoryCB *DirEntry)
2803 NTSTATUS ntStatus = STATUS_SUCCESS;
2804 AFSDirEnumEntry *pDirEnumEntry = NULL;
2805 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2806 IO_STATUS_BLOCK stIoStatus;
2811 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2812 AFS_TRACE_LEVEL_VERBOSE_2,
2813 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2814 &DirEntry->NameInformation.FileName,
2815 pObjectInfo->FileId.Cell,
2816 pObjectInfo->FileId.Volume,
2817 pObjectInfo->FileId.Vnode,
2818 pObjectInfo->FileId.Unique);
2820 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2825 if( !NT_SUCCESS( ntStatus))
2828 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2829 AFS_TRACE_LEVEL_ERROR,
2830 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2831 &DirEntry->NameInformation.FileName,
2832 pObjectInfo->FileId.Cell,
2833 pObjectInfo->FileId.Volume,
2834 pObjectInfo->FileId.Vnode,
2835 pObjectInfo->FileId.Unique,
2838 try_return( ntStatus);
2842 // Check the data version of the file
2845 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2847 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2850 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2851 AFS_TRACE_LEVEL_VERBOSE,
2852 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2853 pObjectInfo->DataVersion.QuadPart,
2854 &DirEntry->NameInformation.FileName,
2855 pObjectInfo->FileId.Cell,
2856 pObjectInfo->FileId.Volume,
2857 pObjectInfo->FileId.Vnode,
2858 pObjectInfo->FileId.Unique);
2861 // We are ok, just get out
2864 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2866 try_return( ntStatus = STATUS_SUCCESS);
2871 // New data version so we will need to process the node based on the type
2874 switch( pDirEnumEntry->FileType)
2877 case AFS_FILE_TYPE_MOUNTPOINT:
2881 // For a mount point we need to ensure the target is the same
2884 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2885 &pDirEnumEntry->TargetFileId))
2891 // Update the metadata for the entry
2894 ntStatus = AFSUpdateMetaData( DirEntry,
2897 if( NT_SUCCESS( ntStatus))
2900 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2906 case AFS_FILE_TYPE_SYMLINK:
2910 // Update the metadata for the entry
2913 ntStatus = AFSUpdateMetaData( DirEntry,
2916 if( NT_SUCCESS( ntStatus))
2919 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2925 case AFS_FILE_TYPE_FILE:
2927 FILE_OBJECT * pCCFileObject = NULL;
2928 BOOLEAN bPurgeExtents = FALSE;
2930 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
2933 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2934 AFS_TRACE_LEVEL_VERBOSE,
2935 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
2936 &DirEntry->NameInformation.FileName,
2937 pObjectInfo->FileId.Cell,
2938 pObjectInfo->FileId.Volume,
2939 pObjectInfo->FileId.Vnode,
2940 pObjectInfo->FileId.Unique,
2941 pObjectInfo->DataVersion.LowPart,
2942 pDirEnumEntry->DataVersion.LowPart
2945 bPurgeExtents = TRUE;
2948 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2951 bPurgeExtents = TRUE;
2953 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2954 AFS_TRACE_LEVEL_VERBOSE,
2955 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2956 &DirEntry->NameInformation.FileName,
2957 pObjectInfo->FileId.Cell,
2958 pObjectInfo->FileId.Volume,
2959 pObjectInfo->FileId.Vnode,
2960 pObjectInfo->FileId.Unique);
2962 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2965 if( pObjectInfo->Fcb != NULL)
2968 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2969 AFS_TRACE_LEVEL_VERBOSE,
2970 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2971 &DirEntry->NameInformation.FileName,
2972 pObjectInfo->FileId.Cell,
2973 pObjectInfo->FileId.Volume,
2974 pObjectInfo->FileId.Vnode,
2975 pObjectInfo->FileId.Unique);
2977 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2983 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2988 if( !NT_SUCCESS( stIoStatus.Status))
2991 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2992 AFS_TRACE_LEVEL_ERROR,
2993 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2994 &DirEntry->NameInformation.FileName,
2995 pObjectInfo->FileId.Cell,
2996 pObjectInfo->FileId.Volume,
2997 pObjectInfo->FileId.Vnode,
2998 pObjectInfo->FileId.Unique,
3000 stIoStatus.Information);
3002 ntStatus = stIoStatus.Status;
3005 if ( bPurgeExtents &&
3006 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3009 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3015 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3016 AFS_TRACE_LEVEL_WARNING,
3017 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3018 &DirEntry->NameInformation.FileName,
3019 pObjectInfo->FileId.Cell,
3020 pObjectInfo->FileId.Volume,
3021 pObjectInfo->FileId.Vnode,
3022 pObjectInfo->FileId.Unique);
3024 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3028 __except( EXCEPTION_EXECUTE_HANDLER)
3030 ntStatus = GetExceptionCode();
3034 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3035 &DirEntry->NameInformation.FileName,
3036 pObjectInfo->FileId.Cell,
3037 pObjectInfo->FileId.Volume,
3038 pObjectInfo->FileId.Vnode,
3039 pObjectInfo->FileId.Unique,
3042 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3045 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3049 AFSFlushExtents( pObjectInfo->Fcb,
3054 // Reacquire the Fcb to purge the cache
3057 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3058 AFS_TRACE_LEVEL_VERBOSE,
3059 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3060 &pObjectInfo->Fcb->NPFcb->Resource,
3061 PsGetCurrentThread());
3063 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3067 // Update the metadata for the entry
3070 ntStatus = AFSUpdateMetaData( DirEntry,
3073 if( !NT_SUCCESS( ntStatus))
3076 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3077 AFS_TRACE_LEVEL_ERROR,
3078 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3079 &DirEntry->NameInformation.FileName,
3080 pObjectInfo->FileId.Cell,
3081 pObjectInfo->FileId.Volume,
3082 pObjectInfo->FileId.Vnode,
3083 pObjectInfo->FileId.Unique,
3090 // Update file sizes
3093 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3094 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3095 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3097 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3098 AFS_TRACE_LEVEL_VERBOSE,
3099 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3100 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3101 PsGetCurrentThread());
3103 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3106 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3108 if ( pCCFileObject != NULL)
3110 CcSetFileSizes( pCCFileObject,
3111 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3114 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3115 AFS_TRACE_LEVEL_VERBOSE,
3116 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3117 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3118 PsGetCurrentThread());
3120 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3122 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3128 // Update the metadata for the entry
3131 ntStatus = AFSUpdateMetaData( DirEntry,
3134 if( !NT_SUCCESS( ntStatus))
3137 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3138 AFS_TRACE_LEVEL_ERROR,
3139 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3140 &DirEntry->NameInformation.FileName,
3141 pObjectInfo->FileId.Cell,
3142 pObjectInfo->FileId.Volume,
3143 pObjectInfo->FileId.Vnode,
3144 pObjectInfo->FileId.Unique,
3150 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3151 AFS_TRACE_LEVEL_WARNING,
3152 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3153 &DirEntry->NameInformation.FileName,
3154 pObjectInfo->FileId.Cell,
3155 pObjectInfo->FileId.Volume,
3156 pObjectInfo->FileId.Vnode,
3157 pObjectInfo->FileId.Unique);
3160 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3165 case AFS_FILE_TYPE_DIRECTORY:
3169 // For a directory or root entry flush the content of
3170 // the directory enumeration.
3173 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3176 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3177 AFS_TRACE_LEVEL_VERBOSE_2,
3178 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3179 &DirEntry->NameInformation.FileName,
3180 pObjectInfo->FileId.Cell,
3181 pObjectInfo->FileId.Volume,
3182 pObjectInfo->FileId.Vnode,
3183 pObjectInfo->FileId.Unique);
3185 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3188 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3191 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3193 if ( !NT_SUCCESS( ntStatus))
3196 try_return( ntStatus);
3201 // Update the metadata for the entry
3204 ntStatus = AFSUpdateMetaData( DirEntry,
3207 if( NT_SUCCESS( ntStatus))
3210 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3216 case AFS_FILE_TYPE_DFSLINK:
3219 UNICODE_STRING uniTargetName;
3222 // For a DFS link need to check the target name has not changed
3225 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3227 uniTargetName.MaximumLength = uniTargetName.Length;
3229 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3231 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3234 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3235 RtlCompareUnicodeString( &uniTargetName,
3236 &DirEntry->NameInformation.TargetName,
3241 // Update the target name