2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSGeneric.cpp
39 #include "AFSCommon.h"
42 // Function: AFSExceptionFilter
46 // This function is the exception handler
50 // A status is returned for the function
54 AFSExceptionFilter( IN CHAR *FunctionString,
56 IN PEXCEPTION_POINTERS ExceptPtrs)
59 UNREFERENCED_PARAMETER(Code);
60 PEXCEPTION_RECORD ExceptRec;
66 ExceptRec = ExceptPtrs->ExceptionRecord;
68 Context = ExceptPtrs->ContextRecord;
72 "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
76 ExceptRec->ExceptionCode,
77 ExceptRec->ExceptionAddress,
78 (void *)AFSExceptionFilter);
80 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
82 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
83 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
85 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
87 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
90 KeBugCheck( (ULONG)-2);
98 __except( EXCEPTION_EXECUTE_HANDLER)
104 return EXCEPTION_EXECUTE_HANDLER;
108 // Function: AFSLibExAllocatePoolWithTag()
110 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
111 // is configured on, then bugcheck the system if
112 // a memory allocation fails. The routine should be
113 // used for all memory allocations that are to be freed
114 // when the library is unloaded. Memory allocations that
115 // are to survive library unload and reload should be
116 // performed using AFSExAllocatePoolWithTag() which is
117 // provided by the AFS Framework.
120 // POOL_TYPE PoolType - Paged or NonPaged
121 // SIZE_T NumberOfBytes - requested allocation size
122 // ULONG Tag - Pool Allocation Tag to be applied for tracking
125 // void * - the memory allocation
129 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
130 IN SIZE_T NumberOfBytes,
134 void *pBuffer = NULL;
136 pBuffer = ExAllocatePoolWithTag( PoolType,
143 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
146 KeBugCheck( (ULONG)-2);
153 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
157 PsGetCurrentThread());
167 // Function: AFSAcquireExcl()
169 // Purpose: Called to acquire a resource exclusive with optional wait
172 // PERESOURCE Resource - Resource to acquire
173 // BOOLEAN Wait - Whether to block
176 // BOOLEAN - Whether the mask was acquired
180 AFSAcquireExcl( IN PERESOURCE Resource,
184 BOOLEAN bStatus = FALSE;
187 // Normal kernel APCs must be disabled before calling
188 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
191 KeEnterCriticalRegion();
193 bStatus = ExAcquireResourceExclusiveLite( Resource,
199 KeLeaveCriticalRegion();
206 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
210 BOOLEAN bStatus = FALSE;
212 KeEnterCriticalRegion();
214 bStatus = ExAcquireSharedStarveExclusive( Resource,
220 KeLeaveCriticalRegion();
227 // Function: AFSAcquireShared()
229 // Purpose: Called to acquire a resource shared with optional wait
232 // PERESOURCE Resource - Resource to acquire
233 // BOOLEAN Wait - Whether to block
236 // BOOLEAN - Whether the mask was acquired
240 AFSAcquireShared( IN PERESOURCE Resource,
244 BOOLEAN bStatus = FALSE;
246 KeEnterCriticalRegion();
248 bStatus = ExAcquireResourceSharedLite( Resource,
254 KeLeaveCriticalRegion();
261 // Function: AFSReleaseResource()
263 // Purpose: Called to release a resource
266 // PERESOURCE Resource - Resource to release
273 AFSReleaseResource( IN PERESOURCE Resource)
276 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
277 AFS_TRACE_LEVEL_VERBOSE,
278 "AFSReleaseResource Releasing lock %p Thread %08lX\n",
280 PsGetCurrentThread());
282 ExReleaseResourceLite( Resource);
284 KeLeaveCriticalRegion();
290 AFSConvertToShared( IN PERESOURCE Resource)
293 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
294 AFS_TRACE_LEVEL_VERBOSE,
295 "AFSConvertToShared Converting lock %p Thread %08lX\n",
297 PsGetCurrentThread());
299 ExConvertExclusiveToSharedLite( Resource);
305 // Function: AFSCompleteRequest
309 // This function completes irps
313 // A status is returned for the function
317 AFSCompleteRequest( IN PIRP Irp,
321 Irp->IoStatus.Status = Status;
323 IoCompleteRequest( Irp,
330 // Function: AFSGenerateCRC
334 // Given a device and filename this function generates a CRC
338 // A status is returned for the function
342 AFSGenerateCRC( IN PUNICODE_STRING FileName,
343 IN BOOLEAN UpperCaseName)
347 NTSTATUS ntStatus = STATUS_SUCCESS;
349 ntStatus = RtlHashUnicodeString( FileName,
351 HASH_STRING_ALGORITHM_DEFAULT,
354 if( !NT_SUCCESS( ntStatus))
363 AFSLockSystemBuffer( IN PIRP Irp,
367 void *pAddress = NULL;
369 if( Irp->MdlAddress != NULL)
372 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
375 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
378 pAddress = Irp->AssociatedIrp.SystemBuffer;
380 else if( Irp->UserBuffer != NULL)
383 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
389 if( Irp->MdlAddress != NULL)
393 // Lock the new Mdl in memory.
398 PIO_STACK_LOCATION pIoStack;
399 pIoStack = IoGetCurrentIrpStackLocation( Irp);
402 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
403 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
405 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
408 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
411 AFSDumpTraceFilesFnc();
413 IoFreeMdl( Irp->MdlAddress );
414 Irp->MdlAddress = NULL;
424 AFSLockUserBuffer( IN void *UserBuffer,
425 IN ULONG BufferLength,
429 NTSTATUS ntStatus = STATUS_SUCCESS;
430 void *pAddress = NULL;
436 pMdl = IoAllocateMdl( UserBuffer,
445 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
449 // Lock the new Mdl in memory.
455 MmProbeAndLockPages( pMdl,
459 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
462 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
465 AFSDumpTraceFilesFnc();
487 AFSMapToService( IN PIRP Irp,
491 NTSTATUS ntStatus = STATUS_SUCCESS;
492 void *pMappedBuffer = NULL;
493 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
499 if( pDevExt->Specific.Control.ServiceProcess == NULL)
502 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
505 if( Irp->MdlAddress == NULL)
508 if( AFSLockSystemBuffer( Irp,
512 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
517 // Attach to the service process for mapping
520 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
521 (PRKAPC_STATE)&stApcState);
523 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
530 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
537 return pMappedBuffer;
541 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
545 NTSTATUS ntStatus = STATUS_SUCCESS;
546 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
552 if( pDevExt->Specific.Control.ServiceProcess == NULL)
555 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
562 // Attach to the service process for mapping
565 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
566 (PRKAPC_STATE)&stApcState);
568 MmUnmapLockedPages( MappedBuffer,
571 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
583 AFSInitializeLibraryDevice()
586 NTSTATUS ntStatus = STATUS_SUCCESS;
587 AFSDeviceExt *pDeviceExt = NULL;
592 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
595 // The PIOCtl file name
598 RtlInitUnicodeString( &AFSPIOCtlName,
599 AFS_PIOCTL_FILE_INTERFACE_NAME);
602 // And the global root share name
605 RtlInitUnicodeString( &AFSGlobalRootName,
606 AFS_GLOBAL_ROOT_SHARE_NAME);
614 AFSRemoveLibraryDevice()
617 NTSTATUS ntStatus = STATUS_SUCCESS;
628 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
632 UNREFERENCED_PARAMETER(DeviceObject);
633 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
635 AFSCompleteRequest( Irp,
642 AFSInitializeGlobalDirectoryEntries()
645 NTSTATUS ntStatus = STATUS_SUCCESS;
646 AFSDirectoryCB *pDirNode = NULL;
647 ULONG ulEntryLength = 0;
648 AFSObjectInfoCB *pObjectInfoCB = NULL;
649 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
656 // Initialize the global . entry
659 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
662 if( pObjectInfoCB == NULL)
665 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
666 AFS_TRACE_LEVEL_ERROR,
667 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
670 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
673 lCount = AFSObjectInfoIncrement( pObjectInfoCB);
675 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
676 AFS_TRACE_LEVEL_VERBOSE,
677 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
681 ntStatus = STATUS_SUCCESS;
683 ulEntryLength = sizeof( AFSDirectoryCB) +
686 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
690 if( pDirNode == NULL)
693 AFSDeleteObjectInfo( pObjectInfoCB);
695 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
696 AFS_TRACE_LEVEL_ERROR,
697 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
699 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
702 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
703 sizeof( AFSNonPagedDirectoryCB),
704 AFS_DIR_ENTRY_NP_TAG);
706 if( pNonPagedDirEntry == NULL)
709 ExFreePool( pDirNode);
711 AFSDeleteObjectInfo( pObjectInfoCB);
713 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
714 AFS_TRACE_LEVEL_ERROR,
715 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
717 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
720 RtlZeroMemory( pDirNode,
723 RtlZeroMemory( pNonPagedDirEntry,
724 sizeof( AFSNonPagedDirectoryCB));
726 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
728 pDirNode->NonPaged = pNonPagedDirEntry;
730 pDirNode->ObjectInformation = pObjectInfoCB;
736 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
738 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
741 // Setup the names in the entry
744 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
746 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
748 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
750 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
753 // Populate the rest of the data
756 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
758 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
760 AFSGlobalDotDirEntry = pDirNode;
766 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
769 if( pObjectInfoCB == NULL)
772 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
773 AFS_TRACE_LEVEL_ERROR,
774 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
777 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
780 lCount = AFSObjectInfoIncrement( pObjectInfoCB);
782 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
783 AFS_TRACE_LEVEL_VERBOSE,
784 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
788 ntStatus = STATUS_SUCCESS;
790 ulEntryLength = sizeof( AFSDirectoryCB) +
791 ( 2 * sizeof( WCHAR));
793 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
797 if( pDirNode == NULL)
800 AFSDeleteObjectInfo( pObjectInfoCB);
802 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
805 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
806 sizeof( AFSNonPagedDirectoryCB),
807 AFS_DIR_ENTRY_NP_TAG);
809 if( pNonPagedDirEntry == NULL)
812 ExFreePool( pDirNode);
814 AFSDeleteObjectInfo( pObjectInfoCB);
816 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
819 RtlZeroMemory( pDirNode,
822 RtlZeroMemory( pNonPagedDirEntry,
823 sizeof( AFSNonPagedDirectoryCB));
825 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
827 pDirNode->NonPaged = pNonPagedDirEntry;
829 pDirNode->ObjectInformation = pObjectInfoCB;
835 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
837 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
840 // Setup the names in the entry
843 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
845 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
847 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
849 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
851 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
854 // Populate the rest of the data
857 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
859 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
861 AFSGlobalDotDotDirEntry = pDirNode;
865 if( !NT_SUCCESS( ntStatus))
868 if( AFSGlobalDotDirEntry != NULL)
871 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
873 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
875 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
877 ExFreePool( AFSGlobalDotDirEntry);
879 AFSGlobalDotDirEntry = NULL;
882 if( AFSGlobalDotDotDirEntry != NULL)
885 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
887 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
889 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
891 ExFreePool( AFSGlobalDotDotDirEntry);
893 AFSGlobalDotDotDirEntry = NULL;
902 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
903 IN PUNICODE_STRING FileName,
904 IN PUNICODE_STRING TargetName,
905 IN AFSDirEnumEntry *DirEnumEntry,
909 AFSDirectoryCB *pDirNode = NULL;
910 NTSTATUS ntStatus = STATUS_SUCCESS;
911 ULONG ulEntryLength = 0;
912 AFSObjectInfoCB *pObjectInfoCB = NULL;
913 BOOLEAN bAllocatedObjectCB = FALSE;
914 ULONGLONG ullIndex = 0;
915 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
921 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
922 AFS_TRACE_LEVEL_VERBOSE,
923 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
925 ParentObjectInfo->FileId.Cell,
926 ParentObjectInfo->FileId.Volume,
927 ParentObjectInfo->FileId.Vnode,
928 ParentObjectInfo->FileId.Unique);
931 // First thing is to locate/create our object information block
935 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
938 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
940 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
942 (AFSBTreeEntry **)&pObjectInfoCB);
944 if( !NT_SUCCESS( ntStatus) ||
945 pObjectInfoCB == NULL)
949 // Allocate our object info cb
952 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
955 if( pObjectInfoCB == NULL)
958 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
960 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
963 bAllocatedObjectCB = TRUE;
965 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
966 AFS_TRACE_LEVEL_VERBOSE,
967 "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
973 lCount = AFSObjectInfoIncrement( pObjectInfoCB);
975 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
976 AFS_TRACE_LEVEL_VERBOSE,
977 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
981 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
983 ntStatus = STATUS_SUCCESS;
985 ulEntryLength = sizeof( AFSDirectoryCB) +
988 if( TargetName != NULL)
991 ulEntryLength += TargetName->Length;
994 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
998 if( pDirNode == NULL)
1001 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1004 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1005 sizeof( AFSNonPagedDirectoryCB),
1006 AFS_DIR_ENTRY_NP_TAG);
1008 if( pNonPagedDirEntry == NULL)
1011 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1014 RtlZeroMemory( pDirNode,
1017 RtlZeroMemory( pNonPagedDirEntry,
1018 sizeof( AFSNonPagedDirectoryCB));
1020 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1022 pDirNode->NonPaged = pNonPagedDirEntry;
1024 pDirNode->ObjectInformation = pObjectInfoCB;
1027 // Set valid entry and NOT_IN_PARENT flag
1030 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1032 pDirNode->FileIndex = FileIndex;
1035 // Setup the names in the entry
1038 if( FileName->Length > 0)
1041 pDirNode->NameInformation.FileName.Length = FileName->Length;
1043 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1045 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1047 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1049 pDirNode->NameInformation.FileName.Length);
1052 // Create a CRC for the file
1055 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1058 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1062 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1063 AFS_TRACE_LEVEL_VERBOSE,
1064 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1067 ParentObjectInfo->FileId.Cell,
1068 ParentObjectInfo->FileId.Volume,
1069 ParentObjectInfo->FileId.Vnode,
1070 ParentObjectInfo->FileId.Unique);
1072 if( TargetName != NULL &&
1073 TargetName->Length > 0)
1076 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1078 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1080 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1081 sizeof( AFSDirectoryCB) +
1082 pDirNode->NameInformation.FileName.Length);
1084 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1086 pDirNode->NameInformation.TargetName.Length);
1090 // If we allocated the object information cb then update the information
1093 if( bAllocatedObjectCB)
1097 // Populate the rest of the data
1100 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1102 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1104 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1106 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1108 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1110 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1112 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1114 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1116 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1118 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1120 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1123 pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1126 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1127 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1130 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1133 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1136 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1137 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1141 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1142 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1143 pObjectInfoCB->TargetFileId.Unique == 0 &&
1144 pDirNode->NameInformation.TargetName.Length == 0)
1148 // This will ensure we perform a validation on the node
1151 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1154 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1157 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1162 // Object specific information
1165 pObjectInfoCB->Links = DirEnumEntry->Links;
1167 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1169 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1173 if( !NT_SUCCESS( ntStatus))
1176 if( pNonPagedDirEntry != NULL)
1179 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1181 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1184 if( pDirNode != NULL)
1187 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1193 // Dereference our object info block if we have one
1196 if( pObjectInfoCB != NULL)
1199 lCount = AFSObjectInfoDecrement( pObjectInfoCB);
1201 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1202 AFS_TRACE_LEVEL_VERBOSE,
1203 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1207 if( bAllocatedObjectCB)
1210 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1212 AFSDeleteObjectInfo( pObjectInfoCB);
1222 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1223 IN BOOLEAN DirectoryEntry)
1226 BOOLEAN bReturn = TRUE;
1227 ACCESS_MASK stAccessMask = 0;
1230 // Get rid of anything we don't know about
1233 DesiredAccess = (DesiredAccess &
1239 ACCESS_SYSTEM_SECURITY |
1243 FILE_READ_ATTRIBUTES |
1244 FILE_WRITE_ATTRIBUTES |
1245 FILE_LIST_DIRECTORY |
1251 // Our 'read only' access mask. These are the accesses we will
1252 // allow for a read only file
1255 stAccessMask = DELETE |
1260 ACCESS_SYSTEM_SECURITY |
1264 FILE_READ_ATTRIBUTES |
1265 FILE_WRITE_ATTRIBUTES |
1267 FILE_LIST_DIRECTORY |
1271 // For a directory, add in the directory specific accesses
1277 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1282 if( FlagOn( DesiredAccess, ~stAccessMask))
1286 // A write access is set ...
1296 AFSEvaluateNode( IN GUID *AuthGroup,
1297 IN AFSDirectoryCB *DirEntry)
1300 NTSTATUS ntStatus = STATUS_SUCCESS;
1301 AFSDirEnumEntry *pDirEntry = NULL;
1302 UNICODE_STRING uniTargetName;
1307 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1312 if( !NT_SUCCESS( ntStatus))
1315 try_return( ntStatus);
1318 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1320 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1322 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1324 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1326 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1328 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1330 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1332 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1334 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1336 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1338 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1340 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1343 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1346 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1347 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1350 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1353 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1355 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1358 // If we have a target name then see if it needs updating ...
1361 if( pDirEntry->TargetNameLength > 0)
1365 // Update the target name information if needed
1368 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1370 uniTargetName.MaximumLength = uniTargetName.Length;
1372 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1374 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1377 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1378 RtlCompareUnicodeString( &uniTargetName,
1379 &DirEntry->NameInformation.TargetName,
1384 // Update the target name
1387 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1389 uniTargetName.Buffer,
1390 uniTargetName.Length);
1392 if( !NT_SUCCESS( ntStatus))
1395 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1397 try_return( ntStatus);
1401 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1406 if( pDirEntry != NULL)
1409 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1417 AFSValidateSymLink( IN GUID *AuthGroup,
1418 IN AFSDirectoryCB *DirEntry)
1421 NTSTATUS ntStatus = STATUS_SUCCESS;
1422 AFSDirEnumEntry *pDirEntry = NULL;
1423 UNICODE_STRING uniTargetName;
1428 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1433 if( !NT_SUCCESS( ntStatus))
1436 try_return( ntStatus);
1439 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1440 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1443 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1446 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1448 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1450 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1453 // Update the target name information if needed
1456 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1458 uniTargetName.MaximumLength = uniTargetName.Length;
1460 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1462 if( uniTargetName.Length > 0)
1465 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1468 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1469 RtlCompareUnicodeString( &uniTargetName,
1470 &DirEntry->NameInformation.TargetName,
1475 // Update the target name
1478 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1480 uniTargetName.Buffer,
1481 uniTargetName.Length);
1483 if( !NT_SUCCESS( ntStatus))
1486 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1488 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1492 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1496 // If the FileType is the same then nothing to do since it IS
1500 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1503 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1505 try_return( ntStatus = STATUS_SUCCESS);
1508 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1510 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1512 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1514 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1516 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1518 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1520 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1522 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1524 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1527 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1530 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1531 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1534 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1537 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1539 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1543 if( pDirEntry != NULL)
1546 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1554 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1558 NTSTATUS ntStatus = STATUS_SUCCESS;
1559 IO_STATUS_BLOCK stIoStatus;
1562 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1563 AFS_TRACE_LEVEL_VERBOSE,
1564 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1565 (*ppObjectInfo)->FileType,
1566 (*ppObjectInfo)->FileId.Cell,
1567 (*ppObjectInfo)->FileId.Volume,
1568 (*ppObjectInfo)->FileId.Vnode,
1569 (*ppObjectInfo)->FileId.Unique,
1572 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1573 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1574 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1577 // We only act on the mount point itself, not the target. If the
1578 // node has been deleted then mark it as such otherwise indicate
1579 // it requires verification
1582 if( Reason == AFS_INVALIDATE_DELETED)
1584 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1589 if( Reason == AFS_INVALIDATE_FLUSHED)
1592 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1594 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1597 (*ppObjectInfo)->Expiration.QuadPart = 0;
1599 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1601 (*ppObjectInfo)->TargetFileId.Unique = 0;
1603 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1604 AFS_TRACE_LEVEL_VERBOSE,
1605 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1606 (*ppObjectInfo)->FileId.Cell,
1607 (*ppObjectInfo)->FileId.Volume,
1608 (*ppObjectInfo)->FileId.Vnode,
1609 (*ppObjectInfo)->FileId.Unique);
1611 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1614 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1616 if( Reason == AFS_INVALIDATE_CREDS)
1618 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1621 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1622 Reason == AFS_INVALIDATE_FLUSHED)
1624 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1628 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1631 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1634 FILE_ACTION_MODIFIED);
1636 try_return( ntStatus);
1640 // Depending on the reason for invalidation then perform work on the node
1646 case AFS_INVALIDATE_DELETED:
1650 // Mark this node as invalid
1653 (*ppObjectInfo)->Links = 0;
1655 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1657 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1658 AFS_TRACE_LEVEL_VERBOSE,
1659 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1660 (*ppObjectInfo)->FileId.Cell,
1661 (*ppObjectInfo)->FileId.Volume,
1662 (*ppObjectInfo)->FileId.Vnode,
1663 (*ppObjectInfo)->FileId.Unique);
1665 if( (*ppObjectInfo)->ParentObjectInformation != NULL)
1668 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1669 AFS_TRACE_LEVEL_VERBOSE,
1670 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1671 (*ppObjectInfo)->ParentObjectInformation->FileId.Cell,
1672 (*ppObjectInfo)->ParentObjectInformation->FileId.Volume,
1673 (*ppObjectInfo)->ParentObjectInformation->FileId.Vnode,
1674 (*ppObjectInfo)->ParentObjectInformation->FileId.Unique);
1676 SetFlag( (*ppObjectInfo)->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1678 (*ppObjectInfo)->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1680 (*ppObjectInfo)->ParentObjectInformation->Expiration.QuadPart = 0;
1683 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1685 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1689 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1692 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1695 FILE_ACTION_REMOVED);
1697 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1700 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1706 case AFS_INVALIDATE_FLUSHED:
1709 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1710 (*ppObjectInfo)->Fcb != NULL)
1713 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1714 AFS_TRACE_LEVEL_VERBOSE,
1715 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1716 (*ppObjectInfo)->FileId.Cell,
1717 (*ppObjectInfo)->FileId.Volume,
1718 (*ppObjectInfo)->FileId.Vnode,
1719 (*ppObjectInfo)->FileId.Unique);
1721 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1727 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1732 if( !NT_SUCCESS( stIoStatus.Status))
1735 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1736 AFS_TRACE_LEVEL_ERROR,
1737 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1738 (*ppObjectInfo)->FileId.Cell,
1739 (*ppObjectInfo)->FileId.Volume,
1740 (*ppObjectInfo)->FileId.Vnode,
1741 (*ppObjectInfo)->FileId.Unique,
1743 stIoStatus.Information);
1745 ntStatus = stIoStatus.Status;
1749 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1752 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1758 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1759 AFS_TRACE_LEVEL_WARNING,
1760 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1761 (*ppObjectInfo)->FileId.Cell,
1762 (*ppObjectInfo)->FileId.Volume,
1763 (*ppObjectInfo)->FileId.Vnode,
1764 (*ppObjectInfo)->FileId.Unique);
1766 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1770 __except( EXCEPTION_EXECUTE_HANDLER)
1773 ntStatus = GetExceptionCode();
1777 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1778 (*ppObjectInfo)->FileId.Cell,
1779 (*ppObjectInfo)->FileId.Volume,
1780 (*ppObjectInfo)->FileId.Vnode,
1781 (*ppObjectInfo)->FileId.Unique,
1784 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1787 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1790 // Clear out the extents
1791 // Get rid of them (note this involves waiting
1792 // for any writes or reads to the cache to complete)
1795 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1799 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1802 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1805 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1806 AFS_TRACE_LEVEL_VERBOSE,
1807 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1808 (*ppObjectInfo)->FileId.Cell,
1809 (*ppObjectInfo)->FileId.Volume,
1810 (*ppObjectInfo)->FileId.Vnode,
1811 (*ppObjectInfo)->FileId.Unique);
1813 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1816 // Fall through to the default processing
1822 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1824 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1828 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1831 if( Reason == AFS_INVALIDATE_CREDS)
1833 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1836 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1838 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1842 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1845 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1848 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1851 FILE_ACTION_MODIFIED);
1856 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1859 FILE_ACTION_MODIFIED);
1863 // Indicate this node requires re-evaluation for the remaining reasons
1866 (*ppObjectInfo)->Expiration.QuadPart = 0;
1868 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1869 AFS_TRACE_LEVEL_VERBOSE,
1870 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1871 (*ppObjectInfo)->FileId.Cell,
1872 (*ppObjectInfo)->FileId.Volume,
1873 (*ppObjectInfo)->FileId.Vnode,
1874 (*ppObjectInfo)->FileId.Unique);
1876 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1878 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1879 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1880 ( Reason == AFS_INVALIDATE_CALLBACK ||
1881 Reason == AFS_INVALIDATE_EXPIRED))
1883 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1884 AFS_INVALIDATE_DATA_VERSION)))
1887 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1901 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1904 NTSTATUS ntStatus = STATUS_SUCCESS;
1905 AFSVolumeCB *pVolumeCB = NULL;
1906 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1907 ULONGLONG ullIndex = 0;
1908 AFSObjectInfoCB *pObjectInfo = NULL;
1914 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1915 AFS_TRACE_LEVEL_VERBOSE,
1916 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1917 InvalidateCB->FileID.Cell,
1918 InvalidateCB->FileID.Volume,
1919 InvalidateCB->FileID.Vnode,
1920 InvalidateCB->FileID.Unique,
1921 InvalidateCB->FileType,
1922 InvalidateCB->WholeVolume,
1923 InvalidateCB->Reason);
1926 // Need to locate the Fcb for the directory to purge
1929 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1930 AFS_TRACE_LEVEL_VERBOSE,
1931 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
1932 &pDevExt->Specific.RDR.VolumeTreeLock,
1933 PsGetCurrentThread());
1936 // Starve any exclusive waiters on this paticular call
1939 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1942 // Locate the volume node
1945 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1947 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1949 (AFSBTreeEntry **)&pVolumeCB);
1951 if( pVolumeCB != NULL)
1954 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1956 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1957 AFS_TRACE_LEVEL_VERBOSE,
1958 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
1963 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1965 if( !NT_SUCCESS( ntStatus) ||
1969 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1970 AFS_TRACE_LEVEL_WARNING,
1971 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1972 InvalidateCB->FileID.Cell,
1973 InvalidateCB->FileID.Volume,
1974 InvalidateCB->FileID.Vnode,
1975 InvalidateCB->FileID.Unique,
1978 try_return( ntStatus = STATUS_SUCCESS);
1982 // If this is a whole volume invalidation then go do it now
1985 if( InvalidateCB->WholeVolume)
1988 ntStatus = AFSInvalidateVolume( pVolumeCB,
1989 InvalidateCB->Reason);
1991 try_return( ntStatus);
1994 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1997 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2000 pObjectInfo = &pVolumeCB->ObjectInformation;
2005 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2007 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2009 (AFSBTreeEntry **)&pObjectInfo);
2012 if( pObjectInfo != NULL)
2016 // Reference the node so it won't be torn down
2019 lCount = AFSObjectInfoIncrement( pObjectInfo);
2021 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2022 AFS_TRACE_LEVEL_VERBOSE,
2023 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2028 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2030 if( !NT_SUCCESS( ntStatus) ||
2031 pObjectInfo == NULL)
2034 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2035 AFS_TRACE_LEVEL_VERBOSE,
2036 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2037 InvalidateCB->FileID.Cell,
2038 InvalidateCB->FileID.Volume,
2039 InvalidateCB->FileID.Vnode,
2040 InvalidateCB->FileID.Unique,
2043 try_return( ntStatus = STATUS_SUCCESS);
2046 AFSInvalidateObject( &pObjectInfo,
2047 InvalidateCB->Reason);
2051 if( pObjectInfo != NULL)
2054 lCount = AFSObjectInfoDecrement( pObjectInfo);
2056 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2057 AFS_TRACE_LEVEL_VERBOSE,
2058 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2063 if ( pVolumeCB != NULL)
2066 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2068 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2069 AFS_TRACE_LEVEL_VERBOSE,
2070 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2080 AFSIsChildOfParent( IN AFSFcb *Dcb,
2084 BOOLEAN bIsChild = FALSE;
2085 AFSFcb *pCurrentFcb = Fcb;
2087 while( pCurrentFcb != NULL)
2090 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2098 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2106 AFSCreateHighIndex( IN AFSFileID *FileID)
2109 ULONGLONG ullIndex = 0;
2111 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2118 AFSCreateLowIndex( IN AFSFileID *FileID)
2121 ULONGLONG ullIndex = 0;
2123 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2129 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2130 IN ACCESS_MASK GrantedAccess,
2131 IN BOOLEAN DirectoryEntry)
2134 BOOLEAN bAccessGranted = TRUE;
2137 // Check if we are asking for read/write and granted only read only
2138 // NOTE: There will be more checks here
2141 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2143 AFSCheckForReadOnlyAccess( GrantedAccess,
2147 bAccessGranted = FALSE;
2150 return bAccessGranted;
2154 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2157 NTSTATUS ntStatus = STATUS_SUCCESS;
2158 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2164 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2166 if( AFSGlobalRoot == NULL)
2173 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2176 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2183 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2190 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2191 IN UNICODE_STRING *SubstituteName,
2192 IN ULONG StringIndex)
2195 NTSTATUS ntStatus = STATUS_SUCCESS;
2196 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2197 AFSSysNameCB *pSysName = NULL;
2198 ERESOURCE *pSysNameLock = NULL;
2201 UNICODE_STRING uniSysName;
2208 if( IoIs32bitProcess( NULL))
2211 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2213 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2218 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2220 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2224 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2226 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2230 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2231 AFS_TRACE_LEVEL_VERBOSE,
2232 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2234 PsGetCurrentThread());
2236 AFSAcquireShared( pSysNameLock,
2240 // Find where we are in the list
2243 while( pSysName != NULL &&
2244 ulIndex < StringIndex)
2247 pSysName = pSysName->fLink;
2252 if( pSysName == NULL)
2255 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2258 RtlInitUnicodeString( &uniSysName,
2261 // If it is a full component of @SYS then just substitue the
2265 if( RtlCompareUnicodeString( &uniSysName,
2270 SubstituteName->Length = pSysName->SysName.Length;
2271 SubstituteName->MaximumLength = SubstituteName->Length;
2273 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2274 SubstituteName->Length,
2275 AFS_SUBST_BUFFER_TAG);
2277 if( SubstituteName->Buffer == NULL)
2280 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2283 RtlCopyMemory( SubstituteName->Buffer,
2284 pSysName->SysName.Buffer,
2285 pSysName->SysName.Length);
2292 while( ComponentName->Buffer[ usIndex] != L'@')
2298 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2299 SubstituteName->MaximumLength = SubstituteName->Length;
2301 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2302 SubstituteName->Length,
2303 AFS_SUBST_BUFFER_TAG);
2305 if( SubstituteName->Buffer == NULL)
2308 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2311 RtlCopyMemory( SubstituteName->Buffer,
2312 ComponentName->Buffer,
2313 usIndex * sizeof( WCHAR));
2315 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2316 pSysName->SysName.Buffer,
2317 pSysName->SysName.Length);
2322 AFSReleaseResource( pSysNameLock);
2329 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2330 IN OUT UNICODE_STRING *ComponentName,
2331 IN UNICODE_STRING *SubstituteName,
2332 IN OUT UNICODE_STRING *RemainingPath,
2333 IN BOOLEAN FreePathName)
2336 NTSTATUS ntStatus = STATUS_SUCCESS;
2337 UNICODE_STRING uniPathName;
2338 USHORT usPrefixNameLen = 0;
2339 SHORT sNameLenDelta = 0;
2345 // If the passed in name can handle the additional length
2346 // then just moves things around
2349 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2351 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2353 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2356 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2359 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2360 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2361 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2364 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2365 SubstituteName->Buffer,
2366 SubstituteName->Length);
2368 FullPathName->Length += sNameLenDelta;
2370 ComponentName->Length += sNameLenDelta;
2372 ComponentName->MaximumLength = ComponentName->Length;
2374 if ( RemainingPath->Buffer)
2377 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2380 try_return( ntStatus);
2384 // Need to re-allocate the buffer
2387 uniPathName.Length = FullPathName->Length -
2388 ComponentName->Length +
2389 SubstituteName->Length;
2391 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2393 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2394 uniPathName.MaximumLength,
2395 AFS_NAME_BUFFER_FOUR_TAG);
2397 if( uniPathName.Buffer == NULL)
2400 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2403 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2405 usPrefixNameLen *= sizeof( WCHAR);
2407 RtlZeroMemory( uniPathName.Buffer,
2408 uniPathName.MaximumLength);
2410 RtlCopyMemory( uniPathName.Buffer,
2411 FullPathName->Buffer,
2414 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2415 SubstituteName->Buffer,
2416 SubstituteName->Length);
2418 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2421 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2422 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2423 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2426 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2428 ComponentName->Length += sNameLenDelta;
2430 ComponentName->MaximumLength = ComponentName->Length;
2432 if ( RemainingPath->Buffer)
2435 RemainingPath->Buffer = uniPathName.Buffer
2436 + (RemainingPath->Buffer - FullPathName->Buffer)
2437 + sNameLenDelta/sizeof( WCHAR);
2442 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2445 *FullPathName = uniPathName;
2456 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2460 NTSTATUS ntStatus = STATUS_SUCCESS;
2461 AFSObjectInfoCB *pCurrentObject = NULL;
2462 AFSObjectInfoCB *pNextObject = NULL;
2468 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2469 AFS_TRACE_LEVEL_VERBOSE,
2470 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2471 VolumeCB->ObjectInformation.FileId.Cell,
2472 VolumeCB->ObjectInformation.FileId.Volume,
2473 VolumeCB->ObjectInformation.FileId.Vnode,
2474 VolumeCB->ObjectInformation.FileId.Unique,
2478 // Depending on the reason for invalidation then perform work on the node
2484 case AFS_INVALIDATE_DELETED:
2488 // Mark this volume as invalid
2491 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2493 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2500 // Invalidate the volume root directory
2503 pCurrentObject = &VolumeCB->ObjectInformation;
2505 if ( pCurrentObject )
2508 lCount = AFSObjectInfoIncrement( pCurrentObject);
2510 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2511 AFS_TRACE_LEVEL_VERBOSE,
2512 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2516 AFSInvalidateObject( &pCurrentObject,
2519 if ( pCurrentObject)
2522 lCount = AFSObjectInfoDecrement( pCurrentObject);
2524 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2525 AFS_TRACE_LEVEL_VERBOSE,
2526 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2533 // Apply invalidation to all other volume objects
2536 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2539 pCurrentObject = VolumeCB->ObjectInfoListHead;
2541 if ( pCurrentObject)
2545 // Reference the node so it won't be torn down
2548 lCount = AFSObjectInfoIncrement( pCurrentObject);
2550 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2551 AFS_TRACE_LEVEL_VERBOSE,
2552 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2557 while( pCurrentObject != NULL)
2560 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2566 // Reference the node so it won't be torn down
2569 lCount = AFSObjectInfoIncrement( pNextObject);
2571 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2572 AFS_TRACE_LEVEL_VERBOSE,
2573 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2578 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2580 AFSInvalidateObject( &pCurrentObject,
2583 if ( pCurrentObject )
2586 lCount = AFSObjectInfoDecrement( pCurrentObject);
2588 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2589 AFS_TRACE_LEVEL_VERBOSE,
2590 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2595 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2598 pCurrentObject = pNextObject;
2601 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2608 AFSInvalidateAllVolumes( VOID)
2610 AFSVolumeCB *pVolumeCB = NULL;
2611 AFSVolumeCB *pNextVolumeCB = NULL;
2612 AFSDeviceExt *pRDRDeviceExt = NULL;
2615 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2617 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2618 AFS_TRACE_LEVEL_VERBOSE,
2619 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2620 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2621 PsGetCurrentThread());
2623 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2626 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2631 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2632 AFS_TRACE_LEVEL_VERBOSE,
2633 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2634 pVolumeCB->ObjectInfoTree.TreeLock,
2635 PsGetCurrentThread());
2637 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
2639 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2640 AFS_TRACE_LEVEL_VERBOSE,
2641 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2646 while( pVolumeCB != NULL)
2649 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2654 lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
2656 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2657 AFS_TRACE_LEVEL_VERBOSE,
2658 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2663 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2665 // do I need to hold the volume lock here?
2667 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2669 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2672 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2674 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2675 AFS_TRACE_LEVEL_VERBOSE,
2676 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2680 pVolumeCB = pNextVolumeCB;
2683 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2687 AFSVerifyEntry( IN GUID *AuthGroup,
2688 IN AFSDirectoryCB *DirEntry)
2691 NTSTATUS ntStatus = STATUS_SUCCESS;
2692 AFSDirEnumEntry *pDirEnumEntry = NULL;
2693 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2694 IO_STATUS_BLOCK stIoStatus;
2699 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2700 AFS_TRACE_LEVEL_VERBOSE_2,
2701 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2702 &DirEntry->NameInformation.FileName,
2703 pObjectInfo->FileId.Cell,
2704 pObjectInfo->FileId.Volume,
2705 pObjectInfo->FileId.Vnode,
2706 pObjectInfo->FileId.Unique);
2708 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2713 if( !NT_SUCCESS( ntStatus))
2716 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2717 AFS_TRACE_LEVEL_ERROR,
2718 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2719 &DirEntry->NameInformation.FileName,
2720 pObjectInfo->FileId.Cell,
2721 pObjectInfo->FileId.Volume,
2722 pObjectInfo->FileId.Vnode,
2723 pObjectInfo->FileId.Unique,
2726 try_return( ntStatus);
2730 // Check the data version of the file
2733 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2735 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2738 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2739 AFS_TRACE_LEVEL_VERBOSE,
2740 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2741 pObjectInfo->DataVersion.QuadPart,
2742 &DirEntry->NameInformation.FileName,
2743 pObjectInfo->FileId.Cell,
2744 pObjectInfo->FileId.Volume,
2745 pObjectInfo->FileId.Vnode,
2746 pObjectInfo->FileId.Unique);
2749 // We are ok, just get out
2752 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2754 try_return( ntStatus = STATUS_SUCCESS);
2759 // New data version so we will need to process the node based on the type
2762 switch( pDirEnumEntry->FileType)
2765 case AFS_FILE_TYPE_MOUNTPOINT:
2769 // For a mount point we need to ensure the target is the same
2772 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2773 &pDirEnumEntry->TargetFileId))
2779 // Update the metadata for the entry
2782 ntStatus = AFSUpdateMetaData( DirEntry,
2785 if( NT_SUCCESS( ntStatus))
2788 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2794 case AFS_FILE_TYPE_SYMLINK:
2798 // Update the metadata for the entry
2801 ntStatus = AFSUpdateMetaData( DirEntry,
2804 if( NT_SUCCESS( ntStatus))
2807 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2813 case AFS_FILE_TYPE_FILE:
2815 FILE_OBJECT * pCCFileObject = NULL;
2816 BOOLEAN bPurgeExtents = FALSE;
2818 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
2821 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2822 AFS_TRACE_LEVEL_VERBOSE,
2823 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
2824 &DirEntry->NameInformation.FileName,
2825 pObjectInfo->FileId.Cell,
2826 pObjectInfo->FileId.Volume,
2827 pObjectInfo->FileId.Vnode,
2828 pObjectInfo->FileId.Unique,
2829 pObjectInfo->DataVersion.LowPart,
2830 pDirEnumEntry->DataVersion.LowPart
2833 bPurgeExtents = TRUE;
2836 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2839 bPurgeExtents = TRUE;
2841 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2842 AFS_TRACE_LEVEL_VERBOSE,
2843 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2844 &DirEntry->NameInformation.FileName,
2845 pObjectInfo->FileId.Cell,
2846 pObjectInfo->FileId.Volume,
2847 pObjectInfo->FileId.Vnode,
2848 pObjectInfo->FileId.Unique);
2850 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2853 if( pObjectInfo->Fcb != NULL)
2856 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2857 AFS_TRACE_LEVEL_VERBOSE,
2858 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2859 &DirEntry->NameInformation.FileName,
2860 pObjectInfo->FileId.Cell,
2861 pObjectInfo->FileId.Volume,
2862 pObjectInfo->FileId.Vnode,
2863 pObjectInfo->FileId.Unique);
2865 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2871 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2876 if( !NT_SUCCESS( stIoStatus.Status))
2879 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2880 AFS_TRACE_LEVEL_ERROR,
2881 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2882 &DirEntry->NameInformation.FileName,
2883 pObjectInfo->FileId.Cell,
2884 pObjectInfo->FileId.Volume,
2885 pObjectInfo->FileId.Vnode,
2886 pObjectInfo->FileId.Unique,
2888 stIoStatus.Information);
2890 ntStatus = stIoStatus.Status;
2893 if ( bPurgeExtents &&
2894 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2897 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2903 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2904 AFS_TRACE_LEVEL_WARNING,
2905 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2906 &DirEntry->NameInformation.FileName,
2907 pObjectInfo->FileId.Cell,
2908 pObjectInfo->FileId.Volume,
2909 pObjectInfo->FileId.Vnode,
2910 pObjectInfo->FileId.Unique);
2912 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2916 __except( EXCEPTION_EXECUTE_HANDLER)
2918 ntStatus = GetExceptionCode();
2922 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2923 &DirEntry->NameInformation.FileName,
2924 pObjectInfo->FileId.Cell,
2925 pObjectInfo->FileId.Volume,
2926 pObjectInfo->FileId.Vnode,
2927 pObjectInfo->FileId.Unique,
2930 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2933 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
2937 AFSFlushExtents( pObjectInfo->Fcb,
2942 // Reacquire the Fcb to purge the cache
2945 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2946 AFS_TRACE_LEVEL_VERBOSE,
2947 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
2948 &pObjectInfo->Fcb->NPFcb->Resource,
2949 PsGetCurrentThread());
2951 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2955 // Update the metadata for the entry
2958 ntStatus = AFSUpdateMetaData( DirEntry,
2961 if( !NT_SUCCESS( ntStatus))
2964 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2965 AFS_TRACE_LEVEL_ERROR,
2966 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2967 &DirEntry->NameInformation.FileName,
2968 pObjectInfo->FileId.Cell,
2969 pObjectInfo->FileId.Volume,
2970 pObjectInfo->FileId.Vnode,
2971 pObjectInfo->FileId.Unique,
2978 // Update file sizes
2981 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2982 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2983 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2985 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2986 AFS_TRACE_LEVEL_VERBOSE,
2987 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2988 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2989 PsGetCurrentThread());
2991 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2994 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2996 if ( pCCFileObject != NULL)
2998 CcSetFileSizes( pCCFileObject,
2999 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3002 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3003 AFS_TRACE_LEVEL_VERBOSE,
3004 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3005 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3006 PsGetCurrentThread());
3008 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3010 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3016 // Update the metadata for the entry
3019 ntStatus = AFSUpdateMetaData( DirEntry,
3022 if( !NT_SUCCESS( ntStatus))
3025 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3026 AFS_TRACE_LEVEL_ERROR,
3027 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3028 &DirEntry->NameInformation.FileName,
3029 pObjectInfo->FileId.Cell,
3030 pObjectInfo->FileId.Volume,
3031 pObjectInfo->FileId.Vnode,
3032 pObjectInfo->FileId.Unique,
3038 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3039 AFS_TRACE_LEVEL_WARNING,
3040 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3041 &DirEntry->NameInformation.FileName,
3042 pObjectInfo->FileId.Cell,
3043 pObjectInfo->FileId.Volume,
3044 pObjectInfo->FileId.Vnode,
3045 pObjectInfo->FileId.Unique);
3048 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3053 case AFS_FILE_TYPE_DIRECTORY:
3057 // For a directory or root entry flush the content of
3058 // the directory enumeration.
3061 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3064 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3065 AFS_TRACE_LEVEL_VERBOSE_2,
3066 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3067 &DirEntry->NameInformation.FileName,
3068 pObjectInfo->FileId.Cell,
3069 pObjectInfo->FileId.Volume,
3070 pObjectInfo->FileId.Vnode,
3071 pObjectInfo->FileId.Unique);
3073 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3076 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3079 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3081 if ( !NT_SUCCESS( ntStatus))
3084 try_return( ntStatus);
3089 // Update the metadata for the entry
3092 ntStatus = AFSUpdateMetaData( DirEntry,
3095 if( NT_SUCCESS( ntStatus))
3098 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3104 case AFS_FILE_TYPE_DFSLINK:
3107 UNICODE_STRING uniTargetName;
3110 // For a DFS link need to check the target name has not changed
3113 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3115 uniTargetName.MaximumLength = uniTargetName.Length;
3117 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3119 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3122 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3123 RtlCompareUnicodeString( &uniTargetName,
3124 &DirEntry->NameInformation.TargetName,
3129 // Update the target name
3132 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3134 uniTargetName.Buffer,
3135 uniTargetName.Length);
3137 if( !NT_SUCCESS( ntStatus))
3140 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3146 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3149 // Update the metadata for the entry
3152 ntStatus = AFSUpdateMetaData( DirEntry,
3155 if( NT_SUCCESS( ntStatus))
3158 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3166 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3167 AFS_TRACE_LEVEL_WARNING,
3168 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3169 pObjectInfo->FileType,
3170 &DirEntry->NameInformation.FileName,
3171 pObjectInfo->FileId.Cell,
3172 pObjectInfo->FileId.Volume,
3173 pObjectInfo->FileId.Vnode,
3174 pObjectInfo->FileId.Unique);
3181 if( pDirEnumEntry != NULL)
3184 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3192 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3195 NTSTATUS ntStatus = STATUS_SUCCESS;
3196 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3197 ULONGLONG ullIndex = 0;
3198 AFSVolumeCB *pVolumeCB = NULL;
3204 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3205 AFS_TRACE_LEVEL_VERBOSE,
3206 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3207 VolumeStatus->Online,
3208 VolumeStatus->FileID.Cell,
3209 VolumeStatus->FileID.Volume);
3212 // Need to locate the Fcb for the directory to purge
3215 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3216 AFS_TRACE_LEVEL_VERBOSE,
3217 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3218 &pDevExt->Specific.RDR.VolumeTreeLock,
3219 PsGetCurrentThread());
3221 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3224 // Locate the volume node
3227 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3229 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3231 (AFSBTreeEntry **)&pVolumeCB);
3233 if( pVolumeCB != NULL)
3236 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3238 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3239 AFS_TRACE_LEVEL_VERBOSE,
3240 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3244 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3247 // Set the volume state accordingly
3250 if( VolumeStatus->Online)