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
3244 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3246 uniTargetName.Buffer,
3247 uniTargetName.Length);
3249 if( !NT_SUCCESS( ntStatus))
3252 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3258 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3261 // Update the metadata for the entry
3264 ntStatus = AFSUpdateMetaData( DirEntry,
3267 if( NT_SUCCESS( ntStatus))
3270 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3278 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3279 AFS_TRACE_LEVEL_WARNING,
3280 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3281 pObjectInfo->FileType,
3282 &DirEntry->NameInformation.FileName,
3283 pObjectInfo->FileId.Cell,
3284 pObjectInfo->FileId.Volume,
3285 pObjectInfo->FileId.Vnode,
3286 pObjectInfo->FileId.Unique);
3293 if( pDirEnumEntry != NULL)
3296 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3304 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3307 NTSTATUS ntStatus = STATUS_SUCCESS;
3308 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3309 ULONGLONG ullIndex = 0;
3310 AFSVolumeCB *pVolumeCB = NULL;
3316 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3317 AFS_TRACE_LEVEL_VERBOSE,
3318 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3319 VolumeStatus->Online,
3320 VolumeStatus->FileID.Cell,
3321 VolumeStatus->FileID.Volume);
3324 // Need to locate the Fcb for the directory to purge
3327 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3328 AFS_TRACE_LEVEL_VERBOSE,
3329 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3330 &pDevExt->Specific.RDR.VolumeTreeLock,
3331 PsGetCurrentThread());
3333 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3336 // Locate the volume node
3339 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3341 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3343 (AFSBTreeEntry **)&pVolumeCB);
3345 if( pVolumeCB != NULL)
3348 lCount = AFSVolumeIncrement( pVolumeCB,
3349 AFS_VOLUME_REFERENCE_INVALIDATE);
3351 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3352 AFS_TRACE_LEVEL_VERBOSE,
3353 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3357 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3360 // Set the volume state accordingly
3363 if( VolumeStatus->Online)
3366 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3371 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3380 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3383 NTSTATUS ntStatus = STATUS_SUCCESS;
3388 if( AFSGlobalRoot == NULL)
3391 try_return( ntStatus);
3394 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3398 // Set the network state according to the information
3401 if( NetworkStatus->Online)
3404 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3409 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3412 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3423 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3427 NTSTATUS ntStatus = STATUS_SUCCESS;
3428 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3429 BOOLEAN bAcquiredLock = FALSE;
3430 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3435 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3436 AFS_TRACE_LEVEL_VERBOSE,
3437 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3438 ObjectInfo->FileId.Cell,
3439 ObjectInfo->FileId.Volume,
3440 ObjectInfo->FileId.Vnode,
3441 ObjectInfo->FileId.Unique);
3443 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3446 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3447 AFS_TRACE_LEVEL_VERBOSE,
3448 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3449 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3450 PsGetCurrentThread());
3452 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3455 bAcquiredLock = TRUE;
3459 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3462 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3463 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3466 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3467 AFS_TRACE_LEVEL_ERROR,
3468 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3469 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3470 ObjectInfo->FileId.Cell,
3471 ObjectInfo->FileId.Volume,
3472 ObjectInfo->FileId.Vnode,
3473 ObjectInfo->FileId.Unique);
3477 // Reset the directory list information by clearing all valid entries
3480 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3482 while( pCurrentDirEntry != NULL)
3485 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3487 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3491 // If this entry has been deleted then process it here
3494 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3495 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3496 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3499 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3500 AFS_TRACE_LEVEL_VERBOSE,
3501 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3503 &pCurrentDirEntry->NameInformation.FileName);
3505 AFSDeleteDirEntry( ObjectInfo,
3511 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3513 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3514 AFS_TRACE_LEVEL_VERBOSE,
3515 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3517 pCurrentDirEntry->DirOpenReferenceCount);
3520 // We pull the short name from the parent tree since it could change below
3523 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3526 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3527 AFS_TRACE_LEVEL_VERBOSE,
3528 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3530 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3531 &pCurrentDirEntry->NameInformation.FileName);
3533 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3536 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3541 pCurrentDirEntry = pNextDirEntry;
3545 // Reget the directory contents
3548 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3551 if ( !NT_SUCCESS( ntStatus))
3553 try_return( ntStatus);
3557 // Now start again and tear down any entries not valid
3560 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3562 while( pCurrentDirEntry != NULL)
3565 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3567 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3570 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3571 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3572 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3575 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3578 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3580 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3581 AFS_TRACE_LEVEL_VERBOSE,
3582 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3584 &pCurrentDirEntry->NameInformation.FileName);
3586 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3591 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3594 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3595 AFS_TRACE_LEVEL_VERBOSE,
3596 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3598 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3599 &pCurrentDirEntry->NameInformation.FileName);
3603 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3605 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3606 AFS_TRACE_LEVEL_VERBOSE,
3607 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3609 &pCurrentDirEntry->NameInformation.FileName);
3614 pCurrentDirEntry = pNextDirEntry;
3619 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3620 AFS_TRACE_LEVEL_VERBOSE,
3621 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3623 pCurrentDirEntry->DirOpenReferenceCount);
3625 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3626 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3629 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3630 AFS_TRACE_LEVEL_VERBOSE,
3631 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3632 &pCurrentDirEntry->NameInformation.FileName,
3633 ObjectInfo->FileId.Cell,
3634 ObjectInfo->FileId.Volume,
3635 ObjectInfo->FileId.Vnode,
3636 ObjectInfo->FileId.Unique);
3638 AFSDeleteDirEntry( ObjectInfo,
3644 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3645 AFS_TRACE_LEVEL_VERBOSE,
3646 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3648 &pCurrentDirEntry->NameInformation.FileName,
3649 ObjectInfo->FileId.Cell,
3650 ObjectInfo->FileId.Volume,
3651 ObjectInfo->FileId.Vnode,
3652 ObjectInfo->FileId.Unique);
3654 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3656 AFSRemoveNameEntry( ObjectInfo,
3660 pCurrentDirEntry = pNextDirEntry;
3664 if( !AFSValidateDirList( ObjectInfo))
3667 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3676 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3684 AFSIsVolumeFID( IN AFSFileID *FileID)
3687 BOOLEAN bIsVolume = FALSE;
3689 if( FileID->Vnode == 1 &&
3690 FileID->Unique == 1)
3700 AFSIsFinalNode( IN AFSFcb *Fcb)
3703 BOOLEAN bIsFinalNode = FALSE;
3705 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3706 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3707 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3708 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3709 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3712 bIsFinalNode = TRUE;
3717 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3718 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3721 return bIsFinalNode;
3725 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3726 IN AFSDirEnumEntry *DirEnumEntry)
3729 NTSTATUS ntStatus = STATUS_SUCCESS;
3730 UNICODE_STRING uniTargetName;
3731 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3736 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3738 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3740 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3742 pObjectInfo->FileType = DirEnumEntry->FileType;
3744 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3746 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3748 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3750 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3752 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3754 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3756 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3758 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3759 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3762 pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3765 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
3768 if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
3771 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3776 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3780 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3782 pObjectInfo->Links = DirEnumEntry->Links;
3784 if( DirEnumEntry->TargetNameLength > 0 &&
3785 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3786 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3790 // Update the target name information if needed
3793 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3795 uniTargetName.MaximumLength = uniTargetName.Length;
3797 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3799 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3802 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3803 RtlCompareUnicodeString( &uniTargetName,
3804 &DirEntry->NameInformation.TargetName,
3809 // Update the target name
3812 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3814 uniTargetName.Buffer,
3815 uniTargetName.Length);
3817 if( !NT_SUCCESS( ntStatus))
3820 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3822 try_return( ntStatus);
3826 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3828 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3829 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3832 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3835 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3836 DirEntry->NameInformation.TargetName.Buffer != NULL)
3838 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3841 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3843 DirEntry->NameInformation.TargetName.Length = 0;
3844 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3845 DirEntry->NameInformation.TargetName.Buffer = NULL;
3847 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3859 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3861 IN BOOLEAN FastCall,
3862 IN BOOLEAN bSafeToPurge)
3865 NTSTATUS ntStatus = STATUS_SUCCESS;
3866 LARGE_INTEGER liSystemTime;
3867 AFSDirEnumEntry *pDirEnumEntry = NULL;
3868 AFSFcb *pCurrentFcb = NULL;
3869 BOOLEAN bReleaseFcb = FALSE;
3870 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3876 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3880 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3881 AFS_TRACE_LEVEL_VERBOSE_2,
3882 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3883 &DirEntry->NameInformation.FileName,
3884 pObjectInfo->FileId.Cell,
3885 pObjectInfo->FileId.Volume,
3886 pObjectInfo->FileId.Vnode,
3887 pObjectInfo->FileId.Unique,
3891 // If this is a fake node then bail since the service knows nothing about it
3894 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3897 try_return( ntStatus);
3901 // This routine ensures that the current entry is valid by:
3903 // 1) Checking that the expiration time is non-zero and after where we
3907 KeQuerySystemTime( &liSystemTime);
3909 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3910 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3911 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3912 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3915 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3916 AFS_TRACE_LEVEL_VERBOSE_2,
3917 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3918 &DirEntry->NameInformation.FileName,
3919 pObjectInfo->FileId.Cell,
3920 pObjectInfo->FileId.Volume,
3921 pObjectInfo->FileId.Vnode,
3922 pObjectInfo->FileId.Unique);
3924 try_return( ntStatus);
3928 // This node requires updating
3931 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3936 if( !NT_SUCCESS( ntStatus))
3939 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3940 AFS_TRACE_LEVEL_ERROR,
3941 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3943 &DirEntry->NameInformation.FileName,
3944 pObjectInfo->FileId.Cell,
3945 pObjectInfo->FileId.Volume,
3946 pObjectInfo->FileId.Vnode,
3947 pObjectInfo->FileId.Unique,
3951 // Failed validation of node so return access-denied
3954 try_return( ntStatus);
3957 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3958 AFS_TRACE_LEVEL_VERBOSE,
3959 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3961 &DirEntry->NameInformation.FileName,
3962 pObjectInfo->FileId.Cell,
3963 pObjectInfo->FileId.Volume,
3964 pObjectInfo->FileId.Vnode,
3965 pObjectInfo->FileId.Unique,
3966 pObjectInfo->DataVersion.QuadPart,
3967 pDirEnumEntry->DataVersion.QuadPart,
3968 pDirEnumEntry->FileType);
3972 // Based on the file type, process the node
3975 switch( pDirEnumEntry->FileType)
3978 case AFS_FILE_TYPE_MOUNTPOINT:
3982 // Update the metadata for the entry
3985 ntStatus = AFSUpdateMetaData( DirEntry,
3988 if( NT_SUCCESS( ntStatus))
3991 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3997 case AFS_FILE_TYPE_SYMLINK:
3998 case AFS_FILE_TYPE_DFSLINK:
4002 // Update the metadata for the entry
4005 ntStatus = AFSUpdateMetaData( DirEntry,
4008 if( NT_SUCCESS( ntStatus))
4011 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4017 case AFS_FILE_TYPE_FILE:
4020 BOOLEAN bPurgeExtents = FALSE;
4023 // For a file where the data version has become invalid we need to
4024 // fail any current extent requests and purge the cache for the file
4025 // Can't hold the Fcb resource while doing this
4028 if( pObjectInfo->Fcb != NULL &&
4029 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4030 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4033 pCurrentFcb = pObjectInfo->Fcb;
4035 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4038 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4039 AFS_TRACE_LEVEL_VERBOSE,
4040 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4041 &pCurrentFcb->NPFcb->Resource,
4042 PsGetCurrentThread());
4044 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4050 if( pCurrentFcb != NULL)
4053 IO_STATUS_BLOCK stIoStatus;
4055 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4056 AFS_TRACE_LEVEL_VERBOSE_2,
4057 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4058 &DirEntry->NameInformation.FileName,
4059 pObjectInfo->FileId.Cell,
4060 pObjectInfo->FileId.Volume,
4061 pObjectInfo->FileId.Vnode,
4062 pObjectInfo->FileId.Unique);
4064 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4067 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4068 AFS_TRACE_LEVEL_VERBOSE,
4069 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4070 &DirEntry->NameInformation.FileName,
4071 pObjectInfo->FileId.Cell,
4072 pObjectInfo->FileId.Volume,
4073 pObjectInfo->FileId.Vnode,
4074 pObjectInfo->FileId.Unique,
4075 pObjectInfo->DataVersion.LowPart,
4076 pDirEnumEntry->DataVersion.LowPart
4079 bPurgeExtents = TRUE;
4085 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4087 bPurgeExtents = TRUE;
4089 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4090 AFS_TRACE_LEVEL_VERBOSE,
4091 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4092 &DirEntry->NameInformation.FileName,
4093 pObjectInfo->FileId.Cell,
4094 pObjectInfo->FileId.Volume,
4095 pObjectInfo->FileId.Vnode,
4096 pObjectInfo->FileId.Unique);
4098 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4101 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4102 AFS_TRACE_LEVEL_VERBOSE,
4103 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4104 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4105 PsGetCurrentThread());
4107 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4111 // Release Fcb->Resource to avoid Trend Micro deadlock
4114 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
4119 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4124 if( !NT_SUCCESS( stIoStatus.Status))
4127 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4128 AFS_TRACE_LEVEL_ERROR,
4129 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4130 &DirEntry->NameInformation.FileName,
4131 pObjectInfo->FileId.Cell,
4132 pObjectInfo->FileId.Volume,
4133 pObjectInfo->FileId.Vnode,
4134 pObjectInfo->FileId.Unique,
4136 stIoStatus.Information);
4138 ntStatus = stIoStatus.Status;
4141 if ( bPurgeExtents &&
4142 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4145 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4151 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4152 AFS_TRACE_LEVEL_WARNING,
4153 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4154 &DirEntry->NameInformation.FileName,
4155 pObjectInfo->FileId.Cell,
4156 pObjectInfo->FileId.Volume,
4157 pObjectInfo->FileId.Vnode,
4158 pObjectInfo->FileId.Unique);
4160 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4164 __except( EXCEPTION_EXECUTE_HANDLER)
4166 ntStatus = GetExceptionCode();
4170 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4171 &DirEntry->NameInformation.FileName,
4172 pObjectInfo->FileId.Cell,
4173 pObjectInfo->FileId.Volume,
4174 pObjectInfo->FileId.Vnode,
4175 pObjectInfo->FileId.Unique,
4178 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4181 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4182 AFS_TRACE_LEVEL_VERBOSE,
4183 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4184 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4185 PsGetCurrentThread());
4187 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4189 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4198 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4203 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4205 bReleaseFcb = FALSE;
4207 if ( bPurgeExtents &&
4210 AFSFlushExtents( pCurrentFcb,
4217 // Update the metadata for the entry but only if it is safe to do so.
4218 // If it was determined that a data version change has occurred or
4219 // that a pending data verification was required, do not update the
4220 // ObjectInfo meta data or the FileObject size information. That
4221 // way it is consistent for the next time that the data is verified
4225 if ( !(bPurgeExtents && bSafeToPurge))
4228 ntStatus = AFSUpdateMetaData( DirEntry,
4231 if( !NT_SUCCESS( ntStatus))
4234 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4235 AFS_TRACE_LEVEL_ERROR,
4236 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4237 &DirEntry->NameInformation.FileName,
4238 pObjectInfo->FileId.Cell,
4239 pObjectInfo->FileId.Volume,
4240 pObjectInfo->FileId.Vnode,
4241 pObjectInfo->FileId.Unique,
4247 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4250 // Update file sizes
4253 if( pObjectInfo->Fcb != NULL)
4255 FILE_OBJECT *pCCFileObject;
4257 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4258 AFS_TRACE_LEVEL_VERBOSE,
4259 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4260 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4261 PsGetCurrentThread());
4263 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4266 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4268 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4269 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4270 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4272 if ( pCCFileObject != NULL)
4274 CcSetFileSizes( pCCFileObject,
4275 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4278 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4279 AFS_TRACE_LEVEL_VERBOSE,
4280 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4281 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4282 PsGetCurrentThread());
4284 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4290 case AFS_FILE_TYPE_DIRECTORY:
4293 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4297 // For a directory or root entry flush the content of
4298 // the directory enumeration.
4301 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4302 AFS_TRACE_LEVEL_VERBOSE,
4303 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4304 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4305 PsGetCurrentThread());
4307 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4310 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4311 AFS_TRACE_LEVEL_VERBOSE_2,
4312 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4313 &DirEntry->NameInformation.FileName,
4314 pObjectInfo->FileId.Cell,
4315 pObjectInfo->FileId.Volume,
4316 pObjectInfo->FileId.Vnode,
4317 pObjectInfo->FileId.Unique);
4319 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4322 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4325 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4328 if( !NT_SUCCESS( ntStatus))
4331 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4332 AFS_TRACE_LEVEL_ERROR,
4333 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4334 &DirEntry->NameInformation.FileName,
4335 pObjectInfo->FileId.Cell,
4336 pObjectInfo->FileId.Volume,
4337 pObjectInfo->FileId.Vnode,
4338 pObjectInfo->FileId.Unique,
4346 // Update the metadata for the entry
4349 ntStatus = AFSUpdateMetaData( DirEntry,
4352 if( NT_SUCCESS( ntStatus))
4355 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4363 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4364 AFS_TRACE_LEVEL_WARNING,
4365 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4366 pObjectInfo->FileType,
4368 &DirEntry->NameInformation.FileName,
4369 pObjectInfo->FileId.Cell,
4370 pObjectInfo->FileId.Volume,
4371 pObjectInfo->FileId.Vnode,
4372 pObjectInfo->FileId.Unique);
4382 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4385 if( pDirEnumEntry != NULL)
4388 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4396 AFSInitializeSpecialShareNameList()
4399 NTSTATUS ntStatus = STATUS_SUCCESS;
4400 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4401 AFSObjectInfoCB *pObjectInfoCB = NULL;
4402 UNICODE_STRING uniShareName;
4403 ULONG ulEntryLength = 0;
4404 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4410 RtlInitUnicodeString( &uniShareName,
4413 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4416 if( pObjectInfoCB == NULL)
4419 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4422 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4423 AFS_OBJECT_REFERENCE_GLOBAL);
4425 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4426 AFS_TRACE_LEVEL_VERBOSE,
4427 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4431 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4433 ulEntryLength = sizeof( AFSDirectoryCB) +
4434 uniShareName.Length;
4436 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4440 if( pDirNode == NULL)
4443 AFSDeleteObjectInfo( &pObjectInfoCB);
4445 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4448 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4449 AFS_TRACE_LEVEL_VERBOSE,
4450 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4453 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4454 sizeof( AFSNonPagedDirectoryCB),
4455 AFS_DIR_ENTRY_NP_TAG);
4457 if( pNonPagedDirEntry == NULL)
4460 ExFreePool( pDirNode);
4462 AFSDeleteObjectInfo( &pObjectInfoCB);
4464 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4467 RtlZeroMemory( pDirNode,
4470 RtlZeroMemory( pNonPagedDirEntry,
4471 sizeof( AFSNonPagedDirectoryCB));
4473 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4475 pDirNode->NonPaged = pNonPagedDirEntry;
4477 pDirNode->ObjectInformation = pObjectInfoCB;
4483 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4485 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4487 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4489 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4491 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4492 uniShareName.Buffer,
4493 pDirNode->NameInformation.FileName.Length);
4495 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4498 AFSSpecialShareNames = pDirNode;
4500 pLastDirNode = pDirNode;
4503 RtlInitUnicodeString( &uniShareName,
4506 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4509 if( pObjectInfoCB == NULL)
4512 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4515 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4516 AFS_OBJECT_REFERENCE_GLOBAL);
4518 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4519 AFS_TRACE_LEVEL_VERBOSE,
4520 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4524 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4526 ulEntryLength = sizeof( AFSDirectoryCB) +
4527 uniShareName.Length;
4529 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4533 if( pDirNode == NULL)
4536 AFSDeleteObjectInfo( &pObjectInfoCB);
4538 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4541 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4542 AFS_TRACE_LEVEL_VERBOSE,
4543 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4546 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4547 sizeof( AFSNonPagedDirectoryCB),
4548 AFS_DIR_ENTRY_NP_TAG);
4550 if( pNonPagedDirEntry == NULL)
4553 ExFreePool( pDirNode);
4555 AFSDeleteObjectInfo( &pObjectInfoCB);
4557 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4560 RtlZeroMemory( pDirNode,
4563 RtlZeroMemory( pNonPagedDirEntry,
4564 sizeof( AFSNonPagedDirectoryCB));
4566 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4568 pDirNode->NonPaged = pNonPagedDirEntry;
4570 pDirNode->ObjectInformation = pObjectInfoCB;
4576 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4578 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4580 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4582 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4584 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4585 uniShareName.Buffer,
4586 pDirNode->NameInformation.FileName.Length);
4588 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4591 pLastDirNode->ListEntry.fLink = pDirNode;
4593 pDirNode->ListEntry.bLink = pLastDirNode;
4597 if( !NT_SUCCESS( ntStatus))
4600 if( AFSSpecialShareNames != NULL)
4603 pDirNode = AFSSpecialShareNames;
4605 while( pDirNode != NULL)
4608 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4610 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4612 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4614 ExFreePool( pDirNode->NonPaged);
4616 ExFreePool( pDirNode);
4618 pDirNode = pLastDirNode;
4621 AFSSpecialShareNames = NULL;
4630 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4631 IN UNICODE_STRING *SecondaryName)
4634 AFSDirectoryCB *pDirectoryCB = NULL;
4635 ULONGLONG ullHash = 0;
4636 UNICODE_STRING uniFullShareName;
4642 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4643 AFS_TRACE_LEVEL_VERBOSE_2,
4644 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4648 uniFullShareName = *ShareName;
4651 // Generate our hash value
4654 ullHash = AFSGenerateCRC( &uniFullShareName,
4658 // Loop through our special share names to see if this is one of them
4661 pDirectoryCB = AFSSpecialShareNames;
4663 while( pDirectoryCB != NULL)
4666 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4672 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4676 return pDirectoryCB;
4680 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4684 // Block on the queue flush event
4687 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4697 AFSWaitOnQueuedReleases()
4700 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4703 // Block on the queue flush event
4706 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4716 AFSIsEqualFID( IN AFSFileID *FileId1,
4717 IN AFSFileID *FileId2)
4720 BOOLEAN bIsEqual = FALSE;
4722 if( FileId1->Hash == FileId2->Hash &&
4723 FileId1->Unique == FileId2->Unique &&
4724 FileId1->Vnode == FileId2->Vnode &&
4725 FileId1->Volume == FileId2->Volume &&
4726 FileId1->Cell == FileId2->Cell)
4736 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4739 NTSTATUS ntStatus = STATUS_SUCCESS;
4740 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4745 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4748 // Reset the directory list information
4751 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4753 while( pCurrentDirEntry != NULL)
4756 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4758 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
4759 pCurrentDirEntry->NameArrayReferenceCount <= 0)
4762 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4763 AFS_TRACE_LEVEL_VERBOSE,
4764 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4766 &pCurrentDirEntry->NameInformation.FileName);
4768 AFSDeleteDirEntry( ObjectInfoCB,
4774 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4775 AFS_TRACE_LEVEL_VERBOSE,
4776 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4778 &pCurrentDirEntry->NameInformation.FileName);
4780 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4782 AFSRemoveNameEntry( ObjectInfoCB,
4786 pCurrentDirEntry = pNextDirEntry;
4789 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4791 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4793 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4795 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4797 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4799 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4801 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4802 AFS_TRACE_LEVEL_VERBOSE,
4803 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4804 ObjectInfoCB->FileId.Cell,
4805 ObjectInfoCB->FileId.Volume,
4806 ObjectInfoCB->FileId.Vnode,
4807 ObjectInfoCB->FileId.Unique);
4814 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4817 NTSTATUS ntStatus = STATUS_SUCCESS;
4818 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4819 UNICODE_STRING uniFullName;
4824 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4825 AFS_TRACE_LEVEL_VERBOSE,
4826 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4827 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4828 PsGetCurrentThread());
4830 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4833 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4836 try_return( ntStatus);
4840 // Initialize the root information
4843 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4846 // Enumerate the shares in the volume
4849 ntStatus = AFSEnumerateDirectory( AuthGroup,
4850 &AFSGlobalRoot->ObjectInformation,
4853 if( !NT_SUCCESS( ntStatus))
4856 try_return( ntStatus);
4859 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4861 uniFullName.MaximumLength = PAGE_SIZE;
4862 uniFullName.Length = 0;
4864 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4865 uniFullName.MaximumLength,
4866 AFS_GENERIC_MEMORY_12_TAG);
4868 if( uniFullName.Buffer == NULL)
4872 // Reset the directory content
4875 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4877 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4879 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4883 // Populate our list of entries in the NP enumeration list
4886 while( pDirGlobalDirNode != NULL)
4889 uniFullName.Buffer[ 0] = L'\\';
4890 uniFullName.Buffer[ 1] = L'\\';
4892 uniFullName.Length = 2 * sizeof( WCHAR);
4894 RtlCopyMemory( &uniFullName.Buffer[ 2],
4895 AFSServerName.Buffer,
4896 AFSServerName.Length);
4898 uniFullName.Length += AFSServerName.Length;
4900 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4902 uniFullName.Length += sizeof( WCHAR);
4904 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4905 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4906 pDirGlobalDirNode->NameInformation.FileName.Length);
4908 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4910 AFSAddConnectionEx( &uniFullName,
4911 RESOURCEDISPLAYTYPE_SHARE,
4914 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4917 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
4921 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4928 AFSIsRelativeName( IN UNICODE_STRING *Name)
4931 BOOLEAN bIsRelative = FALSE;
4933 if( Name->Length > 0 &&
4934 Name->Buffer[ 0] != L'\\')
4944 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
4946 UNICODE_STRING uniTempName;
4947 BOOLEAN bIsAbsolute = FALSE;
4950 // An absolute AFS path must begin with \afs\... or equivalent
4953 if ( Name->Length == 0 ||
4954 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
4955 Name->Buffer[ 0] != L'\\' ||
4956 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
4962 uniTempName.Length = AFSMountRootName.Length;
4963 uniTempName.MaximumLength = AFSMountRootName.Length;
4965 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4966 uniTempName.MaximumLength,
4967 AFS_NAME_BUFFER_TWO_TAG);
4969 if( uniTempName.Buffer == NULL)
4975 RtlCopyMemory( uniTempName.Buffer,
4977 AFSMountRootName.Length);
4979 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
4983 AFSExFreePoolWithTag( uniTempName.Buffer,
4984 AFS_NAME_BUFFER_TWO_TAG);
4991 AFSUpdateName( IN UNICODE_STRING *Name)
4996 while( usIndex < Name->Length/sizeof( WCHAR))
4999 if( Name->Buffer[ usIndex] == L'/')
5002 Name->Buffer[ usIndex] = L'\\';
5012 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
5013 IN OUT ULONG *Flags,
5014 IN WCHAR *NameBuffer,
5015 IN USHORT NameLength)
5018 NTSTATUS ntStatus = STATUS_SUCCESS;
5019 WCHAR *pTmpBuffer = NULL;
5025 // If we have enough space then just move in the name otherwise
5026 // allocate a new buffer
5029 if( TargetName->Length < NameLength)
5032 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5034 AFS_NAME_BUFFER_FIVE_TAG);
5036 if( pTmpBuffer == NULL)
5039 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5042 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5045 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5048 TargetName->MaximumLength = NameLength;
5050 TargetName->Buffer = pTmpBuffer;
5052 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5055 TargetName->Length = NameLength;
5057 RtlCopyMemory( TargetName->Buffer,
5059 TargetName->Length);
5062 // Update the name in the buffer
5065 AFSUpdateName( TargetName);
5076 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
5077 IN ULONG InitialElementCount)
5080 AFSNameArrayHdr *pNameArray = NULL;
5081 AFSNameArrayCB *pCurrentElement = NULL;
5082 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5088 if( InitialElementCount == 0)
5091 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
5094 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
5095 sizeof( AFSNameArrayHdr) +
5096 (InitialElementCount * sizeof( AFSNameArrayCB)),
5097 AFS_NAME_ARRAY_TAG);
5099 if( pNameArray == NULL)
5102 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5103 AFS_TRACE_LEVEL_ERROR,
5104 "AFSInitNameArray Failed to allocate name array\n");
5106 try_return( pNameArray);
5109 RtlZeroMemory( pNameArray,
5110 sizeof( AFSNameArrayHdr) +
5111 (InitialElementCount * sizeof( AFSNameArrayCB)));
5113 pNameArray->MaxElementCount = InitialElementCount;
5115 if( DirectoryCB != NULL)
5118 pCurrentElement = &pNameArray->ElementArray[ 0];
5120 pNameArray->CurrentEntry = pCurrentElement;
5122 pNameArray->Count = 1;
5124 pNameArray->LinkCount = 0;
5126 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5128 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5129 AFS_TRACE_LEVEL_VERBOSE,
5130 "AFSInitNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5132 &DirectoryCB->NameInformation.FileName,
5136 pCurrentElement->DirectoryCB = DirectoryCB;
5138 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5140 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5142 if( pCurrentElement->FileId.Vnode == 1)
5145 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5148 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5149 AFS_TRACE_LEVEL_VERBOSE,
5150 "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5152 pCurrentElement->DirectoryCB,
5153 pCurrentElement->FileId.Cell,
5154 pCurrentElement->FileId.Volume,
5155 pCurrentElement->FileId.Vnode,
5156 pCurrentElement->FileId.Unique,
5157 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5158 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5170 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
5171 IN UNICODE_STRING *Path,
5172 IN AFSDirectoryCB *DirectoryCB)
5175 NTSTATUS ntStatus = STATUS_SUCCESS;
5176 AFSNameArrayCB *pCurrentElement = NULL;
5182 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5183 AFS_TRACE_LEVEL_VERBOSE,
5184 "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5188 DirectoryCB->ObjectInformation->FileId.Cell,
5189 DirectoryCB->ObjectInformation->FileId.Volume,
5190 DirectoryCB->ObjectInformation->FileId.Vnode,
5191 DirectoryCB->ObjectInformation->FileId.Unique,
5192 &DirectoryCB->NameInformation.FileName,
5193 DirectoryCB->ObjectInformation->FileType);
5196 // Init some info in the header
5199 pCurrentElement = &NameArray->ElementArray[ 0];
5201 NameArray->CurrentEntry = pCurrentElement;
5204 // The first entry points at the root
5207 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
5209 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5211 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5212 AFS_TRACE_LEVEL_VERBOSE,
5213 "AFSPopulateNameArray [NA:%p] Increment count on volume %wZ DE %p Cnt %d\n",
5215 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5216 pCurrentElement->DirectoryCB,
5219 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
5221 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
5223 pCurrentElement->Flags = 0;
5225 if( pCurrentElement->FileId.Vnode == 1)
5228 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5231 NameArray->Count = 1;
5233 NameArray->LinkCount = 0;
5235 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5236 AFS_TRACE_LEVEL_VERBOSE,
5237 "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5239 pCurrentElement->DirectoryCB,
5240 pCurrentElement->FileId.Cell,
5241 pCurrentElement->FileId.Volume,
5242 pCurrentElement->FileId.Vnode,
5243 pCurrentElement->FileId.Unique,
5244 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5245 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5248 // If the root is the parent then we are done ...
5251 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
5253 try_return( ntStatus);
5265 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
5266 IN AFSNameArrayHdr *RelatedNameArray,
5267 IN AFSDirectoryCB *DirectoryCB)
5270 NTSTATUS ntStatus = STATUS_SUCCESS;
5271 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
5280 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5281 AFS_TRACE_LEVEL_VERBOSE,
5282 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5286 DirectoryCB->ObjectInformation->FileId.Cell,
5287 DirectoryCB->ObjectInformation->FileId.Volume,
5288 DirectoryCB->ObjectInformation->FileId.Vnode,
5289 DirectoryCB->ObjectInformation->FileId.Unique,
5290 &DirectoryCB->NameInformation.FileName,
5291 DirectoryCB->ObjectInformation->FileType);
5296 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5297 AFS_TRACE_LEVEL_VERBOSE,
5298 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE NULL\n",
5304 // Init some info in the header
5307 pCurrentElement = &NameArray->ElementArray[ 0];
5309 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5311 NameArray->Count = 0;
5313 NameArray->LinkCount = RelatedNameArray->LinkCount;
5316 // Populate the name array with the data from the related array
5322 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5324 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5326 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5328 pCurrentElement->Flags = 0;
5330 if( pCurrentElement->FileId.Vnode == 1)
5333 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5336 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5338 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5339 AFS_TRACE_LEVEL_VERBOSE,
5340 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5342 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5343 pCurrentElement->DirectoryCB,
5346 lCount = InterlockedIncrement( &NameArray->Count);
5348 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5349 AFS_TRACE_LEVEL_VERBOSE,
5350 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5353 pCurrentElement->DirectoryCB,
5354 pCurrentElement->FileId.Cell,
5355 pCurrentElement->FileId.Volume,
5356 pCurrentElement->FileId.Vnode,
5357 pCurrentElement->FileId.Unique,
5358 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5359 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5361 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5362 NameArray->Count == RelatedNameArray->Count)
5374 pCurrentRelatedElement++;
5377 NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
5384 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5387 NTSTATUS ntStatus = STATUS_SUCCESS;
5388 AFSNameArrayCB *pCurrentElement = NULL;
5389 LONG lCount, lElement;
5394 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5395 AFS_TRACE_LEVEL_VERBOSE,
5396 "AFSFreeNameArray [NA:%p]\n",
5399 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5402 pCurrentElement = &NameArray->ElementArray[ lElement];
5404 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5406 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5407 AFS_TRACE_LEVEL_VERBOSE,
5408 "AFSFreeNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5410 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5411 pCurrentElement->DirectoryCB,
5414 ASSERT( lCount >= 0);
5417 AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
5424 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5425 IN AFSDirectoryCB *DirectoryCB)
5428 NTSTATUS ntStatus = STATUS_SUCCESS;
5429 AFSNameArrayCB *pCurrentElement = NULL;
5435 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5436 AFS_TRACE_LEVEL_VERBOSE,
5437 "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5440 DirectoryCB->ObjectInformation->FileId.Cell,
5441 DirectoryCB->ObjectInformation->FileId.Volume,
5442 DirectoryCB->ObjectInformation->FileId.Vnode,
5443 DirectoryCB->ObjectInformation->FileId.Unique,
5444 &DirectoryCB->NameInformation.FileName,
5445 DirectoryCB->ObjectInformation->FileType);
5447 if( NameArray->Count == (LONG) NameArray->MaxElementCount)
5450 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5451 AFS_TRACE_LEVEL_ERROR,
5452 "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
5455 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5458 for ( lCount = 0; lCount < NameArray->Count; lCount++)
5461 if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
5462 &DirectoryCB->ObjectInformation->FileId) )
5465 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5466 AFS_TRACE_LEVEL_WARNING,
5467 "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
5470 STATUS_ACCESS_DENIED);
5472 try_return( ntStatus = STATUS_ACCESS_DENIED);
5476 if( NameArray->Count > 0)
5479 NameArray->CurrentEntry++;
5483 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5486 pCurrentElement = NameArray->CurrentEntry;
5488 lCount = InterlockedIncrement( &NameArray->Count);
5490 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5492 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5493 AFS_TRACE_LEVEL_VERBOSE,
5494 "AFSInsertNextElement [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5496 &DirectoryCB->NameInformation.FileName,
5500 ASSERT( lCount > 0);
5502 pCurrentElement->DirectoryCB = DirectoryCB;
5504 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5506 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5508 pCurrentElement->Flags = 0;
5510 if( pCurrentElement->FileId.Vnode == 1)
5513 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5516 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5517 AFS_TRACE_LEVEL_VERBOSE,
5518 "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5520 NameArray->Count - 1,
5521 pCurrentElement->DirectoryCB,
5522 pCurrentElement->FileId.Cell,
5523 pCurrentElement->FileId.Volume,
5524 pCurrentElement->FileId.Vnode,
5525 pCurrentElement->FileId.Unique,
5526 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5527 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5538 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5541 AFSDirectoryCB *pDirectoryCB = NULL;
5542 AFSNameArrayCB *pCurrentElement = NULL;
5543 BOOLEAN bVolumeRoot = FALSE;
5549 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5550 AFS_TRACE_LEVEL_VERBOSE,
5551 "AFSBackupEntry [NA:%p]\n",
5554 if( NameArray->Count == 0)
5557 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5558 AFS_TRACE_LEVEL_ERROR,
5559 "AFSBackupEntry [NA:%p] No more entries\n",
5562 try_return( pCurrentElement);
5565 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->NameArrayReferenceCount);
5567 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5568 AFS_TRACE_LEVEL_VERBOSE,
5569 "AFSBackupEntry [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5571 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5572 NameArray->CurrentEntry->DirectoryCB,
5575 ASSERT( lCount >= 0);
5577 NameArray->CurrentEntry->DirectoryCB = NULL;
5579 lCount = InterlockedDecrement( &NameArray->Count);
5583 NameArray->CurrentEntry = NULL;
5585 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5586 AFS_TRACE_LEVEL_ERROR,
5587 "AFSBackupEntry [NA:%p] No more entries\n",
5593 bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5595 NameArray->CurrentEntry--;
5597 pCurrentElement = NameArray->CurrentEntry;
5599 pDirectoryCB = pCurrentElement->DirectoryCB;
5601 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5602 AFS_TRACE_LEVEL_VERBOSE,
5603 "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5605 NameArray->Count - 1,
5606 pCurrentElement->DirectoryCB,
5607 pCurrentElement->FileId.Cell,
5608 pCurrentElement->FileId.Volume,
5609 pCurrentElement->FileId.Vnode,
5610 pCurrentElement->FileId.Unique,
5611 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5612 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5615 // If the entry we are removing is a volume root,
5616 // we must remove the mount point entry as well.
5617 // If the NameArray was constructed by checking the
5618 // share name via the service, the name array can
5619 // contain two volume roots in sequence without a
5620 // mount point separating them.
5624 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
5627 pDirectoryCB = AFSBackupEntry( NameArray);
5637 return pDirectoryCB;
5641 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5644 AFSDirectoryCB *pDirEntry = NULL;
5645 AFSNameArrayCB *pElement = NULL;
5650 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5651 AFS_TRACE_LEVEL_VERBOSE,
5652 "AFSGetParentEntry [NA:%p]\n",
5655 if( NameArray->Count == 0 ||
5656 NameArray->Count == 1)
5659 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5660 AFS_TRACE_LEVEL_ERROR,
5661 "AFSGetParentEntry [NA:%p] No more entries\n",
5664 try_return( pDirEntry = NULL);
5667 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5669 pDirEntry = pElement->DirectoryCB;
5671 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5672 AFS_TRACE_LEVEL_VERBOSE,
5673 "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5675 NameArray->Count - 2,
5676 pElement->DirectoryCB,
5677 pElement->FileId.Cell,
5678 pElement->FileId.Volume,
5679 pElement->FileId.Vnode,
5680 pElement->FileId.Unique,
5681 &pElement->DirectoryCB->NameInformation.FileName,
5682 pElement->DirectoryCB->ObjectInformation->FileType);
5693 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5694 IN AFSDirectoryCB *DirectoryCB)
5697 AFSNameArrayCB *pCurrentElement = NULL;
5698 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5699 LONG lCount, lElement;
5704 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5705 AFS_TRACE_LEVEL_VERBOSE,
5706 "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5709 DirectoryCB->ObjectInformation->FileId.Cell,
5710 DirectoryCB->ObjectInformation->FileId.Volume,
5711 DirectoryCB->ObjectInformation->FileId.Vnode,
5712 DirectoryCB->ObjectInformation->FileId.Unique,
5713 &DirectoryCB->NameInformation.FileName,
5714 DirectoryCB->ObjectInformation->FileType);
5716 // Dereference previous name array contents
5719 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5722 pCurrentElement = &NameArray->ElementArray[ lElement];
5724 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5726 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5727 AFS_TRACE_LEVEL_VERBOSE,
5728 "AFSResetNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5730 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5731 pCurrentElement->DirectoryCB,
5734 ASSERT( lCount >= 0);
5737 RtlZeroMemory( NameArray,
5738 sizeof( AFSNameArrayHdr) +
5739 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5741 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5743 if( DirectoryCB != NULL)
5746 pCurrentElement = &NameArray->ElementArray[ 0];
5748 NameArray->CurrentEntry = pCurrentElement;
5750 NameArray->Count = 1;
5752 NameArray->LinkCount = 0;
5754 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5756 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5757 AFS_TRACE_LEVEL_VERBOSE,
5758 "AFSResetNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5760 &DirectoryCB->NameInformation.FileName,
5764 pCurrentElement->DirectoryCB = DirectoryCB;
5766 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5768 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5770 pCurrentElement->Flags = 0;
5772 if( pCurrentElement->FileId.Vnode == 1)
5775 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5778 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5779 AFS_TRACE_LEVEL_VERBOSE,
5780 "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5782 pCurrentElement->DirectoryCB,
5783 pCurrentElement->FileId.Cell,
5784 pCurrentElement->FileId.Volume,
5785 pCurrentElement->FileId.Vnode,
5786 pCurrentElement->FileId.Unique,
5787 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5788 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5796 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5799 AFSNameArrayCB *pCurrentElement = NULL;
5801 pCurrentElement = &NameArray->ElementArray[ 0];
5803 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5805 while( pCurrentElement->DirectoryCB != NULL)
5808 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5809 pCurrentElement->FileId.Cell,
5810 pCurrentElement->FileId.Volume,
5811 pCurrentElement->FileId.Vnode,
5812 pCurrentElement->FileId.Unique,
5813 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5818 AFSPrint("AFSDumpNameArray End\n\n");
5824 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5829 // Depending on the type of node, set the event
5832 switch( Fcb->Header.NodeTypeCode)
5835 case AFS_DIRECTORY_FCB:
5840 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5850 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5856 // Depending on the type of node, set the event
5859 switch( Fcb->Header.NodeTypeCode)
5862 case AFS_DIRECTORY_FCB:
5867 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5869 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5879 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5882 BOOLEAN bIsInProcess = FALSE;
5887 if( ObjectInfo->Fcb == NULL)
5890 try_return( bIsInProcess);
5893 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5896 case AFS_DIRECTORY_FCB:
5901 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5904 bIsInProcess = TRUE;
5916 return bIsInProcess;
5920 AFSVerifyVolume( IN ULONGLONG ProcessId,
5921 IN AFSVolumeCB *VolumeCB)
5924 UNREFERENCED_PARAMETER(ProcessId);
5925 UNREFERENCED_PARAMETER(VolumeCB);
5926 NTSTATUS ntStatus = STATUS_SUCCESS;
5933 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5936 NTSTATUS ntStatus = STATUS_SUCCESS;
5937 AFSObjectInfoCB *pObjectInfoCB = NULL;
5938 AFSDirectoryCB *pDirNode = NULL;
5939 ULONG ulEntryLength = 0;
5940 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5946 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5949 if( pObjectInfoCB == NULL)
5952 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5955 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5956 AFS_OBJECT_REFERENCE_DIRENTRY);
5958 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5959 AFS_TRACE_LEVEL_VERBOSE,
5960 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5964 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5966 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5968 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5970 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5974 if( pDirNode == NULL)
5977 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5980 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5981 AFS_TRACE_LEVEL_VERBOSE,
5982 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5985 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5986 sizeof( AFSNonPagedDirectoryCB),
5987 AFS_DIR_ENTRY_NP_TAG);
5989 if( pNonPagedDirEntry == NULL)
5992 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5995 RtlZeroMemory( pDirNode,
5998 RtlZeroMemory( pNonPagedDirEntry,
5999 sizeof( AFSNonPagedDirectoryCB));
6001 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
6003 pDirNode->NonPaged = pNonPagedDirEntry;
6005 pDirNode->ObjectInformation = pObjectInfoCB;
6007 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
6013 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
6015 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
6017 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
6019 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
6021 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
6022 AFSPIOCtlName.Buffer,
6023 pDirNode->NameInformation.FileName.Length);
6025 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
6028 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
6031 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6032 AFS_TRACE_LEVEL_WARNING,
6033 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
6034 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
6037 try_return( ntStatus = STATUS_REPARSE);
6042 if ( ntStatus != STATUS_SUCCESS)
6045 if ( pDirNode != NULL)
6048 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
6049 AFS_TRACE_LEVEL_VERBOSE,
6050 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
6053 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
6056 if( pNonPagedDirEntry != NULL)
6059 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
6061 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
6064 if ( pObjectInfoCB != NULL)
6067 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
6068 AFS_OBJECT_REFERENCE_DIRENTRY);
6070 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6071 AFS_TRACE_LEVEL_VERBOSE,
6072 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
6076 AFSDeleteObjectInfo( &pObjectInfoCB);
6085 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
6086 IN AFSDirectoryCB *DirectoryCB,
6087 IN UNICODE_STRING *ParentPathName,
6088 IN AFSNameArrayHdr *RelatedNameArray,
6090 OUT AFSFileInfoCB *FileInfo)
6093 NTSTATUS ntStatus = STATUS_SUCCESS;
6094 AFSDirEnumEntry *pDirEntry = NULL;
6095 UNICODE_STRING uniFullPathName = {0};
6096 AFSNameArrayHdr *pNameArray = NULL;
6097 AFSVolumeCB *pVolumeCB = NULL;
6098 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6099 AFSVolumeCB *pNewVolumeCB = NULL;
6100 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6101 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6102 AFSDirectoryCB *pNewParentDirEntry = NULL;
6103 WCHAR *pwchBuffer = NULL;
6104 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6105 ULONG ulNameDifference = 0;
6112 // Retrieve a target name for the entry
6115 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6118 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6121 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6123 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6128 if( !NT_SUCCESS( ntStatus) ||
6129 pDirEntry->TargetNameLength == 0)
6132 if( pDirEntry != NULL)
6135 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6138 try_return( ntStatus);
6141 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6144 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6148 // Update the target name
6151 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6152 &DirectoryCB->Flags,
6153 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6154 (USHORT)pDirEntry->TargetNameLength);
6156 if( !NT_SUCCESS( ntStatus))
6159 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6161 try_return( ntStatus);
6165 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6169 // Need to pass the full path in for parsing.
6172 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
6175 uniFullPathName.Length = 0;
6176 uniFullPathName.MaximumLength = ParentPathName->Length +
6178 DirectoryCB->NameInformation.TargetName.Length;
6180 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6181 uniFullPathName.MaximumLength,
6182 AFS_NAME_BUFFER_SIX_TAG);
6184 if( uniFullPathName.Buffer == NULL)
6187 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6189 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6192 pwchBuffer = uniFullPathName.Buffer;
6194 RtlZeroMemory( uniFullPathName.Buffer,
6195 uniFullPathName.MaximumLength);
6197 RtlCopyMemory( uniFullPathName.Buffer,
6198 ParentPathName->Buffer,
6199 ParentPathName->Length);
6201 uniFullPathName.Length = ParentPathName->Length;
6203 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
6204 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
6207 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
6209 uniFullPathName.Length += sizeof( WCHAR);
6212 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
6213 DirectoryCB->NameInformation.TargetName.Buffer,
6214 DirectoryCB->NameInformation.TargetName.Length);
6216 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
6218 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
6219 uniParsedName.MaximumLength = uniParsedName.Length;
6221 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
6223 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6226 // We populate up to the current parent
6229 if( RelatedNameArray != NULL)
6232 pNameArray = AFSInitNameArray( NULL,
6233 RelatedNameArray->MaxElementCount);
6235 if( pNameArray == NULL)
6238 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6241 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
6248 pNameArray = AFSInitNameArray( NULL,
6251 if( pNameArray == NULL)
6254 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6257 ntStatus = AFSPopulateNameArray( pNameArray,
6262 if( !NT_SUCCESS( ntStatus))
6265 try_return( ntStatus);
6268 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
6270 pParentDirEntry = ParentDirectoryCB;
6275 uniFullPathName.Length = 0;
6276 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6278 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6279 uniFullPathName.MaximumLength,
6280 AFS_NAME_BUFFER_SEVEN_TAG);
6282 if( uniFullPathName.Buffer == NULL)
6285 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6287 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6290 pwchBuffer = uniFullPathName.Buffer;
6292 RtlZeroMemory( uniFullPathName.Buffer,
6293 uniFullPathName.MaximumLength);
6295 RtlCopyMemory( uniFullPathName.Buffer,
6296 DirectoryCB->NameInformation.TargetName.Buffer,
6297 DirectoryCB->NameInformation.TargetName.Length);
6299 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6302 // This name should begin with the \afs server so parse it off and check it
6305 FsRtlDissectName( uniFullPathName,
6309 if( RtlCompareUnicodeString( &uniComponentName,
6314 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6316 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6317 AFS_TRACE_LEVEL_ERROR,
6318 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
6321 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
6324 uniFullPathName = uniRemainingPath;
6326 uniParsedName = uniFullPathName;
6328 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6330 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6336 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6339 if( pNameArray == NULL)
6342 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6345 pVolumeCB = AFSGlobalRoot;
6347 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6351 // Increment the ref count on the volume and dir entry for correct processing below
6354 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
6356 lCount = AFSVolumeIncrement( pVolumeCB,
6357 VolumeReferenceReason);
6359 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6360 AFS_TRACE_LEVEL_VERBOSE,
6361 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
6363 VolumeReferenceReason,
6366 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6368 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6369 AFS_TRACE_LEVEL_VERBOSE,
6370 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6371 &pParentDirEntry->NameInformation.FileName,
6376 ntStatus = AFSLocateNameEntry( NULL,
6381 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
6385 &NewVolumeReferenceReason,
6386 &pNewParentDirEntry,
6390 if ( pNewVolumeCB != NULL)
6393 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6394 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6395 // the reference on pVolumeCB that was held prior to the call.
6396 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6397 // will be released second.
6400 lCount = AFSVolumeDecrement( pVolumeCB,
6401 VolumeReferenceReason);
6403 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6404 AFS_TRACE_LEVEL_VERBOSE,
6405 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
6407 VolumeReferenceReason,
6410 pVolumeCB = pNewVolumeCB;
6412 pNewVolumeCB = NULL;
6414 VolumeReferenceReason = NewVolumeReferenceReason;
6416 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6420 // AFSLocateNameEntry does not alter the reference count of
6421 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6422 // a reference held.
6425 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6427 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6428 AFS_TRACE_LEVEL_VERBOSE,
6429 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
6430 &pParentDirEntry->NameInformation.FileName,
6434 pParentDirEntry = pNewParentDirEntry;
6436 pNewParentDirEntry = NULL;
6438 if( !NT_SUCCESS( ntStatus) ||
6439 ntStatus == STATUS_REPARSE)
6442 try_return( ntStatus);
6446 // Store off the information
6449 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6452 // Check for the mount point being returned
6455 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
6456 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6459 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6461 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
6464 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6467 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6472 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6476 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6478 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6480 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6482 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6484 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6486 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6490 if( pDirEntry != NULL)
6493 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6496 if( pDirectoryEntry != NULL)
6499 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6501 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6502 AFS_TRACE_LEVEL_VERBOSE,
6503 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6504 &pDirectoryEntry->NameInformation.FileName,
6509 ASSERT( lCount >= 0);
6512 if ( pParentDirEntry != NULL)
6515 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6517 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6518 AFS_TRACE_LEVEL_VERBOSE,
6519 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6520 &pParentDirEntry->NameInformation.FileName,
6525 ASSERT( lCount >= 0);
6528 if( pVolumeCB != NULL)
6531 lCount = AFSVolumeDecrement( pVolumeCB,
6532 VolumeReferenceReason);
6534 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6535 AFS_TRACE_LEVEL_VERBOSE,
6536 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
6538 VolumeReferenceReason,
6542 if( pNameArray != NULL)
6545 AFSFreeNameArray( pNameArray);
6548 if( pwchBuffer != NULL)
6552 // Always free the buffer that we allocated as AFSLocateNameEntry
6553 // will not free it. If uniFullPathName.Buffer was allocated by
6554 // AFSLocateNameEntry, then we must free that as well.
6555 // Check that the uniFullPathName.Buffer in the string is not the same
6556 // offset by the length of the server name
6559 if( uniFullPathName.Length > 0 &&
6560 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6563 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6566 AFSExFreePoolWithTag( pwchBuffer, 0);
6574 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6575 IN ULONGLONG HashIndex)
6578 NTSTATUS ntStatus = STATUS_SUCCESS;
6579 AFSObjectInfoCB *pObjectInfo = NULL;
6585 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6586 sizeof( AFSObjectInfoCB),
6587 AFS_OBJECT_INFO_TAG);
6589 if( pObjectInfo == NULL)
6592 try_return( pObjectInfo);
6595 RtlZeroMemory( pObjectInfo,
6596 sizeof( AFSObjectInfoCB));
6598 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6599 sizeof( AFSNonPagedObjectInfoCB),
6600 AFS_NP_OBJECT_INFO_TAG);
6602 if( pObjectInfo->NonPagedInfo == NULL)
6605 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6607 try_return( pObjectInfo = NULL);
6610 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6612 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6614 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6616 if( ParentObjectInfo != NULL)
6619 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6621 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6623 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6625 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6626 AFS_OBJECT_REFERENCE_CHILD);
6628 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6629 AFS_TRACE_LEVEL_VERBOSE,
6630 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6636 // Initialize the access time
6639 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6644 ASSERT( ParentObjectInfo);
6647 // Insert the entry into the object tree and list
6650 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6652 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6655 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6660 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6661 &pObjectInfo->TreeEntry);
6663 ASSERT( NT_SUCCESS( ntStatus));
6667 // And the object list in the volume
6670 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6673 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6678 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6680 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6683 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6686 // Indicate the object is in the hash tree and linked list in the volume
6689 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6701 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6707 if ( ObjectInfo->ObjectReferenceCount == 0)
6710 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6713 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6718 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6721 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6726 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6728 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6733 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6735 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6741 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6745 LONG lCount, lCount2;
6747 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6750 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6755 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6757 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6759 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6762 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6765 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6767 ASSERT( lCount2 >= 0);
6769 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6775 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6776 IN AFSFileID *FileId)
6778 DWORD ntStatus = STATUS_SUCCESS;
6780 AFSObjectInfoCB *pObjectInfo = NULL;
6782 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6785 pObjectInfo = &VolumeCB->ObjectInformation;
6790 AFSAcquireExcl( VolumeCB->ObjectInfoTree.TreeLock,
6793 ullIndex = AFSCreateLowIndex( FileId);
6795 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6797 (AFSBTreeEntry **)&pObjectInfo);
6799 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6802 if ( NT_SUCCESS( ntStatus)) {
6804 AFSObjectInfoIncrement( pObjectInfo,
6805 AFS_OBJECT_REFERENCE_FIND);
6812 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6815 AFSObjectInfoDecrement( *ppObjectInfo,
6816 AFS_OBJECT_REFERENCE_FIND);
6818 *ppObjectInfo = NULL;
6822 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6825 BOOLEAN bAcquiredTreeLock = FALSE;
6826 AFSObjectInfoCB *pObjectInfo = (*ppObjectInfo);
6827 BOOLEAN bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6828 AFSObjectInfoCB * pParentObjectInfo = NULL;
6832 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_ROOT_VOLUME))
6836 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6837 // embedded in the VolumeCB.
6845 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6847 (*ppObjectInfo) = NULL;
6849 if( !ExIsResourceAcquiredExclusiveLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6852 ASSERT( !ExIsResourceAcquiredLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6854 AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6857 bAcquiredTreeLock = TRUE;
6860 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6863 pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
6864 &pObjectInfo->ParentFileId);
6868 // Remove it from the tree and list if it was inserted
6871 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6874 AFSRemoveHashEntry( &pObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6875 &pObjectInfo->TreeEntry);
6878 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6881 if( pObjectInfo->ListEntry.fLink == NULL)
6884 pObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6886 if( pObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6889 pObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6895 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6898 if( pObjectInfo->ListEntry.bLink == NULL)
6901 pObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6903 if( pObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6906 pObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6912 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6916 if( pParentObjectInfo != NULL)
6919 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6921 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6922 AFS_OBJECT_REFERENCE_CHILD);
6924 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6925 AFS_TRACE_LEVEL_VERBOSE,
6926 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6930 AFSReleaseObjectInfo( &pParentObjectInfo);
6933 if( bAcquiredTreeLock)
6936 AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6942 FileId = pObjectInfo->FileId;
6945 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6947 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6949 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6951 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6954 // Release the fid in the service
6960 AFSReleaseFid( &FileId);
6967 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6968 OUT AFSDirectoryCB **TargetDirEntry)
6971 NTSTATUS ntStatus = STATUS_SUCCESS;
6972 AFSDirEnumEntry *pDirEntry = NULL;
6973 UNICODE_STRING uniFullPathName = {0};
6974 AFSNameArrayHdr *pNameArray = NULL;
6975 AFSVolumeCB *pVolumeCB = NULL;
6976 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6977 AFSVolumeCB *pNewVolumeCB = NULL;
6978 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6979 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6980 AFSDirectoryCB *pNewParentDirEntry = NULL;
6981 WCHAR *pwchBuffer = NULL;
6982 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6983 ULONG ulNameDifference = 0;
6990 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6991 DirectoryCB->ObjectInformation,
6995 if( !NT_SUCCESS( ntStatus))
6997 try_return( ntStatus);
7001 // Retrieve a target name for the entry
7004 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
7007 if( DirectoryCB->NameInformation.TargetName.Length == 0)
7010 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7012 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
7017 if( !NT_SUCCESS( ntStatus) ||
7018 pDirEntry->TargetNameLength == 0)
7021 if( pDirEntry != NULL)
7024 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
7027 try_return( ntStatus);
7030 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
7033 if( DirectoryCB->NameInformation.TargetName.Length == 0)
7037 // Update the target name
7040 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
7041 &DirectoryCB->Flags,
7042 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
7043 (USHORT)pDirEntry->TargetNameLength);
7045 if( !NT_SUCCESS( ntStatus))
7048 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7050 try_return( ntStatus);
7054 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
7058 // Need to pass the full path in for parsing.
7061 uniFullPathName.Length = 0;
7062 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
7064 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7065 uniFullPathName.MaximumLength,
7066 AFS_NAME_BUFFER_EIGHT_TAG);
7068 if( uniFullPathName.Buffer == NULL)
7071 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7073 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7076 pwchBuffer = uniFullPathName.Buffer;
7078 RtlZeroMemory( uniFullPathName.Buffer,
7079 uniFullPathName.MaximumLength);
7081 RtlCopyMemory( uniFullPathName.Buffer,
7082 DirectoryCB->NameInformation.TargetName.Buffer,
7083 DirectoryCB->NameInformation.TargetName.Length);
7085 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
7088 // This name should begin with the \afs server so parse it off and chech it
7091 FsRtlDissectName( uniFullPathName,
7095 if( RtlCompareUnicodeString( &uniComponentName,
7101 // Try evaluating the full path
7104 uniFullPathName.Buffer = pwchBuffer;
7106 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
7108 uniFullPathName.MaximumLength = uniFullPathName.Length;
7113 uniFullPathName = uniRemainingPath;
7116 uniParsedName = uniFullPathName;
7118 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
7120 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7126 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7129 if( pNameArray == NULL)
7132 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7135 pVolumeCB = AFSGlobalRoot;
7137 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7139 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
7141 lCount = AFSVolumeIncrement( pVolumeCB,
7142 VolumeReferenceReason);
7144 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7145 AFS_TRACE_LEVEL_VERBOSE,
7146 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
7148 VolumeReferenceReason,
7151 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
7153 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7154 AFS_TRACE_LEVEL_VERBOSE,
7155 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7156 &pParentDirEntry->NameInformation.FileName,
7161 ntStatus = AFSLocateNameEntry( NULL,
7170 &VolumeReferenceReason,
7171 &pNewParentDirEntry,
7175 if ( pNewVolumeCB != NULL)
7178 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
7179 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
7180 // the reference on pVolumeCB that was held prior to the call.
7181 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
7182 // will be released second.
7185 lCount = AFSVolumeDecrement( pVolumeCB,
7186 VolumeReferenceReason);
7188 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7189 AFS_TRACE_LEVEL_VERBOSE,
7190 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
7192 VolumeReferenceReason,
7195 pVolumeCB = pNewVolumeCB;
7197 pNewVolumeCB = NULL;
7199 VolumeReferenceReason = NewVolumeReferenceReason;
7201 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7205 // AFSLocateNameEntry does not alter the reference count of
7206 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
7207 // a reference held.
7210 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
7212 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7213 AFS_TRACE_LEVEL_VERBOSE,
7214 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
7215 &pParentDirEntry->NameInformation.FileName,
7219 pParentDirEntry = pNewParentDirEntry;
7221 pNewParentDirEntry = NULL;
7223 if( !NT_SUCCESS( ntStatus) ||
7224 ntStatus == STATUS_REPARSE)
7229 try_return( ntStatus);
7233 // Pass back the target dir entry for this request
7234 // The caller must release the DirOpenReferenceCount
7237 *TargetDirEntry = pDirectoryEntry;
7239 pDirectoryEntry = NULL;
7243 if( pDirectoryEntry != NULL)
7246 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
7248 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7249 AFS_TRACE_LEVEL_VERBOSE,
7250 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7251 &pDirectoryEntry->NameInformation.FileName,
7256 ASSERT( lCount >= 0);
7259 if ( pParentDirEntry != NULL)
7262 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
7264 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7265 AFS_TRACE_LEVEL_VERBOSE,
7266 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7267 &pParentDirEntry->NameInformation.FileName,
7272 ASSERT( lCount >= 0);
7275 if( pDirEntry != NULL)
7278 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
7281 if( pVolumeCB != NULL)
7284 lCount = AFSVolumeDecrement( pVolumeCB,
7285 VolumeReferenceReason);
7287 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7288 AFS_TRACE_LEVEL_VERBOSE,
7289 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
7291 VolumeReferenceReason,
7295 if( pNameArray != NULL)
7298 AFSFreeNameArray( pNameArray);
7301 if( pwchBuffer != NULL)
7305 // Always free the buffer that we allocated as AFSLocateNameEntry
7306 // will not free it. If uniFullPathName.Buffer was allocated by
7307 // AFSLocateNameEntry, then we must free that as well.
7308 // Check that the uniFullPathName.Buffer in the string is not the same
7309 // offset by the length of the server name
7312 if( uniFullPathName.Length > 0 &&
7313 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
7316 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
7319 AFSExFreePoolWithTag( pwchBuffer, 0);
7327 AFSCleanupFcb( IN AFSFcb *Fcb,
7328 IN BOOLEAN ForceFlush)
7331 NTSTATUS ntStatus = STATUS_SUCCESS;
7332 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
7333 LARGE_INTEGER liTime;
7334 IO_STATUS_BLOCK stIoStatus;
7339 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7341 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7343 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
7346 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
7347 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7350 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7351 AFS_TRACE_LEVEL_VERBOSE,
7352 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
7353 &Fcb->NPFcb->Resource,
7354 PsGetCurrentThread());
7356 AFSAcquireShared( &Fcb->NPFcb->Resource,
7359 if( Fcb->OpenReferenceCount > 0)
7362 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7363 AFS_TRACE_LEVEL_VERBOSE,
7364 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7365 &Fcb->NPFcb->SectionObjectResource,
7366 PsGetCurrentThread());
7368 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
7374 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7379 if( !NT_SUCCESS( stIoStatus.Status))
7382 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7383 AFS_TRACE_LEVEL_ERROR,
7384 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7385 Fcb->ObjectInformation->FileId.Cell,
7386 Fcb->ObjectInformation->FileId.Volume,
7387 Fcb->ObjectInformation->FileId.Vnode,
7388 Fcb->ObjectInformation->FileId.Unique,
7390 stIoStatus.Information);
7392 ntStatus = stIoStatus.Status;
7395 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7398 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7404 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7405 AFS_TRACE_LEVEL_WARNING,
7406 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
7407 Fcb->ObjectInformation->FileId.Cell,
7408 Fcb->ObjectInformation->FileId.Volume,
7409 Fcb->ObjectInformation->FileId.Vnode,
7410 Fcb->ObjectInformation->FileId.Unique);
7412 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7416 __except( EXCEPTION_EXECUTE_HANDLER)
7419 ntStatus = GetExceptionCode();
7423 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7424 Fcb->ObjectInformation->FileId.Cell,
7425 Fcb->ObjectInformation->FileId.Volume,
7426 Fcb->ObjectInformation->FileId.Vnode,
7427 Fcb->ObjectInformation->FileId.Unique,
7430 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7433 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7434 AFS_TRACE_LEVEL_VERBOSE,
7435 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7436 &Fcb->NPFcb->SectionObjectResource,
7437 PsGetCurrentThread());
7439 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7442 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7443 AFS_TRACE_LEVEL_VERBOSE,
7444 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
7445 &Fcb->NPFcb->Resource,
7446 PsGetCurrentThread());
7448 AFSReleaseResource( &Fcb->NPFcb->Resource);
7451 // Wait for any currently running flush or release requests to complete
7454 AFSWaitOnQueuedFlushes( Fcb);
7457 // Now perform another flush on the file
7460 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7464 AFSReleaseExtentsWithFlush( Fcb,
7470 if( Fcb->OpenReferenceCount == 0 ||
7471 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7472 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7475 AFSTearDownFcbExtents( Fcb,
7479 try_return( ntStatus);
7482 KeQueryTickCount( &liTime);
7485 // First up are there dirty extents in the cache to flush?
7488 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7489 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7493 // The file has been marked as invalid. Dump it
7496 AFSTearDownFcbExtents( Fcb,
7499 else if( ForceFlush ||
7500 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7501 Fcb->Specific.File.ExtentCount) &&
7502 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7503 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7505 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7507 Fcb->OpenReferenceCount == 0)
7510 AFSReleaseExtentsWithFlush( Fcb,
7517 // If there are extents and they haven't been used recently *and*
7518 // are not being used
7522 ( 0 != Fcb->Specific.File.ExtentCount &&
7523 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7524 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7525 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7528 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7529 AFS_TRACE_LEVEL_VERBOSE,
7530 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7531 &Fcb->NPFcb->SectionObjectResource,
7532 PsGetCurrentThread());
7534 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7540 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7545 if( !NT_SUCCESS( stIoStatus.Status))
7548 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7549 AFS_TRACE_LEVEL_ERROR,
7550 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7551 Fcb->ObjectInformation->FileId.Cell,
7552 Fcb->ObjectInformation->FileId.Volume,
7553 Fcb->ObjectInformation->FileId.Vnode,
7554 Fcb->ObjectInformation->FileId.Unique,
7556 stIoStatus.Information);
7558 ntStatus = stIoStatus.Status;
7562 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7565 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7571 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7572 AFS_TRACE_LEVEL_WARNING,
7573 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7574 Fcb->ObjectInformation->FileId.Cell,
7575 Fcb->ObjectInformation->FileId.Volume,
7576 Fcb->ObjectInformation->FileId.Vnode,
7577 Fcb->ObjectInformation->FileId.Unique);
7579 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7583 __except( EXCEPTION_EXECUTE_HANDLER)
7586 ntStatus = GetExceptionCode();
7590 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7591 Fcb->ObjectInformation->FileId.Cell,
7592 Fcb->ObjectInformation->FileId.Volume,
7593 Fcb->ObjectInformation->FileId.Vnode,
7594 Fcb->ObjectInformation->FileId.Unique,
7598 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7599 AFS_TRACE_LEVEL_VERBOSE,
7600 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7601 &Fcb->NPFcb->SectionObjectResource,
7602 PsGetCurrentThread());
7604 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7606 if( Fcb->OpenReferenceCount <= 0)
7610 // Tear em down we'll not be needing them again
7613 AFSTearDownFcbExtents( Fcb,
7620 ntStatus = STATUS_RETRY;
7633 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7634 IN UNICODE_STRING *NewFileName)
7637 NTSTATUS ntStatus = STATUS_SUCCESS;
7638 WCHAR *pTmpBuffer = NULL;
7643 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7646 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7649 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7651 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7653 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7657 // OK, we need to allocate a new name buffer
7660 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7661 NewFileName->Length,
7662 AFS_NAME_BUFFER_NINE_TAG);
7664 if( pTmpBuffer == NULL)
7667 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7670 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7672 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7674 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7677 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7679 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7680 NewFileName->Buffer,
7681 NewFileName->Length);
7692 AFSReadCacheFile( IN void *ReadBuffer,
7693 IN LARGE_INTEGER *ReadOffset,
7694 IN ULONG RequestedDataLength,
7695 IN OUT PULONG BytesRead)
7698 NTSTATUS ntStatus = STATUS_SUCCESS;
7701 PIO_STACK_LOCATION pIoStackLocation = NULL;
7702 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7703 FILE_OBJECT *pCacheFileObject = NULL;
7708 pCacheFileObject = AFSReferenceCacheFileObject();
7710 if( pCacheFileObject == NULL)
7712 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7715 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7718 // Initialize the event
7721 KeInitializeEvent( &kEvent,
7722 SynchronizationEvent,
7726 // Allocate an irp for this request. This could also come from a
7727 // private pool, for instance.
7730 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7736 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7740 // Build the IRP's main body
7743 pIrp->UserBuffer = ReadBuffer;
7745 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7746 pIrp->RequestorMode = KernelMode;
7747 pIrp->Flags |= IRP_READ_OPERATION;
7750 // Set up the I/O stack location.
7753 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7754 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7755 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7756 pIoStackLocation->FileObject = pCacheFileObject;
7757 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7759 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7762 // Set the completion routine.
7765 IoSetCompletionRoutine( pIrp,
7773 // Send it to the FSD
7776 ntStatus = IoCallDriver( pTargetDeviceObject,
7779 if( NT_SUCCESS( ntStatus))
7786 ntStatus = KeWaitForSingleObject( &kEvent,
7792 if( NT_SUCCESS( ntStatus))
7795 ntStatus = pIrp->IoStatus.Status;
7797 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7803 if( pCacheFileObject != NULL)
7805 AFSReleaseCacheFileObject( pCacheFileObject);
7811 if( pIrp->MdlAddress != NULL)
7814 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7817 MmUnlockPages( pIrp->MdlAddress);
7820 IoFreeMdl( pIrp->MdlAddress);
7823 pIrp->MdlAddress = NULL;
7837 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7842 UNREFERENCED_PARAMETER(Irp);
7843 UNREFERENCED_PARAMETER(DeviceObject);
7844 KEVENT *pEvent = (KEVENT *)Context;
7850 return STATUS_MORE_PROCESSING_REQUIRED;
7854 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7857 BOOLEAN bIsEmpty = FALSE;
7858 AFSDirectoryCB *pDirEntry = NULL;
7863 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7868 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7871 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7873 while( pDirEntry != NULL)
7876 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7877 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7885 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7890 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7897 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7898 IN AFSDirectoryCB *DirEntry)
7901 NTSTATUS ntStatus = STATUS_SUCCESS;
7906 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7909 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7910 AFS_TRACE_LEVEL_VERBOSE,
7911 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7913 &DirEntry->NameInformation.FileName);
7915 try_return( ntStatus);
7918 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7921 // Remove the entry from the parent tree
7924 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7925 AFS_TRACE_LEVEL_VERBOSE,
7926 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7928 &DirEntry->NameInformation.FileName);
7930 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7933 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7934 AFS_TRACE_LEVEL_VERBOSE,
7935 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7937 &DirEntry->NameInformation.FileName);
7939 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7942 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7946 // From the short name tree
7949 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7950 AFS_TRACE_LEVEL_VERBOSE,
7951 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7953 &DirEntry->NameInformation.FileName);
7955 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7958 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7961 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7962 AFS_TRACE_LEVEL_VERBOSE,
7963 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7965 &DirEntry->NameInformation.FileName);
7967 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7969 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7980 AFSGetAuthenticationId()
7983 LARGE_INTEGER liAuthId = {0,0};
7984 NTSTATUS ntStatus = STATUS_SUCCESS;
7985 PACCESS_TOKEN hToken = NULL;
7986 PTOKEN_STATISTICS pTokenInfo = NULL;
7987 BOOLEAN bCopyOnOpen = FALSE;
7988 BOOLEAN bEffectiveOnly = FALSE;
7989 BOOLEAN bPrimaryToken = FALSE;
7990 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7995 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7998 &stImpersonationLevel);
8003 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
8008 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
8009 AFS_TRACE_LEVEL_ERROR,
8010 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
8012 try_return( ntStatus);
8015 bPrimaryToken = TRUE;
8018 ntStatus = SeQueryInformationToken( hToken,
8020 (PVOID *)&pTokenInfo);
8022 if( !NT_SUCCESS( ntStatus))
8025 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
8026 AFS_TRACE_LEVEL_ERROR,
8027 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
8029 try_return( ntStatus);
8032 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
8033 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
8035 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
8036 AFS_TRACE_LEVEL_VERBOSE,
8037 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
8048 PsDereferenceImpersonationToken( hToken);
8053 PsDereferencePrimaryToken( hToken);
8057 if( pTokenInfo != NULL)
8060 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
8068 AFSUnwindFileInfo( IN AFSFcb *Fcb,
8072 UNREFERENCED_PARAMETER(Fcb);
8073 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
8075 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
8078 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
8080 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
8083 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
8085 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
8088 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
8090 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
8093 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
8095 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
8102 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
8105 BOOLEAN bIsValid = TRUE;
8107 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
8109 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
8111 while( pCurrentDirEntry != NULL)
8114 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
8118 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
8123 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8124 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
8127 if( pDirEntry == NULL)
8134 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
8137 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
8140 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
8142 ObjectInfo->Specific.Directory.DirectoryNodeCount);
8144 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
8153 AFSReferenceCacheFileObject()
8156 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8157 FILE_OBJECT *pCacheFileObject = NULL;
8159 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
8162 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
8164 if( pCacheFileObject != NULL)
8166 ObReferenceObject( pCacheFileObject);
8169 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
8171 return pCacheFileObject;
8175 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
8178 ASSERT( CacheFileObject != NULL);
8180 ObDereferenceObject( CacheFileObject);
8186 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
8189 NTSTATUS ntStatus = STATUS_SUCCESS;
8190 AFSDeviceExt *pControlDevExt = NULL;
8191 ULONG ulTimeIncrement = 0;
8197 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
8199 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
8201 AFSServerName = LibraryInit->AFSServerName;
8203 AFSMountRootName = LibraryInit->AFSMountRootName;
8205 AFSDebugFlags = LibraryInit->AFSDebugFlags;
8208 // Callbacks in the framework
8211 AFSProcessRequest = LibraryInit->AFSProcessRequest;
8213 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
8215 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
8217 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
8219 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
8221 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
8223 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
8225 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
8227 if( LibraryInit->AFSCacheBaseAddress != NULL)
8230 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
8232 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
8234 AFSLibCacheLength = LibraryInit->AFSCacheLength;
8238 // Initialize some flush parameters
8241 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
8243 ulTimeIncrement = KeQueryTimeIncrement();
8245 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
8246 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
8247 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
8248 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
8249 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
8252 // Initialize the global root entry
8255 ntStatus = AFSInitVolume( NULL,
8256 &LibraryInit->GlobalRootFid,
8257 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
8260 if( !NT_SUCCESS( ntStatus))
8263 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8264 AFS_TRACE_LEVEL_ERROR,
8265 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
8268 try_return( ntStatus);
8271 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
8274 if( !NT_SUCCESS( ntStatus))
8277 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8278 AFS_TRACE_LEVEL_ERROR,
8279 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
8282 lCount = AFSVolumeDecrement( AFSGlobalRoot,
8283 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
8285 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8286 AFS_TRACE_LEVEL_VERBOSE,
8287 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8291 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8293 try_return( ntStatus);
8297 // Update the node type code to AFS_ROOT_ALL
8300 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
8302 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
8305 // Invalidate all known volumes since contact with the service and therefore
8306 // the file server was lost.
8309 AFSInvalidateAllVolumes();
8312 // Drop the locks acquired above
8315 AFSInitVolumeWorker( AFSGlobalRoot);
8317 lCount = AFSVolumeDecrement( AFSGlobalRoot,
8318 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
8320 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8321 AFS_TRACE_LEVEL_VERBOSE,
8322 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8326 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8328 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
8342 NTSTATUS ntStatus = STATUS_SUCCESS;
8343 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
8349 if( AFSGlobalDotDirEntry != NULL)
8352 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
8353 AFS_OBJECT_REFERENCE_GLOBAL);
8355 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
8357 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
8359 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
8361 ExFreePool( AFSGlobalDotDirEntry);
8363 AFSGlobalDotDirEntry = NULL;
8366 if( AFSGlobalDotDotDirEntry != NULL)
8369 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
8370 AFS_OBJECT_REFERENCE_GLOBAL);
8372 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
8374 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
8376 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
8378 ExFreePool( AFSGlobalDotDotDirEntry);
8380 AFSGlobalDotDotDirEntry = NULL;
8383 if( AFSSpecialShareNames != NULL)
8386 pDirNode = AFSSpecialShareNames;
8388 while( pDirNode != NULL)
8391 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
8393 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
8394 AFS_OBJECT_REFERENCE_GLOBAL);
8396 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
8398 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
8400 ExFreePool( pDirNode->NonPaged);
8402 ExFreePool( pDirNode);
8404 pDirNode = pLastDirNode;
8407 AFSSpecialShareNames = NULL;
8415 AFSDefaultLogMsg( IN ULONG Subsystem,
8421 UNREFERENCED_PARAMETER(Subsystem);
8422 UNREFERENCED_PARAMETER(Level);
8423 NTSTATUS ntStatus = STATUS_SUCCESS;
8425 char chDebugBuffer[ 256];
8430 va_start( va_args, Format);
8432 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8437 if( NT_SUCCESS( ntStatus))
8439 DbgPrint( chDebugBuffer);
8449 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8450 IN ULONG InputBufferLength,
8451 IN AFSStatusInfoCB *StatusInfo,
8452 OUT ULONG *ReturnLength)
8455 NTSTATUS ntStatus = STATUS_SUCCESS;
8456 AFSVolumeCB *pVolumeCB = NULL;
8457 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8458 AFSVolumeCB *pNewVolumeCB = NULL;
8459 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8460 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8461 AFSObjectInfoCB *pObjectInfo = NULL;
8462 ULONGLONG ullIndex = 0;
8463 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8464 AFSNameArrayHdr *pNameArray = NULL;
8465 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8466 AFSDirectoryCB *pNewParentDirEntry = NULL;
8473 // If we are given a FID then look up the entry by that, otherwise
8477 if( GetStatusInfo->FileID.Cell != 0 &&
8478 GetStatusInfo->FileID.Volume != 0 &&
8479 GetStatusInfo->FileID.Vnode != 0 &&
8480 GetStatusInfo->FileID.Unique != 0)
8483 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8486 // Locate the volume node
8489 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8491 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8493 (AFSBTreeEntry **)&pVolumeCB);
8495 if( pVolumeCB != NULL)
8498 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8500 lCount = AFSVolumeIncrement( pVolumeCB,
8501 VolumeReferenceReason);
8503 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8504 AFS_TRACE_LEVEL_VERBOSE,
8505 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
8507 VolumeReferenceReason,
8511 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8513 if( !NT_SUCCESS( ntStatus) ||
8516 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8519 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8522 pObjectInfo = &pVolumeCB->ObjectInformation;
8524 lCount = AFSObjectInfoIncrement( pObjectInfo,
8525 AFS_OBJECT_REFERENCE_STATUS);
8527 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8528 AFS_TRACE_LEVEL_VERBOSE,
8529 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8536 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8539 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8541 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8543 (AFSBTreeEntry **)&pObjectInfo);
8545 if( pObjectInfo != NULL)
8549 // Reference the node so it won't be torn down
8552 lCount = AFSObjectInfoIncrement( pObjectInfo,
8553 AFS_OBJECT_REFERENCE_STATUS);
8555 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8556 AFS_TRACE_LEVEL_VERBOSE,
8557 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8562 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8564 if( !NT_SUCCESS( ntStatus) ||
8565 pObjectInfo == NULL)
8567 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8574 if( GetStatusInfo->FileNameLength == 0 ||
8575 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8577 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8580 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8581 uniFullPathName.MaximumLength = uniFullPathName.Length;
8583 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8586 // This name should begin with the \afs server so parse it off and check it
8589 FsRtlDissectName( uniFullPathName,
8593 if( RtlCompareUnicodeString( &uniComponentName,
8597 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8598 AFS_TRACE_LEVEL_ERROR,
8599 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8602 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8605 uniFullPathName = uniRemainingPath;
8607 uniParsedName = uniFullPathName;
8613 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8616 if( pNameArray == NULL)
8618 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8621 pVolumeCB = AFSGlobalRoot;
8623 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8626 // Increment the ref count on the volume and dir entry for correct processing below
8629 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8631 lCount = AFSVolumeIncrement( pVolumeCB,
8632 VolumeReferenceReason);
8634 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8635 AFS_TRACE_LEVEL_VERBOSE,
8636 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8638 VolumeReferenceReason,
8641 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8643 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8644 AFS_TRACE_LEVEL_VERBOSE,
8645 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8646 &pParentDirEntry->NameInformation.FileName,
8651 ntStatus = AFSLocateNameEntry( NULL,
8656 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8657 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8661 &NewVolumeReferenceReason,
8662 &pNewParentDirEntry,
8666 if ( pNewVolumeCB != NULL)
8670 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8671 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8672 // the reference on pVolumeCB that was held prior to the call.
8673 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8674 // will be released second.
8677 lCount = AFSVolumeDecrement( pVolumeCB,
8678 VolumeReferenceReason);
8680 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8681 AFS_TRACE_LEVEL_VERBOSE,
8682 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8684 VolumeReferenceReason,
8687 pVolumeCB = pNewVolumeCB;
8689 pNewVolumeCB = NULL;
8691 VolumeReferenceReason = NewVolumeReferenceReason;
8693 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8697 // AFSLocateNameEntry does not alter the reference count of
8698 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8699 // a reference held.
8702 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8704 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8705 AFS_TRACE_LEVEL_VERBOSE,
8706 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8707 &pParentDirEntry->NameInformation.FileName,
8711 pParentDirEntry = pNewParentDirEntry;
8713 pNewParentDirEntry = NULL;
8715 if( !NT_SUCCESS( ntStatus) ||
8716 ntStatus == STATUS_REPARSE)
8721 try_return( ntStatus);
8724 pObjectInfo = pDirectoryEntry->ObjectInformation;
8726 lCount = AFSObjectInfoIncrement( pObjectInfo,
8727 AFS_OBJECT_REFERENCE_STATUS);
8729 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8730 AFS_TRACE_LEVEL_VERBOSE,
8731 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8737 // At this point we have an object info block, return the information
8740 StatusInfo->FileId = pObjectInfo->FileId;
8742 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8744 StatusInfo->Expiration = pObjectInfo->Expiration;
8746 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8748 StatusInfo->FileType = pObjectInfo->FileType;
8750 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8752 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8754 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8756 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8758 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8760 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8762 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8764 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8766 StatusInfo->EaSize = pObjectInfo->EaSize;
8768 StatusInfo->Links = pObjectInfo->Links;
8771 // Return the information length
8774 *ReturnLength = sizeof( AFSStatusInfoCB);
8778 if( pDirectoryEntry != NULL)
8781 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8783 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8784 AFS_TRACE_LEVEL_VERBOSE,
8785 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8786 &pDirectoryEntry->NameInformation.FileName,
8791 ASSERT( lCount >= 0);
8794 if ( pParentDirEntry != NULL)
8797 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8799 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8800 AFS_TRACE_LEVEL_VERBOSE,
8801 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8802 &pParentDirEntry->NameInformation.FileName,
8807 ASSERT( lCount >= 0);
8810 if( pObjectInfo != NULL)
8813 lCount = AFSObjectInfoDecrement( pObjectInfo,
8814 AFS_OBJECT_REFERENCE_STATUS);
8816 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8817 AFS_TRACE_LEVEL_VERBOSE,
8818 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8823 if( pVolumeCB != NULL)
8826 lCount = AFSVolumeDecrement( pVolumeCB,
8827 VolumeReferenceReason);
8829 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8830 AFS_TRACE_LEVEL_VERBOSE,
8831 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8833 VolumeReferenceReason,
8837 if( pNameArray != NULL)
8840 AFSFreeNameArray( pNameArray);
8848 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8849 IN UNICODE_STRING *ComponentName)
8852 NTSTATUS ntStatus = STATUS_SUCCESS;
8853 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8854 AFSDirectoryCB *pDirEntry = NULL;
8862 // Search for the entry in the parent
8865 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8866 AFS_TRACE_LEVEL_VERBOSE_2,
8867 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8870 ulCRC = AFSGenerateCRC( ComponentName,
8873 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8876 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8880 if( pDirEntry == NULL)
8884 // Missed so perform a case insensitive lookup
8887 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8888 AFS_TRACE_LEVEL_VERBOSE_2,
8889 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8892 ulCRC = AFSGenerateCRC( ComponentName,
8895 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8899 if( pDirEntry == NULL)
8903 // OK, if this component is a valid short name then try
8904 // a lookup in the short name tree
8907 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8908 RtlIsNameLegalDOS8Dot3( ComponentName,
8913 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8914 AFS_TRACE_LEVEL_VERBOSE_2,
8915 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8918 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8925 if( pDirEntry != NULL)
8927 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8929 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8930 AFS_TRACE_LEVEL_VERBOSE,
8931 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8932 &pDirEntry->NameInformation.FileName,
8937 ASSERT( lCount >= 0);
8940 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8942 if( pDirEntry == NULL)
8945 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8946 AFS_TRACE_LEVEL_VERBOSE_2,
8947 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8949 STATUS_OBJECT_NAME_NOT_FOUND);
8951 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8955 // We have the symlink object but previously failed to process it so return access
8959 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8960 AFS_TRACE_LEVEL_VERBOSE_2,
8961 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8964 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8966 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8968 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8969 AFS_TRACE_LEVEL_VERBOSE,
8970 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8971 &pDirEntry->NameInformation.FileName,
8976 ASSERT( lCount >= 0);
8987 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8988 OUT UNICODE_STRING *ComponentName)
8991 NTSTATUS ntStatus = STATUS_SUCCESS;
8992 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8994 uniFullPathName = *FullPathName;
8999 FsRtlDissectName( uniFullPathName,
9003 if( uniRemainingPath.Length == 0)
9008 uniFullPathName = uniRemainingPath;
9011 if( uniComponentName.Length > 0)
9013 *ComponentName = uniComponentName;
9020 AFSDumpTraceFiles_Default()
9026 AFSValidNameFormat( IN UNICODE_STRING *FileName)
9029 BOOLEAN bIsValidName = TRUE;
9035 while( usIndex < FileName->Length/sizeof( WCHAR))
9038 if( FileName->Buffer[ usIndex] == L':' ||
9039 FileName->Buffer[ usIndex] == L'*' ||
9040 FileName->Buffer[ usIndex] == L'?' ||
9041 FileName->Buffer[ usIndex] == L'"' ||
9042 FileName->Buffer[ usIndex] == L'<' ||
9043 FileName->Buffer[ usIndex] == L'>')
9045 bIsValidName = FALSE;
9053 return bIsValidName;
9057 AFSCreateDefaultSecurityDescriptor()
9060 NTSTATUS ntStatus = STATUS_SUCCESS;
9062 ULONG ulSACLSize = 0;
9063 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
9064 ULONG ulACESize = 0;
9065 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
9066 ULONG ulSDLength = 0;
9067 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
9068 PSID pWorldSID = NULL;
9069 ULONG *pulSubAuthority = NULL;
9070 ULONG ulWorldSIDLEngth = 0;
9075 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
9077 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
9079 AFS_GENERIC_MEMORY_29_TAG);
9081 if( pWorldSID == NULL)
9083 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
9084 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9087 RtlZeroMemory( pWorldSID,
9090 RtlInitializeSid( pWorldSID,
9091 &SeWorldSidAuthority,
9094 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
9095 *pulSubAuthority = SECURITY_WORLD_RID;
9097 if( AFSRtlSetSaclSecurityDescriptor == NULL)
9100 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
9105 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
9107 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
9109 AFS_GENERIC_MEMORY_29_TAG);
9114 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
9116 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9119 RtlZeroMemory( pACE,
9122 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
9123 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
9124 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
9125 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
9127 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
9129 SeExports->SeLowMandatorySid);
9131 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
9132 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
9134 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
9136 AFS_GENERIC_MEMORY_29_TAG);
9141 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
9143 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9146 ntStatus = RtlCreateAcl( pSACL,
9150 if( !NT_SUCCESS( ntStatus))
9153 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
9156 try_return( ntStatus);
9159 ntStatus = RtlAddAce( pSACL,
9163 pACE->Header.AceSize);
9165 if( !NT_SUCCESS( ntStatus))
9168 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
9171 try_return( ntStatus);
9175 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
9176 sizeof( SECURITY_DESCRIPTOR),
9177 AFS_GENERIC_MEMORY_27_TAG);
9179 if( pSecurityDescr == NULL)
9182 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9184 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9187 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
9188 SECURITY_DESCRIPTOR_REVISION);
9190 if( !NT_SUCCESS( ntStatus))
9193 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
9196 try_return( ntStatus);
9199 if( AFSRtlSetSaclSecurityDescriptor != NULL)
9201 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
9206 if( !NT_SUCCESS( ntStatus))
9209 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
9212 try_return( ntStatus);
9217 // Add in the group and owner to the SD
9220 if( AFSRtlSetGroupSecurityDescriptor != NULL)
9222 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
9226 if( !NT_SUCCESS( ntStatus))
9229 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
9232 try_return( ntStatus);
9236 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
9240 if( !NT_SUCCESS( ntStatus))
9243 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
9246 try_return( ntStatus);
9249 if( !RtlValidSecurityDescriptor( pSecurityDescr))
9252 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
9254 try_return( ntStatus = STATUS_INVALID_PARAMETER);
9257 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
9259 AFS_GENERIC_MEMORY_27_TAG);
9261 if( pRelativeSecurityDescr == NULL)
9264 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9266 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9269 ulSDLength = PAGE_SIZE;
9271 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
9272 pRelativeSecurityDescr,
9275 if( !NT_SUCCESS( ntStatus))
9278 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
9281 try_return( ntStatus);
9284 AFSDefaultSD = pRelativeSecurityDescr;
9288 if( !NT_SUCCESS( ntStatus))
9291 if( pRelativeSecurityDescr != NULL)
9293 ExFreePool( pRelativeSecurityDescr);
9297 if( pSecurityDescr != NULL)
9299 ExFreePool( pSecurityDescr);
9312 if( pWorldSID != NULL)
9314 ExFreePool( pWorldSID);
9322 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
9323 OUT UNICODE_STRING *ParentPath)
9326 *ParentPath = *FullFileName;
9329 // If the final character is a \, jump over it
9332 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
9334 ParentPath->Length -= sizeof( WCHAR);
9337 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
9339 ParentPath->Length -= sizeof( WCHAR);
9343 // And the separator
9346 ParentPath->Length -= sizeof( WCHAR);
9352 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
9353 IN AFSObjectInfoCB *ObjectInfo,
9354 IN BOOLEAN WriteAccess,
9355 OUT GUID *AuthGroup)
9358 NTSTATUS ntStatus = STATUS_SUCCESS;
9359 GUID stAuthGroup, stZeroAuthGroup;
9360 BOOLEAN bFoundAuthGroup = FALSE;
9361 AFSCcb *pCcb = NULL;
9367 RtlZeroMemory( &stAuthGroup,
9370 RtlZeroMemory( &stZeroAuthGroup,
9376 if( ObjectInfo != NULL &&
9377 ObjectInfo->Fcb != NULL)
9379 pFcb = ObjectInfo->Fcb;
9386 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
9389 pCcb = Fcb->CcbListHead;
9391 while( pCcb != NULL)
9395 pCcb->GrantedAccess & FILE_WRITE_DATA)
9397 RtlCopyMemory( &stAuthGroup,
9401 bFoundAuthGroup = TRUE;
9405 else if( pCcb->GrantedAccess & FILE_READ_DATA)
9408 // At least get the read-only access
9411 RtlCopyMemory( &stAuthGroup,
9415 bFoundAuthGroup = TRUE;
9418 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9421 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9424 if( !bFoundAuthGroup)
9427 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9428 (ULONGLONG)PsGetCurrentThreadId(),
9431 if( RtlCompareMemory( &stZeroAuthGroup,
9433 sizeof( GUID)) == sizeof( GUID))
9436 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9438 try_return( ntStatus = STATUS_ACCESS_DENIED);
9442 RtlCopyMemory( AuthGroup,
9455 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9456 IN ULONG InvalidateReason)
9459 NTSTATUS ntStatus = STATUS_SUCCESS;
9462 ULONG ulProcessCount = 0;
9469 switch( InvalidateReason)
9472 case AFS_INVALIDATE_DELETED:
9475 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9476 ObjectInfo->Fcb != NULL)
9479 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9482 ObjectInfo->Links = 0;
9484 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9486 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9491 // Clear out the extents
9492 // And get rid of them (note this involves waiting
9493 // for any writes or reads to the cache to complete)
9496 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9499 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9505 case AFS_INVALIDATE_DATA_VERSION:
9508 LARGE_INTEGER liCurrentOffset = {0,0};
9509 LARGE_INTEGER liFlushLength = {0,0};
9510 ULONG ulFlushLength = 0;
9511 BOOLEAN bLocked = FALSE;
9512 BOOLEAN bExtentsLocked = FALSE;
9513 BOOLEAN bCleanExtents = FALSE;
9515 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9516 ObjectInfo->Fcb != NULL)
9519 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9524 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9525 AFS_TRACE_LEVEL_VERBOSE,
9526 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9527 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9528 PsGetCurrentThread());
9530 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9533 bExtentsLocked = TRUE;
9536 // There are several possibilities here:
9538 // 0. If there are no extents or all of the extents are dirty, do nothing.
9540 // 1. There could be nothing dirty and an open reference count of zero
9541 // in which case we can just tear down all of the extents without
9542 // holding any resources.
9544 // 2. There could be nothing dirty and a non-zero open reference count
9545 // in which case we can issue a CcPurge against the entire file
9546 // while holding just the Fcb Resource.
9548 // 3. There can be dirty extents in which case we need to identify
9549 // the non-dirty ranges and then perform a CcPurge on just the
9550 // non-dirty ranges while holding just the Fcb Resource.
9553 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9556 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9559 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9561 bExtentsLocked = FALSE;
9563 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9566 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9570 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9576 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9577 AFS_TRACE_LEVEL_VERBOSE,
9578 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9579 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9580 PsGetCurrentThread());
9582 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9585 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9592 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9593 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9599 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9600 AFS_TRACE_LEVEL_WARNING,
9601 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9602 ObjectInfo->FileId.Cell,
9603 ObjectInfo->FileId.Volume,
9604 ObjectInfo->FileId.Vnode,
9605 ObjectInfo->FileId.Unique);
9607 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9612 bCleanExtents = TRUE;
9615 __except( EXCEPTION_EXECUTE_HANDLER)
9618 ntStatus = GetExceptionCode();
9622 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9623 ObjectInfo->FileId.Cell,
9624 ObjectInfo->FileId.Volume,
9625 ObjectInfo->FileId.Vnode,
9626 ObjectInfo->FileId.Unique,
9629 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9632 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9633 AFS_TRACE_LEVEL_VERBOSE,
9634 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9635 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9636 PsGetCurrentThread());
9638 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9644 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9646 bExtentsLocked = FALSE;
9648 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9649 AFS_TRACE_LEVEL_VERBOSE,
9650 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9651 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9652 PsGetCurrentThread());
9654 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9657 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9662 // Must build a list of non-dirty ranges from the beginning of the file
9663 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9664 // ranges. In all but the most extreme random data write scenario there will
9665 // be significantly fewer.
9667 // For each range we need offset and size.
9670 AFSByteRange * ByteRangeList = NULL;
9671 ULONG ulByteRangeCount = 0;
9673 BOOLEAN bPurgeOnClose = FALSE;
9678 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9681 if ( ByteRangeList != NULL ||
9682 ulByteRangeCount == 0)
9685 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9692 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9694 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9695 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9696 &ByteRangeList[ulIndex].FileOffset,
9701 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9702 AFS_TRACE_LEVEL_WARNING,
9703 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9704 ObjectInfo->FileId.Cell,
9705 ObjectInfo->FileId.Volume,
9706 ObjectInfo->FileId.Vnode,
9707 ObjectInfo->FileId.Unique);
9709 bPurgeOnClose = TRUE;
9714 bCleanExtents = TRUE;
9717 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9719 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9721 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9728 // We couldn't allocate the memory to build the purge list
9729 // so just walk the extent list while holding the ExtentsList Resource.
9730 // This could deadlock but we do not have much choice.
9733 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9735 bExtentsLocked = TRUE;
9737 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9741 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9745 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9747 while( ulProcessCount < ulCount)
9749 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9751 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9753 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9754 &pEntry->FileOffset,
9759 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9760 AFS_TRACE_LEVEL_WARNING,
9761 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9762 ObjectInfo->FileId.Cell,
9763 ObjectInfo->FileId.Volume,
9764 ObjectInfo->FileId.Vnode,
9765 ObjectInfo->FileId.Unique);
9767 bPurgeOnClose = TRUE;
9772 bCleanExtents = TRUE;
9776 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9779 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9781 while( liFlushLength.QuadPart > 0)
9784 if( liFlushLength.QuadPart > 512 * 1024000)
9786 ulFlushLength = 512 * 1024000;
9790 ulFlushLength = liFlushLength.LowPart;
9793 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9799 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9800 AFS_TRACE_LEVEL_WARNING,
9801 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9802 ObjectInfo->FileId.Cell,
9803 ObjectInfo->FileId.Volume,
9804 ObjectInfo->FileId.Vnode,
9805 ObjectInfo->FileId.Unique);
9807 bPurgeOnClose = TRUE;
9812 bCleanExtents = TRUE;
9815 liFlushLength.QuadPart -= ulFlushLength;
9819 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9827 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9833 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9834 AFS_TRACE_LEVEL_WARNING,
9835 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9836 ObjectInfo->FileId.Cell,
9837 ObjectInfo->FileId.Volume,
9838 ObjectInfo->FileId.Vnode,
9839 ObjectInfo->FileId.Unique);
9841 bPurgeOnClose = TRUE;
9846 bCleanExtents = TRUE;
9853 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9857 __except( EXCEPTION_EXECUTE_HANDLER)
9860 ntStatus = GetExceptionCode();
9864 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9865 ObjectInfo->FileId.Cell,
9866 ObjectInfo->FileId.Volume,
9867 ObjectInfo->FileId.Vnode,
9868 ObjectInfo->FileId.Unique,
9872 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9873 AFS_TRACE_LEVEL_VERBOSE,
9874 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9875 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9876 PsGetCurrentThread());
9878 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9882 if ( bExtentsLocked)
9885 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9891 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9897 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9907 // Destroy the reference passed in by the caller to AFSInvalidateObject
9908 // or AFSQueueInvalidateObject
9911 lCount = AFSObjectInfoDecrement( ObjectInfo,
9912 AFS_OBJECT_REFERENCE_INVALIDATION);
9914 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9915 AFS_TRACE_LEVEL_VERBOSE,
9916 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",