2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSGeneric.cpp
39 #include "AFSCommon.h"
42 // Function: AFSExceptionFilter
46 // This function is the exception handler
50 // A status is returned for the function
54 AFSExceptionFilter( IN CHAR *FunctionString,
56 IN PEXCEPTION_POINTERS ExceptPtrs)
59 UNREFERENCED_PARAMETER(Code);
60 PEXCEPTION_RECORD ExceptRec;
66 ExceptRec = ExceptPtrs->ExceptionRecord;
68 Context = ExceptPtrs->ContextRecord;
72 "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
76 ExceptRec->ExceptionCode,
77 ExceptRec->ExceptionAddress,
78 (void *)AFSExceptionFilter);
80 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
82 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
83 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
85 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
87 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
90 KeBugCheck( (ULONG)-2);
98 __except( EXCEPTION_EXECUTE_HANDLER)
104 return EXCEPTION_EXECUTE_HANDLER;
108 // Function: AFSLibExAllocatePoolWithTag()
110 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
111 // is configured on, then bugcheck the system if
112 // a memory allocation fails. The routine should be
113 // used for all memory allocations that are to be freed
114 // when the library is unloaded. Memory allocations that
115 // are to survive library unload and reload should be
116 // performed using AFSExAllocatePoolWithTag() which is
117 // provided by the AFS Framework.
120 // POOL_TYPE PoolType - Paged or NonPaged
121 // SIZE_T NumberOfBytes - requested allocation size
122 // ULONG Tag - Pool Allocation Tag to be applied for tracking
125 // void * - the memory allocation
129 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
130 IN SIZE_T NumberOfBytes,
134 void *pBuffer = NULL;
136 pBuffer = ExAllocatePoolWithTag( PoolType,
143 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
146 KeBugCheck( (ULONG)-2);
153 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
157 PsGetCurrentThread());
167 // Function: AFSAcquireExcl()
169 // Purpose: Called to acquire a resource exclusive with optional wait
172 // PERESOURCE Resource - Resource to acquire
173 // BOOLEAN Wait - Whether to block
176 // BOOLEAN - Whether the mask was acquired
180 AFSAcquireExcl( IN PERESOURCE Resource,
184 BOOLEAN bStatus = FALSE;
187 // Normal kernel APCs must be disabled before calling
188 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
191 KeEnterCriticalRegion();
193 bStatus = ExAcquireResourceExclusiveLite( Resource,
199 KeLeaveCriticalRegion();
206 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
210 BOOLEAN bStatus = FALSE;
212 KeEnterCriticalRegion();
214 bStatus = ExAcquireSharedStarveExclusive( Resource,
220 KeLeaveCriticalRegion();
227 // Function: AFSAcquireShared()
229 // Purpose: Called to acquire a resource shared with optional wait
232 // PERESOURCE Resource - Resource to acquire
233 // BOOLEAN Wait - Whether to block
236 // BOOLEAN - Whether the mask was acquired
240 AFSAcquireShared( IN PERESOURCE Resource,
244 BOOLEAN bStatus = FALSE;
246 KeEnterCriticalRegion();
248 bStatus = ExAcquireResourceSharedLite( Resource,
254 KeLeaveCriticalRegion();
261 // Function: AFSReleaseResource()
263 // Purpose: Called to release a resource
266 // PERESOURCE Resource - Resource to release
273 AFSReleaseResource( IN PERESOURCE Resource)
276 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
277 AFS_TRACE_LEVEL_VERBOSE,
278 "AFSReleaseResource Releasing lock %p Thread %08lX\n",
280 PsGetCurrentThread());
282 ExReleaseResourceLite( Resource);
284 KeLeaveCriticalRegion();
290 AFSConvertToShared( IN PERESOURCE Resource)
293 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
294 AFS_TRACE_LEVEL_VERBOSE,
295 "AFSConvertToShared Converting lock %p Thread %08lX\n",
297 PsGetCurrentThread());
299 ExConvertExclusiveToSharedLite( Resource);
305 // Function: AFSCompleteRequest
309 // This function completes irps
313 // A status is returned for the function
317 AFSCompleteRequest( IN PIRP Irp,
321 Irp->IoStatus.Status = Status;
323 IoCompleteRequest( Irp,
330 // Function: AFSGenerateCRC
334 // Given a device and filename this function generates a CRC
338 // A status is returned for the function
342 AFSGenerateCRC( IN PUNICODE_STRING FileName,
343 IN BOOLEAN UpperCaseName)
347 NTSTATUS ntStatus = STATUS_SUCCESS;
349 ntStatus = RtlHashUnicodeString( FileName,
351 HASH_STRING_ALGORITHM_DEFAULT,
354 if( !NT_SUCCESS( ntStatus))
363 AFSLockSystemBuffer( IN PIRP Irp,
367 void *pAddress = NULL;
369 if( Irp->MdlAddress != NULL)
372 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
375 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
378 pAddress = Irp->AssociatedIrp.SystemBuffer;
380 else if( Irp->UserBuffer != NULL)
383 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
389 if( Irp->MdlAddress != NULL)
393 // Lock the new Mdl in memory.
398 PIO_STACK_LOCATION pIoStack;
399 pIoStack = IoGetCurrentIrpStackLocation( Irp);
402 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
403 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
405 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
408 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
411 AFSDumpTraceFilesFnc();
413 IoFreeMdl( Irp->MdlAddress );
414 Irp->MdlAddress = NULL;
424 AFSLockUserBuffer( IN void *UserBuffer,
425 IN ULONG BufferLength,
429 NTSTATUS ntStatus = STATUS_SUCCESS;
430 void *pAddress = NULL;
436 pMdl = IoAllocateMdl( UserBuffer,
445 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
449 // Lock the new Mdl in memory.
455 MmProbeAndLockPages( pMdl,
459 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
462 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
465 AFSDumpTraceFilesFnc();
487 AFSMapToService( IN PIRP Irp,
491 NTSTATUS ntStatus = STATUS_SUCCESS;
492 void *pMappedBuffer = NULL;
493 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
499 if( pDevExt->Specific.Control.ServiceProcess == NULL)
502 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
505 if( Irp->MdlAddress == NULL)
508 if( AFSLockSystemBuffer( Irp,
512 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
517 // Attach to the service process for mapping
520 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
521 (PRKAPC_STATE)&stApcState);
523 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
530 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
537 return pMappedBuffer;
541 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
545 NTSTATUS ntStatus = STATUS_SUCCESS;
546 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
552 if( pDevExt->Specific.Control.ServiceProcess == NULL)
555 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
562 // Attach to the service process for mapping
565 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
566 (PRKAPC_STATE)&stApcState);
568 MmUnmapLockedPages( MappedBuffer,
571 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
583 AFSInitializeLibraryDevice()
586 NTSTATUS ntStatus = STATUS_SUCCESS;
587 AFSDeviceExt *pDeviceExt = NULL;
592 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
595 // The PIOCtl file name
598 RtlInitUnicodeString( &AFSPIOCtlName,
599 AFS_PIOCTL_FILE_INTERFACE_NAME);
602 // And the global root share name
605 RtlInitUnicodeString( &AFSGlobalRootName,
606 AFS_GLOBAL_ROOT_SHARE_NAME);
614 AFSRemoveLibraryDevice()
617 NTSTATUS ntStatus = STATUS_SUCCESS;
628 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
632 UNREFERENCED_PARAMETER(DeviceObject);
633 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
635 AFSCompleteRequest( Irp,
642 AFSInitializeGlobalDirectoryEntries()
645 NTSTATUS ntStatus = STATUS_SUCCESS;
646 AFSDirectoryCB *pDirNode = NULL;
647 ULONG ulEntryLength = 0;
648 AFSObjectInfoCB *pObjectInfoCB = NULL;
649 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
656 // Initialize the global . entry
659 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
662 if( pObjectInfoCB == NULL)
665 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
666 AFS_TRACE_LEVEL_ERROR,
667 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
670 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
673 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
674 AFS_OBJECT_REFERENCE_GLOBAL);
676 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
677 AFS_TRACE_LEVEL_VERBOSE,
678 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
682 ntStatus = STATUS_SUCCESS;
684 ulEntryLength = sizeof( AFSDirectoryCB) +
687 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
691 if( pDirNode == NULL)
694 AFSDeleteObjectInfo( &pObjectInfoCB);
696 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
697 AFS_TRACE_LEVEL_ERROR,
698 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
700 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
703 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
704 AFS_TRACE_LEVEL_VERBOSE,
705 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocated %p\n",
708 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
709 sizeof( AFSNonPagedDirectoryCB),
710 AFS_DIR_ENTRY_NP_TAG);
712 if( pNonPagedDirEntry == NULL)
715 ExFreePool( pDirNode);
717 AFSDeleteObjectInfo( &pObjectInfoCB);
719 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
720 AFS_TRACE_LEVEL_ERROR,
721 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
723 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
726 RtlZeroMemory( pDirNode,
729 RtlZeroMemory( pNonPagedDirEntry,
730 sizeof( AFSNonPagedDirectoryCB));
732 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
734 pDirNode->NonPaged = pNonPagedDirEntry;
736 pDirNode->ObjectInformation = pObjectInfoCB;
742 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
744 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
747 // Setup the names in the entry
750 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
752 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
754 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
756 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
759 // Populate the rest of the data
762 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
764 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
766 AFSGlobalDotDirEntry = pDirNode;
772 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
775 if( pObjectInfoCB == NULL)
778 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
779 AFS_TRACE_LEVEL_ERROR,
780 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
783 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
786 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
787 AFS_OBJECT_REFERENCE_GLOBAL);
789 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
790 AFS_TRACE_LEVEL_VERBOSE,
791 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
795 ntStatus = STATUS_SUCCESS;
797 ulEntryLength = sizeof( AFSDirectoryCB) +
798 ( 2 * sizeof( WCHAR));
800 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
804 if( pDirNode == NULL)
807 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
808 AFS_TRACE_LEVEL_ERROR,
809 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocation failure\n");
811 AFSDeleteObjectInfo( &pObjectInfoCB);
813 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
816 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
817 AFS_TRACE_LEVEL_VERBOSE,
818 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocated %p\n",
821 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
822 sizeof( AFSNonPagedDirectoryCB),
823 AFS_DIR_ENTRY_NP_TAG);
825 if( pNonPagedDirEntry == NULL)
828 ExFreePool( pDirNode);
830 AFSDeleteObjectInfo( &pObjectInfoCB);
832 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
835 RtlZeroMemory( pDirNode,
838 RtlZeroMemory( pNonPagedDirEntry,
839 sizeof( AFSNonPagedDirectoryCB));
841 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
843 pDirNode->NonPaged = pNonPagedDirEntry;
845 pDirNode->ObjectInformation = pObjectInfoCB;
851 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
853 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
856 // Setup the names in the entry
859 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
861 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
863 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
865 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
867 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
870 // Populate the rest of the data
873 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
875 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
877 AFSGlobalDotDotDirEntry = pDirNode;
881 if( !NT_SUCCESS( ntStatus))
884 if( AFSGlobalDotDirEntry != NULL)
887 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
889 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
891 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
893 ExFreePool( AFSGlobalDotDirEntry);
895 AFSGlobalDotDirEntry = NULL;
898 if( AFSGlobalDotDotDirEntry != NULL)
901 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
903 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
905 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
907 ExFreePool( AFSGlobalDotDotDirEntry);
909 AFSGlobalDotDotDirEntry = NULL;
918 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
919 IN PUNICODE_STRING FileName,
920 IN PUNICODE_STRING TargetName,
921 IN AFSDirEnumEntry *DirEnumEntry,
925 AFSDirectoryCB *pDirNode = NULL;
926 NTSTATUS ntStatus = STATUS_SUCCESS;
927 ULONG ulEntryLength = 0;
928 AFSObjectInfoCB *pObjectInfoCB = NULL;
929 BOOLEAN bAllocatedObjectCB = FALSE;
930 ULONGLONG ullIndex = 0;
931 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
937 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
938 AFS_TRACE_LEVEL_VERBOSE,
939 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
941 ParentObjectInfo->FileId.Cell,
942 ParentObjectInfo->FileId.Volume,
943 ParentObjectInfo->FileId.Vnode,
944 ParentObjectInfo->FileId.Unique);
947 // First thing is to locate/create our object information block
951 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
954 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
956 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
958 (AFSBTreeEntry **)&pObjectInfoCB);
960 if( !NT_SUCCESS( ntStatus) ||
961 pObjectInfoCB == NULL)
965 // Allocate our object info cb
968 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
971 if( pObjectInfoCB == NULL)
974 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
976 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
979 bAllocatedObjectCB = TRUE;
981 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
982 AFS_TRACE_LEVEL_VERBOSE,
983 "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
989 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
990 AFS_OBJECT_REFERENCE_DIRENTRY);
992 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
993 AFS_TRACE_LEVEL_VERBOSE,
994 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
998 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1000 ntStatus = STATUS_SUCCESS;
1002 ulEntryLength = sizeof( AFSDirectoryCB) +
1005 if( TargetName != NULL)
1008 ulEntryLength += TargetName->Length;
1011 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1015 if( pDirNode == NULL)
1018 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1021 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1022 AFS_TRACE_LEVEL_VERBOSE,
1023 "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
1026 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1027 sizeof( AFSNonPagedDirectoryCB),
1028 AFS_DIR_ENTRY_NP_TAG);
1030 if( pNonPagedDirEntry == NULL)
1033 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1036 RtlZeroMemory( pDirNode,
1039 RtlZeroMemory( pNonPagedDirEntry,
1040 sizeof( AFSNonPagedDirectoryCB));
1042 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1044 pDirNode->NonPaged = pNonPagedDirEntry;
1046 pDirNode->ObjectInformation = pObjectInfoCB;
1049 // Set valid entry and NOT_IN_PARENT flag
1052 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1054 pDirNode->FileIndex = FileIndex;
1057 // Setup the names in the entry
1060 if( FileName->Length > 0)
1063 pDirNode->NameInformation.FileName.Length = FileName->Length;
1065 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1067 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1069 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1071 pDirNode->NameInformation.FileName.Length);
1074 // Create a CRC for the file
1077 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1080 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1084 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1085 AFS_TRACE_LEVEL_VERBOSE,
1086 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1089 ParentObjectInfo->FileId.Cell,
1090 ParentObjectInfo->FileId.Volume,
1091 ParentObjectInfo->FileId.Vnode,
1092 ParentObjectInfo->FileId.Unique);
1094 if( TargetName != NULL &&
1095 TargetName->Length > 0)
1098 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1100 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1102 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1103 sizeof( AFSDirectoryCB) +
1104 pDirNode->NameInformation.FileName.Length);
1106 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1108 pDirNode->NameInformation.TargetName.Length);
1112 // If we allocated the object information cb then update the information
1115 if( bAllocatedObjectCB)
1119 // Populate the rest of the data
1122 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1124 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1126 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1128 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1130 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1132 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1134 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1136 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1138 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1140 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1142 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1145 pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1148 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1149 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1152 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1155 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1158 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1159 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1163 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1164 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1165 pObjectInfoCB->TargetFileId.Unique == 0 &&
1166 pDirNode->NameInformation.TargetName.Length == 0)
1170 // This will ensure we perform a validation on the node
1173 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1176 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1179 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1184 // Object specific information
1187 pObjectInfoCB->Links = DirEnumEntry->Links;
1189 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1191 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1195 if( !NT_SUCCESS( ntStatus))
1198 if( pNonPagedDirEntry != NULL)
1201 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1203 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1206 if( pDirNode != NULL)
1209 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1210 AFS_TRACE_LEVEL_VERBOSE,
1211 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1214 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1220 // Dereference our object info block if we have one
1223 if( pObjectInfoCB != NULL)
1226 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1227 AFS_OBJECT_REFERENCE_DIRENTRY);
1229 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1230 AFS_TRACE_LEVEL_VERBOSE,
1231 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1235 if( bAllocatedObjectCB)
1238 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1240 AFSDeleteObjectInfo( &pObjectInfoCB);
1250 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1251 IN BOOLEAN DirectoryEntry)
1254 BOOLEAN bReturn = TRUE;
1255 ACCESS_MASK stAccessMask = 0;
1258 // Get rid of anything we don't know about
1261 DesiredAccess = (DesiredAccess &
1267 ACCESS_SYSTEM_SECURITY |
1271 FILE_READ_ATTRIBUTES |
1272 FILE_WRITE_ATTRIBUTES |
1273 FILE_LIST_DIRECTORY |
1279 // Our 'read only' access mask. These are the accesses we will
1280 // allow for a read only file
1283 stAccessMask = DELETE |
1288 ACCESS_SYSTEM_SECURITY |
1292 FILE_READ_ATTRIBUTES |
1293 FILE_WRITE_ATTRIBUTES |
1295 FILE_LIST_DIRECTORY |
1299 // For a directory, add in the directory specific accesses
1305 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1310 if( FlagOn( DesiredAccess, ~stAccessMask))
1314 // A write access is set ...
1324 AFSEvaluateNode( IN GUID *AuthGroup,
1325 IN AFSDirectoryCB *DirEntry)
1328 NTSTATUS ntStatus = STATUS_SUCCESS;
1329 AFSDirEnumEntry *pDirEntry = NULL;
1330 UNICODE_STRING uniTargetName;
1335 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1340 if( !NT_SUCCESS( ntStatus))
1343 try_return( ntStatus);
1346 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1348 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1350 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1352 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1354 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1356 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1358 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1360 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1362 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1364 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1366 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1368 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1371 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1374 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1375 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1378 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1381 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1383 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1386 // If we have a target name then see if it needs updating ...
1389 if( pDirEntry->TargetNameLength > 0)
1393 // Update the target name information if needed
1396 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1398 uniTargetName.MaximumLength = uniTargetName.Length;
1400 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1402 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1405 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1406 RtlCompareUnicodeString( &uniTargetName,
1407 &DirEntry->NameInformation.TargetName,
1412 // Update the target name
1415 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1417 uniTargetName.Buffer,
1418 uniTargetName.Length);
1420 if( !NT_SUCCESS( ntStatus))
1423 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1425 try_return( ntStatus);
1429 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1434 if( pDirEntry != NULL)
1437 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1445 AFSValidateSymLink( IN GUID *AuthGroup,
1446 IN AFSDirectoryCB *DirEntry)
1449 NTSTATUS ntStatus = STATUS_SUCCESS;
1450 AFSDirEnumEntry *pDirEntry = NULL;
1451 UNICODE_STRING uniTargetName;
1456 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1461 if( !NT_SUCCESS( ntStatus))
1464 try_return( ntStatus);
1467 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1468 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1471 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1472 AFS_TRACE_LEVEL_VERBOSE_2,
1473 "AFSValidateSymLink Invalid type Status %08lX\n",
1474 STATUS_OBJECT_NAME_NOT_FOUND);
1476 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1479 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1481 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1483 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1486 // Update the target name information if needed
1489 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1491 uniTargetName.MaximumLength = uniTargetName.Length;
1493 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1495 if( uniTargetName.Length > 0)
1498 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1501 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1502 RtlCompareUnicodeString( &uniTargetName,
1503 &DirEntry->NameInformation.TargetName,
1508 // Update the target name
1511 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1513 uniTargetName.Buffer,
1514 uniTargetName.Length);
1516 if( !NT_SUCCESS( ntStatus))
1519 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1521 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1525 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1529 // If the FileType is the same then nothing to do since it IS
1533 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1536 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1538 try_return( ntStatus = STATUS_SUCCESS);
1541 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1543 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1545 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1547 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1549 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1551 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1553 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1555 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1557 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1560 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1563 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1564 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1567 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1570 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1572 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1576 if( pDirEntry != NULL)
1579 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1587 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1591 NTSTATUS ntStatus = STATUS_SUCCESS;
1592 IO_STATUS_BLOCK stIoStatus;
1594 AFSObjectInfoCB * pParentObjectInfo = NULL;
1596 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1597 AFS_TRACE_LEVEL_VERBOSE,
1598 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1599 (*ppObjectInfo)->FileType,
1600 (*ppObjectInfo)->FileId.Cell,
1601 (*ppObjectInfo)->FileId.Volume,
1602 (*ppObjectInfo)->FileId.Vnode,
1603 (*ppObjectInfo)->FileId.Unique,
1606 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1609 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1610 &(*ppObjectInfo)->ParentFileId);
1613 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1614 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1615 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1618 // We only act on the mount point itself, not the target. If the
1619 // node has been deleted then mark it as such otherwise indicate
1620 // it requires verification
1623 if( Reason == AFS_INVALIDATE_DELETED)
1625 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1630 if( Reason == AFS_INVALIDATE_FLUSHED)
1633 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1635 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1638 (*ppObjectInfo)->Expiration.QuadPart = 0;
1640 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1642 (*ppObjectInfo)->TargetFileId.Unique = 0;
1644 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1645 AFS_TRACE_LEVEL_VERBOSE,
1646 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1647 (*ppObjectInfo)->FileId.Cell,
1648 (*ppObjectInfo)->FileId.Volume,
1649 (*ppObjectInfo)->FileId.Vnode,
1650 (*ppObjectInfo)->FileId.Unique);
1652 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1655 if ( pParentObjectInfo != NULL)
1658 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1660 if( Reason == AFS_INVALIDATE_CREDS)
1662 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1665 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1666 Reason == AFS_INVALIDATE_FLUSHED)
1668 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1672 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1675 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1678 FILE_ACTION_MODIFIED);
1681 try_return( ntStatus);
1685 // Depending on the reason for invalidation then perform work on the node
1691 case AFS_INVALIDATE_DELETED:
1695 // Mark this node as invalid
1698 (*ppObjectInfo)->Links = 0;
1700 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1702 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1703 AFS_TRACE_LEVEL_VERBOSE,
1704 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1705 (*ppObjectInfo)->FileId.Cell,
1706 (*ppObjectInfo)->FileId.Volume,
1707 (*ppObjectInfo)->FileId.Vnode,
1708 (*ppObjectInfo)->FileId.Unique);
1710 if( pParentObjectInfo != NULL)
1713 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1714 AFS_TRACE_LEVEL_VERBOSE,
1715 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1716 pParentObjectInfo->FileId.Cell,
1717 pParentObjectInfo->FileId.Volume,
1718 pParentObjectInfo->FileId.Vnode,
1719 pParentObjectInfo->FileId.Unique);
1721 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1723 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1725 pParentObjectInfo->Expiration.QuadPart = 0;
1727 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1729 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1733 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1736 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1739 FILE_ACTION_REMOVED);
1742 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1745 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1751 case AFS_INVALIDATE_FLUSHED:
1754 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1755 (*ppObjectInfo)->Fcb != NULL)
1758 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1759 AFS_TRACE_LEVEL_VERBOSE,
1760 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1761 (*ppObjectInfo)->FileId.Cell,
1762 (*ppObjectInfo)->FileId.Volume,
1763 (*ppObjectInfo)->FileId.Vnode,
1764 (*ppObjectInfo)->FileId.Unique);
1766 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1772 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1777 if( !NT_SUCCESS( stIoStatus.Status))
1780 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1781 AFS_TRACE_LEVEL_ERROR,
1782 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1783 (*ppObjectInfo)->FileId.Cell,
1784 (*ppObjectInfo)->FileId.Volume,
1785 (*ppObjectInfo)->FileId.Vnode,
1786 (*ppObjectInfo)->FileId.Unique,
1788 stIoStatus.Information);
1790 ntStatus = stIoStatus.Status;
1794 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1797 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1803 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1804 AFS_TRACE_LEVEL_WARNING,
1805 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1806 (*ppObjectInfo)->FileId.Cell,
1807 (*ppObjectInfo)->FileId.Volume,
1808 (*ppObjectInfo)->FileId.Vnode,
1809 (*ppObjectInfo)->FileId.Unique);
1811 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1815 __except( EXCEPTION_EXECUTE_HANDLER)
1818 ntStatus = GetExceptionCode();
1822 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1823 (*ppObjectInfo)->FileId.Cell,
1824 (*ppObjectInfo)->FileId.Volume,
1825 (*ppObjectInfo)->FileId.Vnode,
1826 (*ppObjectInfo)->FileId.Unique,
1829 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1832 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1835 // Clear out the extents
1836 // Get rid of them (note this involves waiting
1837 // for any writes or reads to the cache to complete)
1840 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1844 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1847 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1850 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1851 AFS_TRACE_LEVEL_VERBOSE,
1852 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1853 (*ppObjectInfo)->FileId.Cell,
1854 (*ppObjectInfo)->FileId.Volume,
1855 (*ppObjectInfo)->FileId.Vnode,
1856 (*ppObjectInfo)->FileId.Unique);
1858 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1861 // Fall through to the default processing
1867 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1869 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1873 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1876 if( Reason == AFS_INVALIDATE_CREDS)
1878 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1881 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1883 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1887 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1890 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1893 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1896 FILE_ACTION_MODIFIED);
1898 else if ( pParentObjectInfo != NULL)
1901 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1904 FILE_ACTION_MODIFIED);
1908 // Indicate this node requires re-evaluation for the remaining reasons
1911 (*ppObjectInfo)->Expiration.QuadPart = 0;
1913 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1914 AFS_TRACE_LEVEL_VERBOSE,
1915 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1916 (*ppObjectInfo)->FileId.Cell,
1917 (*ppObjectInfo)->FileId.Volume,
1918 (*ppObjectInfo)->FileId.Vnode,
1919 (*ppObjectInfo)->FileId.Unique);
1921 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1923 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1924 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1925 ( Reason == AFS_INVALIDATE_CALLBACK ||
1926 Reason == AFS_INVALIDATE_EXPIRED))
1928 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1929 AFS_INVALIDATE_DATA_VERSION)))
1932 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1942 if ( pParentObjectInfo != NULL)
1945 AFSReleaseObjectInfo( &pParentObjectInfo);
1952 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1955 NTSTATUS ntStatus = STATUS_SUCCESS;
1956 AFSVolumeCB *pVolumeCB = NULL;
1957 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1958 ULONGLONG ullIndex = 0;
1959 AFSObjectInfoCB *pObjectInfo = NULL;
1965 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1966 AFS_TRACE_LEVEL_VERBOSE,
1967 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1968 InvalidateCB->FileID.Cell,
1969 InvalidateCB->FileID.Volume,
1970 InvalidateCB->FileID.Vnode,
1971 InvalidateCB->FileID.Unique,
1972 InvalidateCB->FileType,
1973 InvalidateCB->WholeVolume,
1974 InvalidateCB->Reason);
1977 // Need to locate the Fcb for the directory to purge
1980 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1981 AFS_TRACE_LEVEL_VERBOSE,
1982 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
1983 &pDevExt->Specific.RDR.VolumeTreeLock,
1984 PsGetCurrentThread());
1987 // Starve any exclusive waiters on this paticular call
1990 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1993 // Locate the volume node
1996 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1998 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2000 (AFSBTreeEntry **)&pVolumeCB);
2002 if( pVolumeCB != NULL)
2005 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
2007 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2008 AFS_TRACE_LEVEL_VERBOSE,
2009 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2014 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2016 if( !NT_SUCCESS( ntStatus) ||
2020 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2021 AFS_TRACE_LEVEL_WARNING,
2022 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2023 InvalidateCB->FileID.Cell,
2024 InvalidateCB->FileID.Volume,
2025 InvalidateCB->FileID.Vnode,
2026 InvalidateCB->FileID.Unique,
2029 try_return( ntStatus = STATUS_SUCCESS);
2033 // If this is a whole volume invalidation then go do it now
2036 if( InvalidateCB->WholeVolume)
2039 ntStatus = AFSInvalidateVolume( pVolumeCB,
2040 InvalidateCB->Reason);
2042 try_return( ntStatus);
2045 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
2048 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2051 pObjectInfo = &pVolumeCB->ObjectInformation;
2056 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2058 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2060 (AFSBTreeEntry **)&pObjectInfo);
2063 if( pObjectInfo != NULL)
2067 // Reference the node so it won't be torn down
2070 lCount = AFSObjectInfoIncrement( pObjectInfo,
2071 AFS_OBJECT_REFERENCE_INVALIDATION);
2073 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2074 AFS_TRACE_LEVEL_VERBOSE,
2075 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2080 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2082 if( !NT_SUCCESS( ntStatus) ||
2083 pObjectInfo == NULL)
2086 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2087 AFS_TRACE_LEVEL_VERBOSE,
2088 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2089 InvalidateCB->FileID.Cell,
2090 InvalidateCB->FileID.Volume,
2091 InvalidateCB->FileID.Vnode,
2092 InvalidateCB->FileID.Unique,
2095 try_return( ntStatus = STATUS_SUCCESS);
2098 AFSInvalidateObject( &pObjectInfo,
2099 InvalidateCB->Reason);
2103 if( pObjectInfo != NULL)
2106 lCount = AFSObjectInfoDecrement( pObjectInfo,
2107 AFS_OBJECT_REFERENCE_INVALIDATION);
2109 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2110 AFS_TRACE_LEVEL_VERBOSE,
2111 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2116 if ( pVolumeCB != NULL)
2119 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2121 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2122 AFS_TRACE_LEVEL_VERBOSE,
2123 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2133 AFSIsChildOfParent( IN AFSFcb *Dcb,
2137 BOOLEAN bIsChild = FALSE;
2138 AFSFcb *pCurrentFcb = Fcb;
2139 AFSObjectInfoCB * pParentObjectInfo = NULL;
2141 while( pCurrentFcb != NULL)
2144 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2145 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2153 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2154 &pCurrentFcb->ObjectInformation->ParentFileId);
2156 if ( pParentObjectInfo != NULL)
2159 pCurrentFcb = pParentObjectInfo->Fcb;
2161 AFSReleaseObjectInfo( &pParentObjectInfo);
2175 AFSCreateHighIndex( IN AFSFileID *FileID)
2178 ULONGLONG ullIndex = 0;
2180 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2187 AFSCreateLowIndex( IN AFSFileID *FileID)
2190 ULONGLONG ullIndex = 0;
2192 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2198 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2199 IN ACCESS_MASK GrantedAccess,
2200 IN BOOLEAN DirectoryEntry)
2203 BOOLEAN bAccessGranted = TRUE;
2206 // Check if we are asking for read/write and granted only read only
2207 // NOTE: There will be more checks here
2210 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2212 AFSCheckForReadOnlyAccess( GrantedAccess,
2216 bAccessGranted = FALSE;
2219 return bAccessGranted;
2223 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2226 NTSTATUS ntStatus = STATUS_SUCCESS;
2227 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2233 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2235 if( AFSGlobalRoot == NULL)
2242 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2245 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2252 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2259 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2260 IN UNICODE_STRING *SubstituteName,
2261 IN ULONG StringIndex)
2264 NTSTATUS ntStatus = STATUS_SUCCESS;
2265 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2266 AFSSysNameCB *pSysName = NULL;
2267 ERESOURCE *pSysNameLock = NULL;
2270 UNICODE_STRING uniSysName;
2277 if( IoIs32bitProcess( NULL))
2280 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2282 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2287 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2289 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2293 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2295 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2299 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2300 AFS_TRACE_LEVEL_VERBOSE,
2301 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2303 PsGetCurrentThread());
2305 AFSAcquireShared( pSysNameLock,
2309 // Find where we are in the list
2312 while( pSysName != NULL &&
2313 ulIndex < StringIndex)
2316 pSysName = pSysName->fLink;
2321 if( pSysName == NULL)
2324 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2325 AFS_TRACE_LEVEL_VERBOSE_2,
2326 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2328 STATUS_OBJECT_NAME_NOT_FOUND);
2330 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2333 RtlInitUnicodeString( &uniSysName,
2336 // If it is a full component of @SYS then just substitue the
2340 if( RtlCompareUnicodeString( &uniSysName,
2345 SubstituteName->Length = pSysName->SysName.Length;
2346 SubstituteName->MaximumLength = SubstituteName->Length;
2348 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2349 SubstituteName->Length,
2350 AFS_SUBST_BUFFER_TAG);
2352 if( SubstituteName->Buffer == NULL)
2355 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2358 RtlCopyMemory( SubstituteName->Buffer,
2359 pSysName->SysName.Buffer,
2360 pSysName->SysName.Length);
2367 while( ComponentName->Buffer[ usIndex] != L'@')
2373 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2374 SubstituteName->MaximumLength = SubstituteName->Length;
2376 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2377 SubstituteName->Length,
2378 AFS_SUBST_BUFFER_TAG);
2380 if( SubstituteName->Buffer == NULL)
2383 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2386 RtlCopyMemory( SubstituteName->Buffer,
2387 ComponentName->Buffer,
2388 usIndex * sizeof( WCHAR));
2390 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2391 pSysName->SysName.Buffer,
2392 pSysName->SysName.Length);
2397 AFSReleaseResource( pSysNameLock);
2404 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2405 IN OUT UNICODE_STRING *ComponentName,
2406 IN UNICODE_STRING *SubstituteName,
2407 IN OUT UNICODE_STRING *RemainingPath,
2408 IN BOOLEAN FreePathName)
2411 NTSTATUS ntStatus = STATUS_SUCCESS;
2412 UNICODE_STRING uniPathName;
2413 USHORT usPrefixNameLen = 0;
2414 SHORT sNameLenDelta = 0;
2420 // If the passed in name can handle the additional length
2421 // then just moves things around
2424 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2426 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2428 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2431 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2434 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2435 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2436 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2439 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2440 SubstituteName->Buffer,
2441 SubstituteName->Length);
2443 FullPathName->Length += sNameLenDelta;
2445 ComponentName->Length += sNameLenDelta;
2447 ComponentName->MaximumLength = ComponentName->Length;
2449 if ( RemainingPath->Buffer)
2452 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2455 try_return( ntStatus);
2459 // Need to re-allocate the buffer
2462 uniPathName.Length = FullPathName->Length -
2463 ComponentName->Length +
2464 SubstituteName->Length;
2466 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2468 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2469 uniPathName.MaximumLength,
2470 AFS_NAME_BUFFER_FOUR_TAG);
2472 if( uniPathName.Buffer == NULL)
2475 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2478 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2480 usPrefixNameLen *= sizeof( WCHAR);
2482 RtlZeroMemory( uniPathName.Buffer,
2483 uniPathName.MaximumLength);
2485 RtlCopyMemory( uniPathName.Buffer,
2486 FullPathName->Buffer,
2489 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2490 SubstituteName->Buffer,
2491 SubstituteName->Length);
2493 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2496 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2497 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2498 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2501 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2503 ComponentName->Length += sNameLenDelta;
2505 ComponentName->MaximumLength = ComponentName->Length;
2507 if ( RemainingPath->Buffer)
2510 RemainingPath->Buffer = uniPathName.Buffer
2511 + (RemainingPath->Buffer - FullPathName->Buffer)
2512 + sNameLenDelta/sizeof( WCHAR);
2517 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2520 *FullPathName = uniPathName;
2531 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2535 NTSTATUS ntStatus = STATUS_SUCCESS;
2536 AFSObjectInfoCB *pCurrentObject = NULL;
2537 AFSObjectInfoCB *pNextObject = NULL;
2543 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2544 AFS_TRACE_LEVEL_VERBOSE,
2545 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2546 VolumeCB->ObjectInformation.FileId.Cell,
2547 VolumeCB->ObjectInformation.FileId.Volume,
2548 VolumeCB->ObjectInformation.FileId.Vnode,
2549 VolumeCB->ObjectInformation.FileId.Unique,
2553 // Depending on the reason for invalidation then perform work on the node
2559 case AFS_INVALIDATE_DELETED:
2563 // Mark this volume as invalid
2566 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2568 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2575 // Invalidate the volume root directory
2578 pCurrentObject = &VolumeCB->ObjectInformation;
2580 if ( pCurrentObject )
2583 lCount = AFSObjectInfoIncrement( pCurrentObject,
2584 AFS_OBJECT_REFERENCE_INVALIDATION);
2586 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2587 AFS_TRACE_LEVEL_VERBOSE,
2588 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2592 AFSInvalidateObject( &pCurrentObject,
2595 if ( pCurrentObject)
2598 lCount = AFSObjectInfoDecrement( pCurrentObject,
2599 AFS_OBJECT_REFERENCE_INVALIDATION);
2601 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2602 AFS_TRACE_LEVEL_VERBOSE,
2603 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2610 // Apply invalidation to all other volume objects
2613 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2616 pCurrentObject = VolumeCB->ObjectInfoListHead;
2618 if ( pCurrentObject)
2622 // Reference the node so it won't be torn down
2625 lCount = AFSObjectInfoIncrement( pCurrentObject,
2626 AFS_OBJECT_REFERENCE_INVALIDATION);
2628 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2629 AFS_TRACE_LEVEL_VERBOSE,
2630 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2635 while( pCurrentObject != NULL)
2638 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2644 // Reference the node so it won't be torn down
2647 lCount = AFSObjectInfoIncrement( pNextObject,
2648 AFS_OBJECT_REFERENCE_INVALIDATION);
2650 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2651 AFS_TRACE_LEVEL_VERBOSE,
2652 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2657 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2659 AFSInvalidateObject( &pCurrentObject,
2662 if ( pCurrentObject )
2665 lCount = AFSObjectInfoDecrement( pCurrentObject,
2666 AFS_OBJECT_REFERENCE_INVALIDATION);
2668 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2669 AFS_TRACE_LEVEL_VERBOSE,
2670 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2675 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2678 pCurrentObject = pNextObject;
2681 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2688 AFSInvalidateAllVolumes( VOID)
2690 AFSVolumeCB *pVolumeCB = NULL;
2691 AFSVolumeCB *pNextVolumeCB = NULL;
2692 AFSDeviceExt *pRDRDeviceExt = NULL;
2695 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2697 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2698 AFS_TRACE_LEVEL_VERBOSE,
2699 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2700 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2701 PsGetCurrentThread());
2703 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2706 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2711 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2712 AFS_TRACE_LEVEL_VERBOSE,
2713 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2714 pVolumeCB->ObjectInfoTree.TreeLock,
2715 PsGetCurrentThread());
2717 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
2719 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2720 AFS_TRACE_LEVEL_VERBOSE,
2721 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2726 while( pVolumeCB != NULL)
2729 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2734 lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
2736 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2737 AFS_TRACE_LEVEL_VERBOSE,
2738 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2743 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2745 // do I need to hold the volume lock here?
2747 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2749 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2752 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2754 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2755 AFS_TRACE_LEVEL_VERBOSE,
2756 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2760 pVolumeCB = pNextVolumeCB;
2763 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2767 AFSVerifyEntry( IN GUID *AuthGroup,
2768 IN AFSDirectoryCB *DirEntry)
2771 NTSTATUS ntStatus = STATUS_SUCCESS;
2772 AFSDirEnumEntry *pDirEnumEntry = NULL;
2773 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2774 IO_STATUS_BLOCK stIoStatus;
2779 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2780 AFS_TRACE_LEVEL_VERBOSE_2,
2781 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2782 &DirEntry->NameInformation.FileName,
2783 pObjectInfo->FileId.Cell,
2784 pObjectInfo->FileId.Volume,
2785 pObjectInfo->FileId.Vnode,
2786 pObjectInfo->FileId.Unique);
2788 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2793 if( !NT_SUCCESS( ntStatus))
2796 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2797 AFS_TRACE_LEVEL_ERROR,
2798 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2799 &DirEntry->NameInformation.FileName,
2800 pObjectInfo->FileId.Cell,
2801 pObjectInfo->FileId.Volume,
2802 pObjectInfo->FileId.Vnode,
2803 pObjectInfo->FileId.Unique,
2806 try_return( ntStatus);
2810 // Check the data version of the file
2813 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2815 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2818 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2819 AFS_TRACE_LEVEL_VERBOSE,
2820 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2821 pObjectInfo->DataVersion.QuadPart,
2822 &DirEntry->NameInformation.FileName,
2823 pObjectInfo->FileId.Cell,
2824 pObjectInfo->FileId.Volume,
2825 pObjectInfo->FileId.Vnode,
2826 pObjectInfo->FileId.Unique);
2829 // We are ok, just get out
2832 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2834 try_return( ntStatus = STATUS_SUCCESS);
2839 // New data version so we will need to process the node based on the type
2842 switch( pDirEnumEntry->FileType)
2845 case AFS_FILE_TYPE_MOUNTPOINT:
2849 // For a mount point we need to ensure the target is the same
2852 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2853 &pDirEnumEntry->TargetFileId))
2859 // Update the metadata for the entry
2862 ntStatus = AFSUpdateMetaData( DirEntry,
2865 if( NT_SUCCESS( ntStatus))
2868 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2874 case AFS_FILE_TYPE_SYMLINK:
2878 // Update the metadata for the entry
2881 ntStatus = AFSUpdateMetaData( DirEntry,
2884 if( NT_SUCCESS( ntStatus))
2887 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2893 case AFS_FILE_TYPE_FILE:
2895 FILE_OBJECT * pCCFileObject = NULL;
2896 BOOLEAN bPurgeExtents = FALSE;
2898 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
2901 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2902 AFS_TRACE_LEVEL_VERBOSE,
2903 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
2904 &DirEntry->NameInformation.FileName,
2905 pObjectInfo->FileId.Cell,
2906 pObjectInfo->FileId.Volume,
2907 pObjectInfo->FileId.Vnode,
2908 pObjectInfo->FileId.Unique,
2909 pObjectInfo->DataVersion.LowPart,
2910 pDirEnumEntry->DataVersion.LowPart
2913 bPurgeExtents = TRUE;
2916 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2919 bPurgeExtents = TRUE;
2921 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2922 AFS_TRACE_LEVEL_VERBOSE,
2923 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2924 &DirEntry->NameInformation.FileName,
2925 pObjectInfo->FileId.Cell,
2926 pObjectInfo->FileId.Volume,
2927 pObjectInfo->FileId.Vnode,
2928 pObjectInfo->FileId.Unique);
2930 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2933 if( pObjectInfo->Fcb != NULL)
2936 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2937 AFS_TRACE_LEVEL_VERBOSE,
2938 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2939 &DirEntry->NameInformation.FileName,
2940 pObjectInfo->FileId.Cell,
2941 pObjectInfo->FileId.Volume,
2942 pObjectInfo->FileId.Vnode,
2943 pObjectInfo->FileId.Unique);
2945 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2951 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2956 if( !NT_SUCCESS( stIoStatus.Status))
2959 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2960 AFS_TRACE_LEVEL_ERROR,
2961 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2962 &DirEntry->NameInformation.FileName,
2963 pObjectInfo->FileId.Cell,
2964 pObjectInfo->FileId.Volume,
2965 pObjectInfo->FileId.Vnode,
2966 pObjectInfo->FileId.Unique,
2968 stIoStatus.Information);
2970 ntStatus = stIoStatus.Status;
2973 if ( bPurgeExtents &&
2974 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2977 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2983 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2984 AFS_TRACE_LEVEL_WARNING,
2985 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2986 &DirEntry->NameInformation.FileName,
2987 pObjectInfo->FileId.Cell,
2988 pObjectInfo->FileId.Volume,
2989 pObjectInfo->FileId.Vnode,
2990 pObjectInfo->FileId.Unique);
2992 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2996 __except( EXCEPTION_EXECUTE_HANDLER)
2998 ntStatus = GetExceptionCode();
3002 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3003 &DirEntry->NameInformation.FileName,
3004 pObjectInfo->FileId.Cell,
3005 pObjectInfo->FileId.Volume,
3006 pObjectInfo->FileId.Vnode,
3007 pObjectInfo->FileId.Unique,
3010 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3013 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3017 AFSFlushExtents( pObjectInfo->Fcb,
3022 // Reacquire the Fcb to purge the cache
3025 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3026 AFS_TRACE_LEVEL_VERBOSE,
3027 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3028 &pObjectInfo->Fcb->NPFcb->Resource,
3029 PsGetCurrentThread());
3031 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3035 // Update the metadata for the entry
3038 ntStatus = AFSUpdateMetaData( DirEntry,
3041 if( !NT_SUCCESS( ntStatus))
3044 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3045 AFS_TRACE_LEVEL_ERROR,
3046 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3047 &DirEntry->NameInformation.FileName,
3048 pObjectInfo->FileId.Cell,
3049 pObjectInfo->FileId.Volume,
3050 pObjectInfo->FileId.Vnode,
3051 pObjectInfo->FileId.Unique,
3058 // Update file sizes
3061 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3062 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3063 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3065 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3066 AFS_TRACE_LEVEL_VERBOSE,
3067 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3068 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3069 PsGetCurrentThread());
3071 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3074 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3076 if ( pCCFileObject != NULL)
3078 CcSetFileSizes( pCCFileObject,
3079 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3082 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3083 AFS_TRACE_LEVEL_VERBOSE,
3084 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3085 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3086 PsGetCurrentThread());
3088 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3090 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3096 // Update the metadata for the entry
3099 ntStatus = AFSUpdateMetaData( DirEntry,
3102 if( !NT_SUCCESS( ntStatus))
3105 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3106 AFS_TRACE_LEVEL_ERROR,
3107 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3108 &DirEntry->NameInformation.FileName,
3109 pObjectInfo->FileId.Cell,
3110 pObjectInfo->FileId.Volume,
3111 pObjectInfo->FileId.Vnode,
3112 pObjectInfo->FileId.Unique,
3118 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3119 AFS_TRACE_LEVEL_WARNING,
3120 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3121 &DirEntry->NameInformation.FileName,
3122 pObjectInfo->FileId.Cell,
3123 pObjectInfo->FileId.Volume,
3124 pObjectInfo->FileId.Vnode,
3125 pObjectInfo->FileId.Unique);
3128 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3133 case AFS_FILE_TYPE_DIRECTORY:
3137 // For a directory or root entry flush the content of
3138 // the directory enumeration.
3141 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3144 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3145 AFS_TRACE_LEVEL_VERBOSE_2,
3146 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3147 &DirEntry->NameInformation.FileName,
3148 pObjectInfo->FileId.Cell,
3149 pObjectInfo->FileId.Volume,
3150 pObjectInfo->FileId.Vnode,
3151 pObjectInfo->FileId.Unique);
3153 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3156 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3159 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3161 if ( !NT_SUCCESS( ntStatus))
3164 try_return( ntStatus);
3169 // Update the metadata for the entry
3172 ntStatus = AFSUpdateMetaData( DirEntry,
3175 if( NT_SUCCESS( ntStatus))
3178 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3184 case AFS_FILE_TYPE_DFSLINK:
3187 UNICODE_STRING uniTargetName;
3190 // For a DFS link need to check the target name has not changed
3193 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3195 uniTargetName.MaximumLength = uniTargetName.Length;
3197 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3199 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3202 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3203 RtlCompareUnicodeString( &uniTargetName,
3204 &DirEntry->NameInformation.TargetName,
3209 // Update the target name
3212 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3214 uniTargetName.Buffer,
3215 uniTargetName.Length);
3217 if( !NT_SUCCESS( ntStatus))
3220 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3226 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3229 // Update the metadata for the entry
3232 ntStatus = AFSUpdateMetaData( DirEntry,
3235 if( NT_SUCCESS( ntStatus))
3238 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3246 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3247 AFS_TRACE_LEVEL_WARNING,
3248 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3249 pObjectInfo->FileType,
3250 &DirEntry->NameInformation.FileName,
3251 pObjectInfo->FileId.Cell,
3252 pObjectInfo->FileId.Volume,
3253 pObjectInfo->FileId.Vnode,
3254 pObjectInfo->FileId.Unique);
3261 if( pDirEnumEntry != NULL)
3264 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3272 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3275 NTSTATUS ntStatus = STATUS_SUCCESS;
3276 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3277 ULONGLONG ullIndex = 0;
3278 AFSVolumeCB *pVolumeCB = NULL;
3284 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3285 AFS_TRACE_LEVEL_VERBOSE,
3286 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3287 VolumeStatus->Online,
3288 VolumeStatus->FileID.Cell,
3289 VolumeStatus->FileID.Volume);
3292 // Need to locate the Fcb for the directory to purge
3295 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3296 AFS_TRACE_LEVEL_VERBOSE,
3297 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3298 &pDevExt->Specific.RDR.VolumeTreeLock,
3299 PsGetCurrentThread());
3301 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3304 // Locate the volume node
3307 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3309 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3311 (AFSBTreeEntry **)&pVolumeCB);
3313 if( pVolumeCB != NULL)
3316 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3318 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3319 AFS_TRACE_LEVEL_VERBOSE,
3320 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3324 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3327 // Set the volume state accordingly
3330 if( VolumeStatus->Online)
3333 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3338 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3347 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3350 NTSTATUS ntStatus = STATUS_SUCCESS;
3355 if( AFSGlobalRoot == NULL)
3358 try_return( ntStatus);
3361 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3365 // Set the network state according to the information
3368 if( NetworkStatus->Online)
3371 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3376 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3379 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3390 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3394 NTSTATUS ntStatus = STATUS_SUCCESS;
3395 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3396 BOOLEAN bAcquiredLock = FALSE;
3397 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3402 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3403 AFS_TRACE_LEVEL_VERBOSE,
3404 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3405 ObjectInfo->FileId.Cell,
3406 ObjectInfo->FileId.Volume,
3407 ObjectInfo->FileId.Vnode,
3408 ObjectInfo->FileId.Unique);
3410 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3413 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3414 AFS_TRACE_LEVEL_VERBOSE,
3415 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3416 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3417 PsGetCurrentThread());
3419 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3422 bAcquiredLock = TRUE;
3426 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3429 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3430 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3434 AFS_TRACE_LEVEL_ERROR,
3435 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3436 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3437 ObjectInfo->FileId.Cell,
3438 ObjectInfo->FileId.Volume,
3439 ObjectInfo->FileId.Vnode,
3440 ObjectInfo->FileId.Unique);
3444 // Reset the directory list information by clearing all valid entries
3447 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3449 while( pCurrentDirEntry != NULL)
3452 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3454 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3458 // If this entry has been deleted then process it here
3461 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3462 pCurrentDirEntry->DirOpenReferenceCount <= 0)
3465 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3466 AFS_TRACE_LEVEL_VERBOSE,
3467 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3469 &pCurrentDirEntry->NameInformation.FileName);
3471 AFSDeleteDirEntry( ObjectInfo,
3477 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3479 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3480 AFS_TRACE_LEVEL_VERBOSE,
3481 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3483 pCurrentDirEntry->DirOpenReferenceCount);
3486 // We pull the short name from the parent tree since it could change below
3489 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3492 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3493 AFS_TRACE_LEVEL_VERBOSE,
3494 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3496 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3497 &pCurrentDirEntry->NameInformation.FileName);
3499 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3502 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3507 pCurrentDirEntry = pNextDirEntry;
3511 // Reget the directory contents
3514 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3517 if ( !NT_SUCCESS( ntStatus))
3519 try_return( ntStatus);
3523 // Now start again and tear down any entries not valid
3526 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3528 while( pCurrentDirEntry != NULL)
3531 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3533 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3536 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3537 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3538 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3541 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3544 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3546 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3547 AFS_TRACE_LEVEL_VERBOSE,
3548 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3550 &pCurrentDirEntry->NameInformation.FileName);
3552 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3557 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3560 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3561 AFS_TRACE_LEVEL_VERBOSE,
3562 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3564 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3565 &pCurrentDirEntry->NameInformation.FileName);
3569 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3571 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3572 AFS_TRACE_LEVEL_VERBOSE,
3573 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3575 &pCurrentDirEntry->NameInformation.FileName);
3580 pCurrentDirEntry = pNextDirEntry;
3585 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3586 AFS_TRACE_LEVEL_VERBOSE,
3587 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3589 pCurrentDirEntry->DirOpenReferenceCount);
3591 if( pCurrentDirEntry->DirOpenReferenceCount <= 0)
3594 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3595 AFS_TRACE_LEVEL_VERBOSE,
3596 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3597 &pCurrentDirEntry->NameInformation.FileName,
3598 ObjectInfo->FileId.Cell,
3599 ObjectInfo->FileId.Volume,
3600 ObjectInfo->FileId.Vnode,
3601 ObjectInfo->FileId.Unique);
3603 AFSDeleteDirEntry( ObjectInfo,
3609 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3610 AFS_TRACE_LEVEL_VERBOSE,
3611 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3613 &pCurrentDirEntry->NameInformation.FileName,
3614 ObjectInfo->FileId.Cell,
3615 ObjectInfo->FileId.Volume,
3616 ObjectInfo->FileId.Vnode,
3617 ObjectInfo->FileId.Unique);
3619 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3621 AFSRemoveNameEntry( ObjectInfo,
3625 pCurrentDirEntry = pNextDirEntry;
3629 if( !AFSValidateDirList( ObjectInfo))
3632 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3641 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3649 AFSIsVolumeFID( IN AFSFileID *FileID)
3652 BOOLEAN bIsVolume = FALSE;
3654 if( FileID->Vnode == 1 &&
3655 FileID->Unique == 1)
3665 AFSIsFinalNode( IN AFSFcb *Fcb)
3668 BOOLEAN bIsFinalNode = FALSE;
3670 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3671 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3672 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3673 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3674 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3677 bIsFinalNode = TRUE;
3682 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3683 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3686 return bIsFinalNode;
3690 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3691 IN AFSDirEnumEntry *DirEnumEntry)
3694 NTSTATUS ntStatus = STATUS_SUCCESS;
3695 UNICODE_STRING uniTargetName;
3696 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3701 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3703 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3705 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3707 pObjectInfo->FileType = DirEnumEntry->FileType;
3709 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3711 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3713 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3715 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3717 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3719 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3721 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3723 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3726 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3729 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3730 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3733 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3736 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3738 pObjectInfo->Links = DirEnumEntry->Links;
3740 if( DirEnumEntry->TargetNameLength > 0 &&
3741 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3742 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3746 // Update the target name information if needed
3749 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3751 uniTargetName.MaximumLength = uniTargetName.Length;
3753 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3755 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3758 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3759 RtlCompareUnicodeString( &uniTargetName,
3760 &DirEntry->NameInformation.TargetName,
3765 // Update the target name
3768 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3770 uniTargetName.Buffer,
3771 uniTargetName.Length);
3773 if( !NT_SUCCESS( ntStatus))
3776 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3778 try_return( ntStatus);
3782 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3784 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3785 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3788 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3791 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3792 DirEntry->NameInformation.TargetName.Buffer != NULL)
3794 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3797 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3799 DirEntry->NameInformation.TargetName.Length = 0;
3800 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3801 DirEntry->NameInformation.TargetName.Buffer = NULL;
3803 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3815 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3817 IN BOOLEAN FastCall,
3818 IN BOOLEAN bSafeToPurge)
3821 NTSTATUS ntStatus = STATUS_SUCCESS;
3822 LARGE_INTEGER liSystemTime;
3823 AFSDirEnumEntry *pDirEnumEntry = NULL;
3824 AFSFcb *pCurrentFcb = NULL;
3825 BOOLEAN bReleaseFcb = FALSE;
3826 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3832 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3836 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3837 AFS_TRACE_LEVEL_VERBOSE_2,
3838 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3839 &DirEntry->NameInformation.FileName,
3840 pObjectInfo->FileId.Cell,
3841 pObjectInfo->FileId.Volume,
3842 pObjectInfo->FileId.Vnode,
3843 pObjectInfo->FileId.Unique,
3847 // If this is a fake node then bail since the service knows nothing about it
3850 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3853 try_return( ntStatus);
3857 // This routine ensures that the current entry is valid by:
3859 // 1) Checking that the expiration time is non-zero and after where we
3863 KeQuerySystemTime( &liSystemTime);
3865 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3866 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3867 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3868 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3871 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3872 AFS_TRACE_LEVEL_VERBOSE_2,
3873 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3874 &DirEntry->NameInformation.FileName,
3875 pObjectInfo->FileId.Cell,
3876 pObjectInfo->FileId.Volume,
3877 pObjectInfo->FileId.Vnode,
3878 pObjectInfo->FileId.Unique);
3880 try_return( ntStatus);
3884 // This node requires updating
3887 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3892 if( !NT_SUCCESS( ntStatus))
3895 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3896 AFS_TRACE_LEVEL_ERROR,
3897 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3899 &DirEntry->NameInformation.FileName,
3900 pObjectInfo->FileId.Cell,
3901 pObjectInfo->FileId.Volume,
3902 pObjectInfo->FileId.Vnode,
3903 pObjectInfo->FileId.Unique,
3907 // Failed validation of node so return access-denied
3910 try_return( ntStatus);
3913 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3914 AFS_TRACE_LEVEL_VERBOSE,
3915 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3917 &DirEntry->NameInformation.FileName,
3918 pObjectInfo->FileId.Cell,
3919 pObjectInfo->FileId.Volume,
3920 pObjectInfo->FileId.Vnode,
3921 pObjectInfo->FileId.Unique,
3922 pObjectInfo->DataVersion.QuadPart,
3923 pDirEnumEntry->DataVersion.QuadPart,
3924 pDirEnumEntry->FileType);
3928 // Based on the file type, process the node
3931 switch( pDirEnumEntry->FileType)
3934 case AFS_FILE_TYPE_MOUNTPOINT:
3938 // Update the metadata for the entry
3941 ntStatus = AFSUpdateMetaData( DirEntry,
3944 if( NT_SUCCESS( ntStatus))
3947 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3953 case AFS_FILE_TYPE_SYMLINK:
3954 case AFS_FILE_TYPE_DFSLINK:
3958 // Update the metadata for the entry
3961 ntStatus = AFSUpdateMetaData( DirEntry,
3964 if( NT_SUCCESS( ntStatus))
3967 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3973 case AFS_FILE_TYPE_FILE:
3976 BOOLEAN bPurgeExtents = FALSE;
3979 // For a file where the data version has become invalid we need to
3980 // fail any current extent requests and purge the cache for the file
3981 // Can't hold the Fcb resource while doing this
3984 if( pObjectInfo->Fcb != NULL &&
3985 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3986 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3989 pCurrentFcb = pObjectInfo->Fcb;
3991 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3994 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3995 AFS_TRACE_LEVEL_VERBOSE,
3996 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
3997 &pCurrentFcb->NPFcb->Resource,
3998 PsGetCurrentThread());
4000 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4006 if( pCurrentFcb != NULL)
4009 IO_STATUS_BLOCK stIoStatus;
4011 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4012 AFS_TRACE_LEVEL_VERBOSE_2,
4013 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4014 &DirEntry->NameInformation.FileName,
4015 pObjectInfo->FileId.Cell,
4016 pObjectInfo->FileId.Volume,
4017 pObjectInfo->FileId.Vnode,
4018 pObjectInfo->FileId.Unique);
4020 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4023 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4024 AFS_TRACE_LEVEL_VERBOSE,
4025 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4026 &DirEntry->NameInformation.FileName,
4027 pObjectInfo->FileId.Cell,
4028 pObjectInfo->FileId.Volume,
4029 pObjectInfo->FileId.Vnode,
4030 pObjectInfo->FileId.Unique,
4031 pObjectInfo->DataVersion.LowPart,
4032 pDirEnumEntry->DataVersion.LowPart
4035 bPurgeExtents = TRUE;
4041 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4043 bPurgeExtents = TRUE;
4045 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4046 AFS_TRACE_LEVEL_VERBOSE,
4047 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4048 &DirEntry->NameInformation.FileName,
4049 pObjectInfo->FileId.Cell,
4050 pObjectInfo->FileId.Volume,
4051 pObjectInfo->FileId.Vnode,
4052 pObjectInfo->FileId.Unique);
4054 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4057 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4058 AFS_TRACE_LEVEL_VERBOSE,
4059 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4060 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4061 PsGetCurrentThread());
4063 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4067 // Release Fcb->Resource to avoid Trend Micro deadlock
4070 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
4075 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4080 if( !NT_SUCCESS( stIoStatus.Status))
4083 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4084 AFS_TRACE_LEVEL_ERROR,
4085 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4086 &DirEntry->NameInformation.FileName,
4087 pObjectInfo->FileId.Cell,
4088 pObjectInfo->FileId.Volume,
4089 pObjectInfo->FileId.Vnode,
4090 pObjectInfo->FileId.Unique,
4092 stIoStatus.Information);
4094 ntStatus = stIoStatus.Status;
4097 if ( bPurgeExtents &&
4098 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4101 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4107 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4108 AFS_TRACE_LEVEL_WARNING,
4109 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4110 &DirEntry->NameInformation.FileName,
4111 pObjectInfo->FileId.Cell,
4112 pObjectInfo->FileId.Volume,
4113 pObjectInfo->FileId.Vnode,
4114 pObjectInfo->FileId.Unique);
4116 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4120 __except( EXCEPTION_EXECUTE_HANDLER)
4122 ntStatus = GetExceptionCode();
4126 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4127 &DirEntry->NameInformation.FileName,
4128 pObjectInfo->FileId.Cell,
4129 pObjectInfo->FileId.Volume,
4130 pObjectInfo->FileId.Vnode,
4131 pObjectInfo->FileId.Unique,
4134 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4137 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4138 AFS_TRACE_LEVEL_VERBOSE,
4139 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4140 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4141 PsGetCurrentThread());
4143 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4145 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4154 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4159 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4161 bReleaseFcb = FALSE;
4163 if ( bPurgeExtents &&
4166 AFSFlushExtents( pCurrentFcb,
4173 // Update the metadata for the entry but only if it is safe to do so.
4174 // If it was determined that a data version change has occurred or
4175 // that a pending data verification was required, do not update the
4176 // ObjectInfo meta data or the FileObject size information. That
4177 // way it is consistent for the next time that the data is verified
4181 if ( !(bPurgeExtents && bSafeToPurge))
4184 ntStatus = AFSUpdateMetaData( DirEntry,
4187 if( !NT_SUCCESS( ntStatus))
4190 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4191 AFS_TRACE_LEVEL_ERROR,
4192 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4193 &DirEntry->NameInformation.FileName,
4194 pObjectInfo->FileId.Cell,
4195 pObjectInfo->FileId.Volume,
4196 pObjectInfo->FileId.Vnode,
4197 pObjectInfo->FileId.Unique,
4203 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4206 // Update file sizes
4209 if( pObjectInfo->Fcb != NULL)
4211 FILE_OBJECT *pCCFileObject;
4213 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4214 AFS_TRACE_LEVEL_VERBOSE,
4215 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4216 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4217 PsGetCurrentThread());
4219 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4222 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4224 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4225 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4226 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4228 if ( pCCFileObject != NULL)
4230 CcSetFileSizes( pCCFileObject,
4231 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4234 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4235 AFS_TRACE_LEVEL_VERBOSE,
4236 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4237 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4238 PsGetCurrentThread());
4240 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4246 case AFS_FILE_TYPE_DIRECTORY:
4249 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4253 // For a directory or root entry flush the content of
4254 // the directory enumeration.
4257 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4258 AFS_TRACE_LEVEL_VERBOSE,
4259 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4260 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4261 PsGetCurrentThread());
4263 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4266 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4267 AFS_TRACE_LEVEL_VERBOSE_2,
4268 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4269 &DirEntry->NameInformation.FileName,
4270 pObjectInfo->FileId.Cell,
4271 pObjectInfo->FileId.Volume,
4272 pObjectInfo->FileId.Vnode,
4273 pObjectInfo->FileId.Unique);
4275 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4278 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4281 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4284 if( !NT_SUCCESS( ntStatus))
4287 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4288 AFS_TRACE_LEVEL_ERROR,
4289 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4290 &DirEntry->NameInformation.FileName,
4291 pObjectInfo->FileId.Cell,
4292 pObjectInfo->FileId.Volume,
4293 pObjectInfo->FileId.Vnode,
4294 pObjectInfo->FileId.Unique,
4302 // Update the metadata for the entry
4305 ntStatus = AFSUpdateMetaData( DirEntry,
4308 if( NT_SUCCESS( ntStatus))
4311 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4319 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4320 AFS_TRACE_LEVEL_WARNING,
4321 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4322 pObjectInfo->FileType,
4324 &DirEntry->NameInformation.FileName,
4325 pObjectInfo->FileId.Cell,
4326 pObjectInfo->FileId.Volume,
4327 pObjectInfo->FileId.Vnode,
4328 pObjectInfo->FileId.Unique);
4338 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4341 if( pDirEnumEntry != NULL)
4344 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4352 AFSInitializeSpecialShareNameList()
4355 NTSTATUS ntStatus = STATUS_SUCCESS;
4356 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4357 AFSObjectInfoCB *pObjectInfoCB = NULL;
4358 UNICODE_STRING uniShareName;
4359 ULONG ulEntryLength = 0;
4360 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4366 RtlInitUnicodeString( &uniShareName,
4369 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4372 if( pObjectInfoCB == NULL)
4375 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4378 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4379 AFS_OBJECT_REFERENCE_GLOBAL);
4381 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4382 AFS_TRACE_LEVEL_VERBOSE,
4383 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4387 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4389 ulEntryLength = sizeof( AFSDirectoryCB) +
4390 uniShareName.Length;
4392 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4396 if( pDirNode == NULL)
4399 AFSDeleteObjectInfo( &pObjectInfoCB);
4401 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4404 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4405 AFS_TRACE_LEVEL_VERBOSE,
4406 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4409 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4410 sizeof( AFSNonPagedDirectoryCB),
4411 AFS_DIR_ENTRY_NP_TAG);
4413 if( pNonPagedDirEntry == NULL)
4416 ExFreePool( pDirNode);
4418 AFSDeleteObjectInfo( &pObjectInfoCB);
4420 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4423 RtlZeroMemory( pDirNode,
4426 RtlZeroMemory( pNonPagedDirEntry,
4427 sizeof( AFSNonPagedDirectoryCB));
4429 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4431 pDirNode->NonPaged = pNonPagedDirEntry;
4433 pDirNode->ObjectInformation = pObjectInfoCB;
4439 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4441 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4443 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4445 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4447 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4448 uniShareName.Buffer,
4449 pDirNode->NameInformation.FileName.Length);
4451 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4454 AFSSpecialShareNames = pDirNode;
4456 pLastDirNode = pDirNode;
4459 RtlInitUnicodeString( &uniShareName,
4462 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4465 if( pObjectInfoCB == NULL)
4468 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4471 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4472 AFS_OBJECT_REFERENCE_GLOBAL);
4474 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4475 AFS_TRACE_LEVEL_VERBOSE,
4476 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4480 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4482 ulEntryLength = sizeof( AFSDirectoryCB) +
4483 uniShareName.Length;
4485 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4489 if( pDirNode == NULL)
4492 AFSDeleteObjectInfo( &pObjectInfoCB);
4494 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4497 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4498 AFS_TRACE_LEVEL_VERBOSE,
4499 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4502 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4503 sizeof( AFSNonPagedDirectoryCB),
4504 AFS_DIR_ENTRY_NP_TAG);
4506 if( pNonPagedDirEntry == NULL)
4509 ExFreePool( pDirNode);
4511 AFSDeleteObjectInfo( &pObjectInfoCB);
4513 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4516 RtlZeroMemory( pDirNode,
4519 RtlZeroMemory( pNonPagedDirEntry,
4520 sizeof( AFSNonPagedDirectoryCB));
4522 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4524 pDirNode->NonPaged = pNonPagedDirEntry;
4526 pDirNode->ObjectInformation = pObjectInfoCB;
4532 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4534 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4536 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4538 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4540 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4541 uniShareName.Buffer,
4542 pDirNode->NameInformation.FileName.Length);
4544 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4547 pLastDirNode->ListEntry.fLink = pDirNode;
4549 pDirNode->ListEntry.bLink = pLastDirNode;
4553 if( !NT_SUCCESS( ntStatus))
4556 if( AFSSpecialShareNames != NULL)
4559 pDirNode = AFSSpecialShareNames;
4561 while( pDirNode != NULL)
4564 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4566 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4568 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4570 ExFreePool( pDirNode->NonPaged);
4572 ExFreePool( pDirNode);
4574 pDirNode = pLastDirNode;
4577 AFSSpecialShareNames = NULL;
4586 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4587 IN UNICODE_STRING *SecondaryName)
4590 AFSDirectoryCB *pDirectoryCB = NULL;
4591 ULONGLONG ullHash = 0;
4592 UNICODE_STRING uniFullShareName;
4598 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4599 AFS_TRACE_LEVEL_VERBOSE_2,
4600 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4604 uniFullShareName = *ShareName;
4607 // Generate our hash value
4610 ullHash = AFSGenerateCRC( &uniFullShareName,
4614 // Loop through our special share names to see if this is one of them
4617 pDirectoryCB = AFSSpecialShareNames;
4619 while( pDirectoryCB != NULL)
4622 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4628 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4632 return pDirectoryCB;
4636 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4640 // Block on the queue flush event
4643 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4653 AFSWaitOnQueuedReleases()
4656 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4659 // Block on the queue flush event
4662 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4672 AFSIsEqualFID( IN AFSFileID *FileId1,
4673 IN AFSFileID *FileId2)
4676 BOOLEAN bIsEqual = FALSE;
4678 if( FileId1->Hash == FileId2->Hash &&
4679 FileId1->Unique == FileId2->Unique &&
4680 FileId1->Vnode == FileId2->Vnode &&
4681 FileId1->Volume == FileId2->Volume &&
4682 FileId1->Cell == FileId2->Cell)
4692 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4695 NTSTATUS ntStatus = STATUS_SUCCESS;
4696 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4701 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4704 // Reset the directory list information
4707 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4709 while( pCurrentDirEntry != NULL)
4712 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4714 if( pCurrentDirEntry->DirOpenReferenceCount <= 0)
4717 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4718 AFS_TRACE_LEVEL_VERBOSE,
4719 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4721 &pCurrentDirEntry->NameInformation.FileName);
4723 AFSDeleteDirEntry( ObjectInfoCB,
4729 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4730 AFS_TRACE_LEVEL_VERBOSE,
4731 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4733 &pCurrentDirEntry->NameInformation.FileName);
4735 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4737 AFSRemoveNameEntry( ObjectInfoCB,
4741 pCurrentDirEntry = pNextDirEntry;
4744 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4746 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4748 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4750 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4752 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4754 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4756 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4757 AFS_TRACE_LEVEL_VERBOSE,
4758 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4759 ObjectInfoCB->FileId.Cell,
4760 ObjectInfoCB->FileId.Volume,
4761 ObjectInfoCB->FileId.Vnode,
4762 ObjectInfoCB->FileId.Unique);
4769 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4772 NTSTATUS ntStatus = STATUS_SUCCESS;
4773 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4774 UNICODE_STRING uniFullName;
4779 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4780 AFS_TRACE_LEVEL_VERBOSE,
4781 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4782 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4783 PsGetCurrentThread());
4785 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4788 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4791 try_return( ntStatus);
4795 // Initialize the root information
4798 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4801 // Enumerate the shares in the volume
4804 ntStatus = AFSEnumerateDirectory( AuthGroup,
4805 &AFSGlobalRoot->ObjectInformation,
4808 if( !NT_SUCCESS( ntStatus))
4811 try_return( ntStatus);
4814 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4817 // Indicate the node is initialized
4820 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4822 uniFullName.MaximumLength = PAGE_SIZE;
4823 uniFullName.Length = 0;
4825 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4826 uniFullName.MaximumLength,
4827 AFS_GENERIC_MEMORY_12_TAG);
4829 if( uniFullName.Buffer == NULL)
4833 // Reset the directory content
4836 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4838 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4840 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4844 // Populate our list of entries in the NP enumeration list
4847 while( pDirGlobalDirNode != NULL)
4850 uniFullName.Buffer[ 0] = L'\\';
4851 uniFullName.Buffer[ 1] = L'\\';
4853 uniFullName.Length = 2 * sizeof( WCHAR);
4855 RtlCopyMemory( &uniFullName.Buffer[ 2],
4856 AFSServerName.Buffer,
4857 AFSServerName.Length);
4859 uniFullName.Length += AFSServerName.Length;
4861 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4863 uniFullName.Length += sizeof( WCHAR);
4865 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4866 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4867 pDirGlobalDirNode->NameInformation.FileName.Length);
4869 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4871 AFSAddConnectionEx( &uniFullName,
4872 RESOURCEDISPLAYTYPE_SHARE,
4875 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4878 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
4882 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4889 AFSIsRelativeName( IN UNICODE_STRING *Name)
4892 BOOLEAN bIsRelative = FALSE;
4894 if( Name->Length > 0 &&
4895 Name->Buffer[ 0] != L'\\')
4905 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
4907 UNICODE_STRING uniTempName;
4908 BOOLEAN bIsAbsolute = FALSE;
4911 // An absolute AFS path must begin with \afs\... or equivalent
4914 if ( Name->Length == 0 ||
4915 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
4916 Name->Buffer[ 0] != L'\\' ||
4917 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
4923 uniTempName.Length = AFSMountRootName.Length;
4924 uniTempName.MaximumLength = AFSMountRootName.Length;
4926 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4927 uniTempName.MaximumLength,
4928 AFS_NAME_BUFFER_TWO_TAG);
4930 if( uniTempName.Buffer == NULL)
4936 RtlCopyMemory( uniTempName.Buffer,
4938 AFSMountRootName.Length);
4940 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
4944 AFSExFreePoolWithTag( uniTempName.Buffer,
4945 AFS_NAME_BUFFER_TWO_TAG);
4952 AFSUpdateName( IN UNICODE_STRING *Name)
4957 while( usIndex < Name->Length/sizeof( WCHAR))
4960 if( Name->Buffer[ usIndex] == L'/')
4963 Name->Buffer[ usIndex] = L'\\';
4973 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4974 IN OUT ULONG *Flags,
4975 IN WCHAR *NameBuffer,
4976 IN USHORT NameLength)
4979 NTSTATUS ntStatus = STATUS_SUCCESS;
4980 WCHAR *pTmpBuffer = NULL;
4986 // If we have enough space then just move in the name otherwise
4987 // allocate a new buffer
4990 if( TargetName->Length < NameLength)
4993 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4995 AFS_NAME_BUFFER_FIVE_TAG);
4997 if( pTmpBuffer == NULL)
5000 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5003 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5006 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5009 TargetName->MaximumLength = NameLength;
5011 TargetName->Buffer = pTmpBuffer;
5013 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5016 TargetName->Length = NameLength;
5018 RtlCopyMemory( TargetName->Buffer,
5020 TargetName->Length);
5023 // Update the name in the buffer
5026 AFSUpdateName( TargetName);
5037 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
5038 IN ULONG InitialElementCount)
5041 AFSNameArrayHdr *pNameArray = NULL;
5042 AFSNameArrayCB *pCurrentElement = NULL;
5043 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5049 if( InitialElementCount == 0)
5052 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
5055 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
5056 sizeof( AFSNameArrayHdr) +
5057 (InitialElementCount * sizeof( AFSNameArrayCB)),
5058 AFS_NAME_ARRAY_TAG);
5060 if( pNameArray == NULL)
5063 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5064 AFS_TRACE_LEVEL_ERROR,
5065 "AFSInitNameArray Failed to allocate name array\n");
5067 try_return( pNameArray);
5070 RtlZeroMemory( pNameArray,
5071 sizeof( AFSNameArrayHdr) +
5072 (InitialElementCount * sizeof( AFSNameArrayCB)));
5074 pNameArray->MaxElementCount = InitialElementCount;
5076 if( DirectoryCB != NULL)
5079 pCurrentElement = &pNameArray->ElementArray[ 0];
5081 pNameArray->CurrentEntry = pCurrentElement;
5083 pNameArray->Count = 1;
5085 pNameArray->LinkCount = 0;
5087 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5089 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5090 AFS_TRACE_LEVEL_VERBOSE,
5091 "AFSInitNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5093 &DirectoryCB->NameInformation.FileName,
5097 pCurrentElement->DirectoryCB = DirectoryCB;
5099 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5101 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5103 if( pCurrentElement->FileId.Vnode == 1)
5106 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5109 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5110 AFS_TRACE_LEVEL_VERBOSE,
5111 "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5113 pCurrentElement->DirectoryCB,
5114 pCurrentElement->FileId.Cell,
5115 pCurrentElement->FileId.Volume,
5116 pCurrentElement->FileId.Vnode,
5117 pCurrentElement->FileId.Unique,
5118 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5119 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5131 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
5132 IN UNICODE_STRING *Path,
5133 IN AFSDirectoryCB *DirectoryCB)
5136 NTSTATUS ntStatus = STATUS_SUCCESS;
5137 AFSNameArrayCB *pCurrentElement = NULL;
5143 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5144 AFS_TRACE_LEVEL_VERBOSE,
5145 "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5149 DirectoryCB->ObjectInformation->FileId.Cell,
5150 DirectoryCB->ObjectInformation->FileId.Volume,
5151 DirectoryCB->ObjectInformation->FileId.Vnode,
5152 DirectoryCB->ObjectInformation->FileId.Unique,
5153 &DirectoryCB->NameInformation.FileName,
5154 DirectoryCB->ObjectInformation->FileType);
5157 // Init some info in the header
5160 pCurrentElement = &NameArray->ElementArray[ 0];
5162 NameArray->CurrentEntry = pCurrentElement;
5165 // The first entry points at the root
5168 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
5170 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5172 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5173 AFS_TRACE_LEVEL_VERBOSE,
5174 "AFSPopulateNameArray [NA:%p] Increment count on volume %wZ DE %p Cnt %d\n",
5176 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5177 pCurrentElement->DirectoryCB,
5180 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
5182 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
5184 pCurrentElement->Flags = 0;
5186 if( pCurrentElement->FileId.Vnode == 1)
5189 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5192 NameArray->Count = 1;
5194 NameArray->LinkCount = 0;
5196 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5197 AFS_TRACE_LEVEL_VERBOSE,
5198 "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5200 pCurrentElement->DirectoryCB,
5201 pCurrentElement->FileId.Cell,
5202 pCurrentElement->FileId.Volume,
5203 pCurrentElement->FileId.Vnode,
5204 pCurrentElement->FileId.Unique,
5205 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5206 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5209 // If the root is the parent then we are done ...
5212 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
5214 try_return( ntStatus);
5226 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
5227 IN AFSNameArrayHdr *RelatedNameArray,
5228 IN AFSDirectoryCB *DirectoryCB)
5231 NTSTATUS ntStatus = STATUS_SUCCESS;
5232 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
5238 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5239 AFS_TRACE_LEVEL_VERBOSE,
5240 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5244 DirectoryCB->ObjectInformation->FileId.Cell,
5245 DirectoryCB->ObjectInformation->FileId.Volume,
5246 DirectoryCB->ObjectInformation->FileId.Vnode,
5247 DirectoryCB->ObjectInformation->FileId.Unique,
5248 &DirectoryCB->NameInformation.FileName,
5249 DirectoryCB->ObjectInformation->FileType);
5252 // Init some info in the header
5255 pCurrentElement = &NameArray->ElementArray[ 0];
5257 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5259 NameArray->Count = 0;
5261 NameArray->LinkCount = RelatedNameArray->LinkCount;
5264 // Populate the name array with the data from the related array
5270 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5272 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5274 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5276 pCurrentElement->Flags = 0;
5278 if( pCurrentElement->FileId.Vnode == 1)
5281 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5284 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5286 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5287 AFS_TRACE_LEVEL_VERBOSE,
5288 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5290 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5291 pCurrentElement->DirectoryCB,
5294 lCount = InterlockedIncrement( &NameArray->Count);
5296 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5297 AFS_TRACE_LEVEL_VERBOSE,
5298 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5301 pCurrentElement->DirectoryCB,
5302 pCurrentElement->FileId.Cell,
5303 pCurrentElement->FileId.Volume,
5304 pCurrentElement->FileId.Vnode,
5305 pCurrentElement->FileId.Unique,
5306 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5307 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5309 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5310 NameArray->Count == RelatedNameArray->Count)
5322 pCurrentRelatedElement++;
5325 NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
5332 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5335 NTSTATUS ntStatus = STATUS_SUCCESS;
5336 AFSNameArrayCB *pCurrentElement = NULL;
5337 LONG lCount, lElement;
5342 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5343 AFS_TRACE_LEVEL_VERBOSE,
5344 "AFSFreeNameArray [NA:%p]\n",
5347 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5350 pCurrentElement = &NameArray->ElementArray[ lElement];
5352 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5354 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5355 AFS_TRACE_LEVEL_VERBOSE,
5356 "AFSFreeNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5358 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5359 pCurrentElement->DirectoryCB,
5362 ASSERT( lCount >= 0);
5365 AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
5372 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5373 IN AFSDirectoryCB *DirectoryCB)
5376 NTSTATUS ntStatus = STATUS_SUCCESS;
5377 AFSNameArrayCB *pCurrentElement = NULL;
5383 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5384 AFS_TRACE_LEVEL_VERBOSE,
5385 "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5388 DirectoryCB->ObjectInformation->FileId.Cell,
5389 DirectoryCB->ObjectInformation->FileId.Volume,
5390 DirectoryCB->ObjectInformation->FileId.Vnode,
5391 DirectoryCB->ObjectInformation->FileId.Unique,
5392 &DirectoryCB->NameInformation.FileName,
5393 DirectoryCB->ObjectInformation->FileType);
5395 if( NameArray->Count == (LONG) NameArray->MaxElementCount)
5398 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5399 AFS_TRACE_LEVEL_ERROR,
5400 "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
5403 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5406 for ( lCount = 0; lCount < NameArray->Count; lCount++)
5409 if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
5410 &DirectoryCB->ObjectInformation->FileId) )
5413 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5414 AFS_TRACE_LEVEL_WARNING,
5415 "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
5418 STATUS_ACCESS_DENIED);
5420 try_return( ntStatus = STATUS_ACCESS_DENIED);
5424 if( NameArray->Count > 0)
5427 NameArray->CurrentEntry++;
5431 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5434 pCurrentElement = NameArray->CurrentEntry;
5436 lCount = InterlockedIncrement( &NameArray->Count);
5438 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5440 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5441 AFS_TRACE_LEVEL_VERBOSE,
5442 "AFSInsertNextElement [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5444 &DirectoryCB->NameInformation.FileName,
5448 ASSERT( lCount > 0);
5450 pCurrentElement->DirectoryCB = DirectoryCB;
5452 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5454 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5456 pCurrentElement->Flags = 0;
5458 if( pCurrentElement->FileId.Vnode == 1)
5461 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5464 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5465 AFS_TRACE_LEVEL_VERBOSE,
5466 "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5468 NameArray->Count - 1,
5469 pCurrentElement->DirectoryCB,
5470 pCurrentElement->FileId.Cell,
5471 pCurrentElement->FileId.Volume,
5472 pCurrentElement->FileId.Vnode,
5473 pCurrentElement->FileId.Unique,
5474 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5475 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5486 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5489 AFSDirectoryCB *pDirectoryCB = NULL;
5490 AFSNameArrayCB *pCurrentElement = NULL;
5491 BOOLEAN bVolumeRoot = FALSE;
5497 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5498 AFS_TRACE_LEVEL_VERBOSE,
5499 "AFSBackupEntry [NA:%p]\n",
5502 if( NameArray->Count == 0)
5505 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5506 AFS_TRACE_LEVEL_ERROR,
5507 "AFSBackupEntry [NA:%p] No more entries\n",
5510 try_return( pCurrentElement);
5513 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->NameArrayReferenceCount);
5515 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5516 AFS_TRACE_LEVEL_VERBOSE,
5517 "AFSBackupEntry [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5519 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5520 NameArray->CurrentEntry->DirectoryCB,
5523 ASSERT( lCount >= 0);
5525 NameArray->CurrentEntry->DirectoryCB = NULL;
5527 lCount = InterlockedDecrement( &NameArray->Count);
5531 NameArray->CurrentEntry = NULL;
5533 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5534 AFS_TRACE_LEVEL_ERROR,
5535 "AFSBackupEntry [NA:%p] No more entries\n",
5541 bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5543 NameArray->CurrentEntry--;
5545 pCurrentElement = NameArray->CurrentEntry;
5547 pDirectoryCB = pCurrentElement->DirectoryCB;
5549 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5550 AFS_TRACE_LEVEL_VERBOSE,
5551 "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5553 NameArray->Count - 1,
5554 pCurrentElement->DirectoryCB,
5555 pCurrentElement->FileId.Cell,
5556 pCurrentElement->FileId.Volume,
5557 pCurrentElement->FileId.Vnode,
5558 pCurrentElement->FileId.Unique,
5559 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5560 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5563 // If the entry we are removing is a volume root,
5564 // we must remove the mount point entry as well.
5565 // If the NameArray was constructed by checking the
5566 // share name via the service, the name array can
5567 // contain two volume roots in sequence without a
5568 // mount point separating them.
5572 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
5575 pDirectoryCB = AFSBackupEntry( NameArray);
5585 return pDirectoryCB;
5589 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5592 AFSDirectoryCB *pDirEntry = NULL;
5593 AFSNameArrayCB *pElement = NULL;
5598 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5599 AFS_TRACE_LEVEL_VERBOSE,
5600 "AFSGetParentEntry [NA:%p]\n",
5603 if( NameArray->Count == 0 ||
5604 NameArray->Count == 1)
5607 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5608 AFS_TRACE_LEVEL_ERROR,
5609 "AFSGetParentEntry [NA:%p] No more entries\n",
5612 try_return( pDirEntry = NULL);
5615 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5617 pDirEntry = pElement->DirectoryCB;
5619 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5620 AFS_TRACE_LEVEL_VERBOSE,
5621 "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5623 NameArray->Count - 2,
5624 pElement->DirectoryCB,
5625 pElement->FileId.Cell,
5626 pElement->FileId.Volume,
5627 pElement->FileId.Vnode,
5628 pElement->FileId.Unique,
5629 &pElement->DirectoryCB->NameInformation.FileName,
5630 pElement->DirectoryCB->ObjectInformation->FileType);
5641 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5642 IN AFSDirectoryCB *DirectoryCB)
5645 AFSNameArrayCB *pCurrentElement = NULL;
5646 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5647 LONG lCount, lElement;
5652 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5653 AFS_TRACE_LEVEL_VERBOSE,
5654 "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5657 DirectoryCB->ObjectInformation->FileId.Cell,
5658 DirectoryCB->ObjectInformation->FileId.Volume,
5659 DirectoryCB->ObjectInformation->FileId.Vnode,
5660 DirectoryCB->ObjectInformation->FileId.Unique,
5661 &DirectoryCB->NameInformation.FileName,
5662 DirectoryCB->ObjectInformation->FileType);
5664 // Dereference previous name array contents
5667 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5670 pCurrentElement = &NameArray->ElementArray[ lElement];
5672 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5674 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5675 AFS_TRACE_LEVEL_VERBOSE,
5676 "AFSResetNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5678 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5679 pCurrentElement->DirectoryCB,
5682 ASSERT( lCount >= 0);
5685 RtlZeroMemory( NameArray,
5686 sizeof( AFSNameArrayHdr) +
5687 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5689 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5691 if( DirectoryCB != NULL)
5694 pCurrentElement = &NameArray->ElementArray[ 0];
5696 NameArray->CurrentEntry = pCurrentElement;
5698 NameArray->Count = 1;
5700 NameArray->LinkCount = 0;
5702 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5704 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5705 AFS_TRACE_LEVEL_VERBOSE,
5706 "AFSResetNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5708 &DirectoryCB->NameInformation.FileName,
5712 pCurrentElement->DirectoryCB = DirectoryCB;
5714 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5716 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5718 pCurrentElement->Flags = 0;
5720 if( pCurrentElement->FileId.Vnode == 1)
5723 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5726 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5727 AFS_TRACE_LEVEL_VERBOSE,
5728 "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5730 pCurrentElement->DirectoryCB,
5731 pCurrentElement->FileId.Cell,
5732 pCurrentElement->FileId.Volume,
5733 pCurrentElement->FileId.Vnode,
5734 pCurrentElement->FileId.Unique,
5735 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5736 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5744 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5747 AFSNameArrayCB *pCurrentElement = NULL;
5749 pCurrentElement = &NameArray->ElementArray[ 0];
5751 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5753 while( pCurrentElement->DirectoryCB != NULL)
5756 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5757 pCurrentElement->FileId.Cell,
5758 pCurrentElement->FileId.Volume,
5759 pCurrentElement->FileId.Vnode,
5760 pCurrentElement->FileId.Unique,
5761 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5766 AFSPrint("AFSDumpNameArray End\n\n");
5772 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5777 // Depending on the type of node, set the event
5780 switch( Fcb->Header.NodeTypeCode)
5783 case AFS_DIRECTORY_FCB:
5788 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5798 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5804 // Depending on the type of node, set the event
5807 switch( Fcb->Header.NodeTypeCode)
5810 case AFS_DIRECTORY_FCB:
5815 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5817 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5827 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5830 BOOLEAN bIsInProcess = FALSE;
5835 if( ObjectInfo->Fcb == NULL)
5838 try_return( bIsInProcess);
5841 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5844 case AFS_DIRECTORY_FCB:
5849 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5852 bIsInProcess = TRUE;
5864 return bIsInProcess;
5868 AFSVerifyVolume( IN ULONGLONG ProcessId,
5869 IN AFSVolumeCB *VolumeCB)
5872 UNREFERENCED_PARAMETER(ProcessId);
5873 UNREFERENCED_PARAMETER(VolumeCB);
5874 NTSTATUS ntStatus = STATUS_SUCCESS;
5881 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5884 NTSTATUS ntStatus = STATUS_SUCCESS;
5885 AFSObjectInfoCB *pObjectInfoCB = NULL;
5886 AFSDirectoryCB *pDirNode = NULL;
5887 ULONG ulEntryLength = 0;
5888 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5894 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5897 if( pObjectInfoCB == NULL)
5900 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5903 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5904 AFS_OBJECT_REFERENCE_DIRENTRY);
5906 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5907 AFS_TRACE_LEVEL_VERBOSE,
5908 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5912 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5914 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5916 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5918 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5922 if( pDirNode == NULL)
5925 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5928 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5929 AFS_TRACE_LEVEL_VERBOSE,
5930 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5933 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5934 sizeof( AFSNonPagedDirectoryCB),
5935 AFS_DIR_ENTRY_NP_TAG);
5937 if( pNonPagedDirEntry == NULL)
5940 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5943 RtlZeroMemory( pDirNode,
5946 RtlZeroMemory( pNonPagedDirEntry,
5947 sizeof( AFSNonPagedDirectoryCB));
5949 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5951 pDirNode->NonPaged = pNonPagedDirEntry;
5953 pDirNode->ObjectInformation = pObjectInfoCB;
5955 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5961 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5963 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5965 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5967 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5969 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5970 AFSPIOCtlName.Buffer,
5971 pDirNode->NameInformation.FileName.Length);
5973 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5976 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5979 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5980 AFS_TRACE_LEVEL_WARNING,
5981 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5982 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5985 try_return( ntStatus = STATUS_REPARSE);
5990 if ( ntStatus != STATUS_SUCCESS)
5993 if ( pDirNode != NULL)
5996 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5997 AFS_TRACE_LEVEL_VERBOSE,
5998 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
6001 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
6004 if( pNonPagedDirEntry != NULL)
6007 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
6009 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
6012 if ( pObjectInfoCB != NULL)
6015 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
6016 AFS_OBJECT_REFERENCE_DIRENTRY);
6018 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6019 AFS_TRACE_LEVEL_VERBOSE,
6020 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
6024 AFSDeleteObjectInfo( &pObjectInfoCB);
6033 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
6034 IN AFSDirectoryCB *DirectoryCB,
6035 IN UNICODE_STRING *ParentPathName,
6036 IN AFSNameArrayHdr *RelatedNameArray,
6038 OUT AFSFileInfoCB *FileInfo)
6041 NTSTATUS ntStatus = STATUS_SUCCESS;
6042 AFSDirEnumEntry *pDirEntry = NULL;
6043 UNICODE_STRING uniFullPathName = {0};
6044 AFSNameArrayHdr *pNameArray = NULL;
6045 AFSVolumeCB *pVolumeCB = NULL;
6046 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6047 WCHAR *pwchBuffer = NULL;
6048 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6049 ULONG ulNameDifference = 0;
6056 // Retrieve a target name for the entry
6059 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6062 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6065 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6067 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6072 if( !NT_SUCCESS( ntStatus) ||
6073 pDirEntry->TargetNameLength == 0)
6076 if( pDirEntry != NULL)
6079 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6082 try_return( ntStatus);
6085 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6088 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6092 // Update the target name
6095 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6096 &DirectoryCB->Flags,
6097 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6098 (USHORT)pDirEntry->TargetNameLength);
6100 if( !NT_SUCCESS( ntStatus))
6103 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6105 try_return( ntStatus);
6109 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6113 // Need to pass the full path in for parsing.
6116 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
6119 uniFullPathName.Length = 0;
6120 uniFullPathName.MaximumLength = ParentPathName->Length +
6122 DirectoryCB->NameInformation.TargetName.Length;
6124 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6125 uniFullPathName.MaximumLength,
6126 AFS_NAME_BUFFER_SIX_TAG);
6128 if( uniFullPathName.Buffer == NULL)
6131 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6133 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6136 pwchBuffer = uniFullPathName.Buffer;
6138 RtlZeroMemory( uniFullPathName.Buffer,
6139 uniFullPathName.MaximumLength);
6141 RtlCopyMemory( uniFullPathName.Buffer,
6142 ParentPathName->Buffer,
6143 ParentPathName->Length);
6145 uniFullPathName.Length = ParentPathName->Length;
6147 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
6148 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
6151 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
6153 uniFullPathName.Length += sizeof( WCHAR);
6156 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
6157 DirectoryCB->NameInformation.TargetName.Buffer,
6158 DirectoryCB->NameInformation.TargetName.Length);
6160 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
6162 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
6163 uniParsedName.MaximumLength = uniParsedName.Length;
6165 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
6167 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6170 // We populate up to the current parent
6173 if( RelatedNameArray != NULL)
6176 pNameArray = AFSInitNameArray( NULL,
6177 RelatedNameArray->MaxElementCount);
6179 if( pNameArray == NULL)
6182 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6185 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
6192 pNameArray = AFSInitNameArray( NULL,
6195 if( pNameArray == NULL)
6198 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6201 ntStatus = AFSPopulateNameArray( pNameArray,
6206 if( !NT_SUCCESS( ntStatus))
6209 try_return( ntStatus);
6212 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
6214 pParentDirEntry = ParentDirectoryCB;
6219 uniFullPathName.Length = 0;
6220 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6222 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6223 uniFullPathName.MaximumLength,
6224 AFS_NAME_BUFFER_SEVEN_TAG);
6226 if( uniFullPathName.Buffer == NULL)
6229 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6231 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6234 pwchBuffer = uniFullPathName.Buffer;
6236 RtlZeroMemory( uniFullPathName.Buffer,
6237 uniFullPathName.MaximumLength);
6239 RtlCopyMemory( uniFullPathName.Buffer,
6240 DirectoryCB->NameInformation.TargetName.Buffer,
6241 DirectoryCB->NameInformation.TargetName.Length);
6243 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6246 // This name should begin with the \afs server so parse it off and check it
6249 FsRtlDissectName( uniFullPathName,
6253 if( RtlCompareUnicodeString( &uniComponentName,
6258 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6260 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6261 AFS_TRACE_LEVEL_ERROR,
6262 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
6265 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
6268 uniFullPathName = uniRemainingPath;
6270 uniParsedName = uniFullPathName;
6272 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6274 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6280 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6283 if( pNameArray == NULL)
6286 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6289 pVolumeCB = AFSGlobalRoot;
6291 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6295 // Increment the ref count on the volume and dir entry for correct processing below
6298 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6300 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6301 AFS_TRACE_LEVEL_VERBOSE,
6302 "AFSRetrieveFileAttributes Increment count on volume %p Cnt %d\n",
6306 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6308 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6309 AFS_TRACE_LEVEL_VERBOSE,
6310 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6311 &pParentDirEntry->NameInformation.FileName,
6316 ntStatus = AFSLocateNameEntry( NULL,
6321 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
6327 if( !NT_SUCCESS( ntStatus) ||
6328 ntStatus == STATUS_REPARSE)
6332 // The volume lock was released on failure or reparse above
6333 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6336 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6339 if( pVolumeCB != NULL)
6342 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6344 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6345 AFS_TRACE_LEVEL_VERBOSE,
6346 "AFSRetrieveFileAttributes Decrement count on volume %p Cnt %d\n",
6351 if( pDirectoryEntry != NULL)
6354 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6356 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6357 AFS_TRACE_LEVEL_VERBOSE,
6358 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6359 &pDirectoryEntry->NameInformation.FileName,
6364 ASSERT( lCount >= 0);
6369 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6371 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6372 AFS_TRACE_LEVEL_VERBOSE,
6373 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6374 &pParentDirEntry->NameInformation.FileName,
6379 ASSERT( lCount >= 0);
6385 try_return( ntStatus);
6389 // Store off the information
6392 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6395 // Check for the mount point being returned
6398 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
6401 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6403 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
6404 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6407 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6410 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6415 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6419 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6421 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6423 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6425 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6427 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6429 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6432 // Remove the reference made above
6435 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6437 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6438 AFS_TRACE_LEVEL_VERBOSE,
6439 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
6440 &pDirectoryEntry->NameInformation.FileName,
6445 ASSERT( lCount >= 0);
6449 if( pDirEntry != NULL)
6452 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6455 if( pVolumeCB != NULL)
6458 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6460 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6461 AFS_TRACE_LEVEL_VERBOSE,
6462 "AFSRetrieveFileAttributes Decrement2 count on volume %p Cnt %d\n",
6467 if( pNameArray != NULL)
6470 AFSFreeNameArray( pNameArray);
6473 if( pwchBuffer != NULL)
6477 // Always free the buffer that we allocated as AFSLocateNameEntry
6478 // will not free it. If uniFullPathName.Buffer was allocated by
6479 // AFSLocateNameEntry, then we must free that as well.
6480 // Check that the uniFullPathName.Buffer in the string is not the same
6481 // offset by the length of the server name
6484 if( uniFullPathName.Length > 0 &&
6485 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6488 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6491 AFSExFreePoolWithTag( pwchBuffer, 0);
6499 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6500 IN ULONGLONG HashIndex)
6503 NTSTATUS ntStatus = STATUS_SUCCESS;
6504 AFSObjectInfoCB *pObjectInfo = NULL;
6510 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6511 sizeof( AFSObjectInfoCB),
6512 AFS_OBJECT_INFO_TAG);
6514 if( pObjectInfo == NULL)
6517 try_return( pObjectInfo);
6520 RtlZeroMemory( pObjectInfo,
6521 sizeof( AFSObjectInfoCB));
6523 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6524 sizeof( AFSNonPagedObjectInfoCB),
6525 AFS_NP_OBJECT_INFO_TAG);
6527 if( pObjectInfo->NonPagedInfo == NULL)
6530 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6532 try_return( pObjectInfo = NULL);
6535 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6537 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6539 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6541 if( ParentObjectInfo != NULL)
6544 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6546 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6548 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6550 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6551 AFS_OBJECT_REFERENCE_CHILD);
6553 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6554 AFS_TRACE_LEVEL_VERBOSE,
6555 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6561 // Initialize the access time
6564 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6569 ASSERT( ParentObjectInfo);
6572 // Insert the entry into the object tree and list
6575 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6577 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6580 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6585 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6586 &pObjectInfo->TreeEntry);
6588 ASSERT( NT_SUCCESS( ntStatus));
6592 // And the object list in the volume
6595 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6598 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6603 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6605 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6608 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6611 // Indicate the object is in the hash tree and linked list in the volume
6614 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6626 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6632 if ( ObjectInfo->ObjectReferenceCount == 0)
6635 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6638 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6643 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6646 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6651 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6653 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6658 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6660 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6666 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6672 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6675 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6680 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6682 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6684 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6687 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6690 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6692 ASSERT( lCount >= 0);
6694 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6700 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6701 IN AFSFileID *FileId)
6703 DWORD ntStatus = STATUS_SUCCESS;
6705 AFSObjectInfoCB *pObjectInfo = NULL;
6707 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6710 pObjectInfo = &VolumeCB->ObjectInformation;
6715 AFSAcquireExcl( VolumeCB->ObjectInfoTree.TreeLock,
6718 ullIndex = AFSCreateLowIndex( FileId);
6720 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6722 (AFSBTreeEntry **)&pObjectInfo);
6724 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6727 if ( NT_SUCCESS( ntStatus)) {
6729 AFSObjectInfoIncrement( pObjectInfo,
6730 AFS_OBJECT_REFERENCE_FIND);
6737 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6740 AFSObjectInfoDecrement( *ppObjectInfo,
6741 AFS_OBJECT_REFERENCE_FIND);
6743 *ppObjectInfo = NULL;
6747 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6750 BOOLEAN bAcquiredTreeLock = FALSE;
6751 AFSObjectInfoCB *pObjectInfo = (*ppObjectInfo);
6752 BOOLEAN bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6753 AFSObjectInfoCB * pParentObjectInfo = NULL;
6757 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_ROOT_VOLUME))
6761 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6762 // embedded in the VolumeCB.
6770 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6772 (*ppObjectInfo) = NULL;
6774 if( !ExIsResourceAcquiredExclusiveLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6777 ASSERT( !ExIsResourceAcquiredLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6779 AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6782 bAcquiredTreeLock = TRUE;
6785 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6788 pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
6789 &pObjectInfo->ParentFileId);
6793 // Remove it from the tree and list if it was inserted
6796 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6799 AFSRemoveHashEntry( &pObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6800 &pObjectInfo->TreeEntry);
6803 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6806 if( pObjectInfo->ListEntry.fLink == NULL)
6809 pObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6811 if( pObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6814 pObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6820 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6823 if( pObjectInfo->ListEntry.bLink == NULL)
6826 pObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6828 if( pObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6831 pObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6837 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6841 if( pParentObjectInfo != NULL)
6844 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6846 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6847 AFS_OBJECT_REFERENCE_CHILD);
6849 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6850 AFS_TRACE_LEVEL_VERBOSE,
6851 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6855 AFSReleaseObjectInfo( &pParentObjectInfo);
6858 if( bAcquiredTreeLock)
6861 AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6867 FileId = pObjectInfo->FileId;
6870 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6872 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6874 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6876 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6879 // Release the fid in the service
6885 AFSReleaseFid( &FileId);
6892 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6893 OUT AFSDirectoryCB **TargetDirEntry)
6896 NTSTATUS ntStatus = STATUS_SUCCESS;
6897 AFSDirEnumEntry *pDirEntry = NULL;
6898 UNICODE_STRING uniFullPathName = {0};
6899 AFSNameArrayHdr *pNameArray = NULL;
6900 AFSVolumeCB *pVolumeCB = NULL;
6901 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6902 WCHAR *pwchBuffer = NULL;
6903 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6904 ULONG ulNameDifference = 0;
6911 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6912 DirectoryCB->ObjectInformation,
6916 if( !NT_SUCCESS( ntStatus))
6918 try_return( ntStatus);
6922 // Retrieve a target name for the entry
6925 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6928 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6931 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6933 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6938 if( !NT_SUCCESS( ntStatus) ||
6939 pDirEntry->TargetNameLength == 0)
6942 if( pDirEntry != NULL)
6945 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6948 try_return( ntStatus);
6951 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6954 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6958 // Update the target name
6961 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6962 &DirectoryCB->Flags,
6963 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6964 (USHORT)pDirEntry->TargetNameLength);
6966 if( !NT_SUCCESS( ntStatus))
6969 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6971 try_return( ntStatus);
6975 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6979 // Need to pass the full path in for parsing.
6982 uniFullPathName.Length = 0;
6983 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6985 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6986 uniFullPathName.MaximumLength,
6987 AFS_NAME_BUFFER_EIGHT_TAG);
6989 if( uniFullPathName.Buffer == NULL)
6992 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6994 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6997 pwchBuffer = uniFullPathName.Buffer;
6999 RtlZeroMemory( uniFullPathName.Buffer,
7000 uniFullPathName.MaximumLength);
7002 RtlCopyMemory( uniFullPathName.Buffer,
7003 DirectoryCB->NameInformation.TargetName.Buffer,
7004 DirectoryCB->NameInformation.TargetName.Length);
7006 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
7009 // This name should begin with the \afs server so parse it off and chech it
7012 FsRtlDissectName( uniFullPathName,
7016 if( RtlCompareUnicodeString( &uniComponentName,
7022 // Try evaluating the full path
7025 uniFullPathName.Buffer = pwchBuffer;
7027 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
7029 uniFullPathName.MaximumLength = uniFullPathName.Length;
7034 uniFullPathName = uniRemainingPath;
7037 uniParsedName = uniFullPathName;
7039 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
7041 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7047 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7050 if( pNameArray == NULL)
7053 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7056 pVolumeCB = AFSGlobalRoot;
7058 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7060 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7062 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7063 AFS_TRACE_LEVEL_VERBOSE,
7064 "AFSEvaluateRootEntry Increment count on volume %p Cnt %d\n",
7068 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
7070 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7071 AFS_TRACE_LEVEL_VERBOSE,
7072 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7073 &pParentDirEntry->NameInformation.FileName,
7078 ntStatus = AFSLocateNameEntry( NULL,
7089 if( !NT_SUCCESS( ntStatus) ||
7090 ntStatus == STATUS_REPARSE)
7094 // The volume lock was released on failure or reparse above
7095 // Except for STATUS_OBJECT_NAME_NOT_FOUND
7098 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
7101 if( pVolumeCB != NULL)
7104 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7106 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7107 AFS_TRACE_LEVEL_VERBOSE,
7108 "AFSEvaluateRootEntry Decrement count on volume %p Cnt %d\n",
7113 if( pDirectoryEntry != NULL)
7116 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
7118 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7119 AFS_TRACE_LEVEL_VERBOSE,
7120 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7121 &pDirectoryEntry->NameInformation.FileName,
7126 ASSERT( lCount >= 0);
7131 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
7133 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7134 AFS_TRACE_LEVEL_VERBOSE,
7135 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7136 &pParentDirEntry->NameInformation.FileName,
7141 ASSERT( lCount >= 0);
7147 try_return( ntStatus);
7151 // Pass back the target dir entry for this request
7152 // The caller must release the DirOpenReferenceCount
7155 *TargetDirEntry = pDirectoryEntry;
7159 if( pDirEntry != NULL)
7162 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
7165 if( pVolumeCB != NULL)
7168 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7170 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7171 AFS_TRACE_LEVEL_VERBOSE,
7172 "AFSEvaluateRootEntry Decrement2 count on volume %p Cnt %d\n",
7177 if( pNameArray != NULL)
7180 AFSFreeNameArray( pNameArray);
7183 if( pwchBuffer != NULL)
7187 // Always free the buffer that we allocated as AFSLocateNameEntry
7188 // will not free it. If uniFullPathName.Buffer was allocated by
7189 // AFSLocateNameEntry, then we must free that as well.
7190 // Check that the uniFullPathName.Buffer in the string is not the same
7191 // offset by the length of the server name
7194 if( uniFullPathName.Length > 0 &&
7195 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
7198 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
7201 AFSExFreePoolWithTag( pwchBuffer, 0);
7209 AFSCleanupFcb( IN AFSFcb *Fcb,
7210 IN BOOLEAN ForceFlush)
7213 NTSTATUS ntStatus = STATUS_SUCCESS;
7214 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
7215 LARGE_INTEGER liTime;
7216 IO_STATUS_BLOCK stIoStatus;
7221 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7223 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7225 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
7228 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
7229 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7232 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7233 AFS_TRACE_LEVEL_VERBOSE,
7234 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
7235 &Fcb->NPFcb->Resource,
7236 PsGetCurrentThread());
7238 AFSAcquireShared( &Fcb->NPFcb->Resource,
7241 if( Fcb->OpenReferenceCount > 0)
7244 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7245 AFS_TRACE_LEVEL_VERBOSE,
7246 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7247 &Fcb->NPFcb->SectionObjectResource,
7248 PsGetCurrentThread());
7250 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
7256 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7261 if( !NT_SUCCESS( stIoStatus.Status))
7264 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7265 AFS_TRACE_LEVEL_ERROR,
7266 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7267 Fcb->ObjectInformation->FileId.Cell,
7268 Fcb->ObjectInformation->FileId.Volume,
7269 Fcb->ObjectInformation->FileId.Vnode,
7270 Fcb->ObjectInformation->FileId.Unique,
7272 stIoStatus.Information);
7274 ntStatus = stIoStatus.Status;
7277 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7280 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7286 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7287 AFS_TRACE_LEVEL_WARNING,
7288 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
7289 Fcb->ObjectInformation->FileId.Cell,
7290 Fcb->ObjectInformation->FileId.Volume,
7291 Fcb->ObjectInformation->FileId.Vnode,
7292 Fcb->ObjectInformation->FileId.Unique);
7294 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7298 __except( EXCEPTION_EXECUTE_HANDLER)
7301 ntStatus = GetExceptionCode();
7305 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7306 Fcb->ObjectInformation->FileId.Cell,
7307 Fcb->ObjectInformation->FileId.Volume,
7308 Fcb->ObjectInformation->FileId.Vnode,
7309 Fcb->ObjectInformation->FileId.Unique,
7312 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7315 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7316 AFS_TRACE_LEVEL_VERBOSE,
7317 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7318 &Fcb->NPFcb->SectionObjectResource,
7319 PsGetCurrentThread());
7321 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7324 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7325 AFS_TRACE_LEVEL_VERBOSE,
7326 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
7327 &Fcb->NPFcb->Resource,
7328 PsGetCurrentThread());
7330 AFSReleaseResource( &Fcb->NPFcb->Resource);
7333 // Wait for any currently running flush or release requests to complete
7336 AFSWaitOnQueuedFlushes( Fcb);
7339 // Now perform another flush on the file
7342 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7346 AFSReleaseExtentsWithFlush( Fcb,
7352 if( Fcb->OpenReferenceCount == 0 ||
7353 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7354 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7357 AFSTearDownFcbExtents( Fcb,
7361 try_return( ntStatus);
7364 KeQueryTickCount( &liTime);
7367 // First up are there dirty extents in the cache to flush?
7370 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7371 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7375 // The file has been marked as invalid. Dump it
7378 AFSTearDownFcbExtents( Fcb,
7381 else if( ForceFlush ||
7382 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7383 Fcb->Specific.File.ExtentCount) &&
7384 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7385 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7387 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7389 Fcb->OpenReferenceCount == 0)
7392 AFSReleaseExtentsWithFlush( Fcb,
7399 // If there are extents and they haven't been used recently *and*
7400 // are not being used
7404 ( 0 != Fcb->Specific.File.ExtentCount &&
7405 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7406 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7407 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7410 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7411 AFS_TRACE_LEVEL_VERBOSE,
7412 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7413 &Fcb->NPFcb->SectionObjectResource,
7414 PsGetCurrentThread());
7416 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7422 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7427 if( !NT_SUCCESS( stIoStatus.Status))
7430 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7431 AFS_TRACE_LEVEL_ERROR,
7432 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7433 Fcb->ObjectInformation->FileId.Cell,
7434 Fcb->ObjectInformation->FileId.Volume,
7435 Fcb->ObjectInformation->FileId.Vnode,
7436 Fcb->ObjectInformation->FileId.Unique,
7438 stIoStatus.Information);
7440 ntStatus = stIoStatus.Status;
7444 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7447 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7453 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7454 AFS_TRACE_LEVEL_WARNING,
7455 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7456 Fcb->ObjectInformation->FileId.Cell,
7457 Fcb->ObjectInformation->FileId.Volume,
7458 Fcb->ObjectInformation->FileId.Vnode,
7459 Fcb->ObjectInformation->FileId.Unique);
7461 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7465 __except( EXCEPTION_EXECUTE_HANDLER)
7468 ntStatus = GetExceptionCode();
7472 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7473 Fcb->ObjectInformation->FileId.Cell,
7474 Fcb->ObjectInformation->FileId.Volume,
7475 Fcb->ObjectInformation->FileId.Vnode,
7476 Fcb->ObjectInformation->FileId.Unique,
7480 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7481 AFS_TRACE_LEVEL_VERBOSE,
7482 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7483 &Fcb->NPFcb->SectionObjectResource,
7484 PsGetCurrentThread());
7486 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7488 if( Fcb->OpenReferenceCount <= 0)
7492 // Tear em down we'll not be needing them again
7495 AFSTearDownFcbExtents( Fcb,
7502 ntStatus = STATUS_RETRY;
7515 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7516 IN UNICODE_STRING *NewFileName)
7519 NTSTATUS ntStatus = STATUS_SUCCESS;
7520 WCHAR *pTmpBuffer = NULL;
7525 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7528 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7531 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7533 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7535 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7539 // OK, we need to allocate a new name buffer
7542 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7543 NewFileName->Length,
7544 AFS_NAME_BUFFER_NINE_TAG);
7546 if( pTmpBuffer == NULL)
7549 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7552 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7554 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7556 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7559 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7561 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7562 NewFileName->Buffer,
7563 NewFileName->Length);
7574 AFSReadCacheFile( IN void *ReadBuffer,
7575 IN LARGE_INTEGER *ReadOffset,
7576 IN ULONG RequestedDataLength,
7577 IN OUT PULONG BytesRead)
7580 NTSTATUS ntStatus = STATUS_SUCCESS;
7583 PIO_STACK_LOCATION pIoStackLocation = NULL;
7584 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7585 FILE_OBJECT *pCacheFileObject = NULL;
7590 pCacheFileObject = AFSReferenceCacheFileObject();
7592 if( pCacheFileObject == NULL)
7594 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7597 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7600 // Initialize the event
7603 KeInitializeEvent( &kEvent,
7604 SynchronizationEvent,
7608 // Allocate an irp for this request. This could also come from a
7609 // private pool, for instance.
7612 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7618 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7622 // Build the IRP's main body
7625 pIrp->UserBuffer = ReadBuffer;
7627 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7628 pIrp->RequestorMode = KernelMode;
7629 pIrp->Flags |= IRP_READ_OPERATION;
7632 // Set up the I/O stack location.
7635 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7636 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7637 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7638 pIoStackLocation->FileObject = pCacheFileObject;
7639 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7641 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7644 // Set the completion routine.
7647 IoSetCompletionRoutine( pIrp,
7655 // Send it to the FSD
7658 ntStatus = IoCallDriver( pTargetDeviceObject,
7661 if( NT_SUCCESS( ntStatus))
7668 ntStatus = KeWaitForSingleObject( &kEvent,
7674 if( NT_SUCCESS( ntStatus))
7677 ntStatus = pIrp->IoStatus.Status;
7679 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7685 if( pCacheFileObject != NULL)
7687 AFSReleaseCacheFileObject( pCacheFileObject);
7693 if( pIrp->MdlAddress != NULL)
7696 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7699 MmUnlockPages( pIrp->MdlAddress);
7702 IoFreeMdl( pIrp->MdlAddress);
7705 pIrp->MdlAddress = NULL;
7719 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7724 UNREFERENCED_PARAMETER(Irp);
7725 UNREFERENCED_PARAMETER(DeviceObject);
7726 KEVENT *pEvent = (KEVENT *)Context;
7732 return STATUS_MORE_PROCESSING_REQUIRED;
7736 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7739 BOOLEAN bIsEmpty = FALSE;
7740 AFSDirectoryCB *pDirEntry = NULL;
7745 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7750 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7753 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7755 while( pDirEntry != NULL)
7758 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7759 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7767 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7772 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7779 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7780 IN AFSDirectoryCB *DirEntry)
7783 NTSTATUS ntStatus = STATUS_SUCCESS;
7788 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7791 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7792 AFS_TRACE_LEVEL_VERBOSE,
7793 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7795 &DirEntry->NameInformation.FileName);
7797 try_return( ntStatus);
7800 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7803 // Remove the entry from the parent tree
7806 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7807 AFS_TRACE_LEVEL_VERBOSE,
7808 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7810 &DirEntry->NameInformation.FileName);
7812 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7815 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7816 AFS_TRACE_LEVEL_VERBOSE,
7817 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7819 &DirEntry->NameInformation.FileName);
7821 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7824 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7828 // From the short name tree
7831 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7832 AFS_TRACE_LEVEL_VERBOSE,
7833 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7835 &DirEntry->NameInformation.FileName);
7837 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7840 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7843 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7844 AFS_TRACE_LEVEL_VERBOSE,
7845 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7847 &DirEntry->NameInformation.FileName);
7849 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7851 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7862 AFSGetAuthenticationId()
7865 LARGE_INTEGER liAuthId = {0,0};
7866 NTSTATUS ntStatus = STATUS_SUCCESS;
7867 PACCESS_TOKEN hToken = NULL;
7868 PTOKEN_STATISTICS pTokenInfo = NULL;
7869 BOOLEAN bCopyOnOpen = FALSE;
7870 BOOLEAN bEffectiveOnly = FALSE;
7871 BOOLEAN bPrimaryToken = FALSE;
7872 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7877 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7880 &stImpersonationLevel);
7885 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7890 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7891 AFS_TRACE_LEVEL_ERROR,
7892 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7894 try_return( ntStatus);
7897 bPrimaryToken = TRUE;
7900 ntStatus = SeQueryInformationToken( hToken,
7902 (PVOID *)&pTokenInfo);
7904 if( !NT_SUCCESS( ntStatus))
7907 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7908 AFS_TRACE_LEVEL_ERROR,
7909 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7911 try_return( ntStatus);
7914 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7915 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7917 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7918 AFS_TRACE_LEVEL_VERBOSE,
7919 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7930 PsDereferenceImpersonationToken( hToken);
7935 PsDereferencePrimaryToken( hToken);
7939 if( pTokenInfo != NULL)
7942 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7950 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7954 UNREFERENCED_PARAMETER(Fcb);
7955 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7957 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7960 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7962 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7965 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7967 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7970 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7972 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7975 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7977 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7984 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7987 BOOLEAN bIsValid = TRUE;
7989 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7991 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7993 while( pCurrentDirEntry != NULL)
7996 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
8000 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
8005 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8006 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
8009 if( pDirEntry == NULL)
8016 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
8019 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
8022 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
8024 ObjectInfo->Specific.Directory.DirectoryNodeCount);
8026 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
8035 AFSReferenceCacheFileObject()
8038 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8039 FILE_OBJECT *pCacheFileObject = NULL;
8041 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
8044 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
8046 if( pCacheFileObject != NULL)
8048 ObReferenceObject( pCacheFileObject);
8051 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
8053 return pCacheFileObject;
8057 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
8060 ASSERT( CacheFileObject != NULL);
8062 ObDereferenceObject( CacheFileObject);
8068 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
8071 NTSTATUS ntStatus = STATUS_SUCCESS;
8072 AFSDeviceExt *pControlDevExt = NULL;
8073 ULONG ulTimeIncrement = 0;
8079 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
8081 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
8083 AFSServerName = LibraryInit->AFSServerName;
8085 AFSMountRootName = LibraryInit->AFSMountRootName;
8087 AFSDebugFlags = LibraryInit->AFSDebugFlags;
8090 // Callbacks in the framework
8093 AFSProcessRequest = LibraryInit->AFSProcessRequest;
8095 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
8097 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
8099 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
8101 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
8103 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
8105 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
8107 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
8109 if( LibraryInit->AFSCacheBaseAddress != NULL)
8112 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
8114 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
8116 AFSLibCacheLength = LibraryInit->AFSCacheLength;
8120 // Initialize some flush parameters
8123 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
8125 ulTimeIncrement = KeQueryTimeIncrement();
8127 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
8128 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
8129 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
8130 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
8131 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
8134 // Initialize the global root entry
8137 ntStatus = AFSInitVolume( NULL,
8138 &LibraryInit->GlobalRootFid,
8141 if( !NT_SUCCESS( ntStatus))
8144 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8145 AFS_TRACE_LEVEL_ERROR,
8146 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
8149 try_return( ntStatus);
8152 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
8155 if( !NT_SUCCESS( ntStatus))
8158 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8159 AFS_TRACE_LEVEL_ERROR,
8160 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
8163 lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
8165 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8166 AFS_TRACE_LEVEL_VERBOSE,
8167 "AFSInitializeLibrary Increment count on volume %p Cnt %d\n",
8171 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8173 try_return( ntStatus);
8177 // Update the node type code to AFS_ROOT_ALL
8180 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
8182 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
8185 // Invalidate all known volumes since contact with the service and therefore
8186 // the file server was lost.
8189 AFSInvalidateAllVolumes();
8192 // Drop the locks acquired above
8195 AFSInitVolumeWorker( AFSGlobalRoot);
8197 lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
8199 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8200 AFS_TRACE_LEVEL_VERBOSE,
8201 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8205 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8207 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
8221 NTSTATUS ntStatus = STATUS_SUCCESS;
8222 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
8228 if( AFSGlobalDotDirEntry != NULL)
8231 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
8232 AFS_OBJECT_REFERENCE_GLOBAL);
8234 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
8236 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
8238 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
8240 ExFreePool( AFSGlobalDotDirEntry);
8242 AFSGlobalDotDirEntry = NULL;
8245 if( AFSGlobalDotDotDirEntry != NULL)
8248 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
8249 AFS_OBJECT_REFERENCE_GLOBAL);
8251 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
8253 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
8255 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
8257 ExFreePool( AFSGlobalDotDotDirEntry);
8259 AFSGlobalDotDotDirEntry = NULL;
8262 if( AFSSpecialShareNames != NULL)
8265 pDirNode = AFSSpecialShareNames;
8267 while( pDirNode != NULL)
8270 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
8272 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
8273 AFS_OBJECT_REFERENCE_GLOBAL);
8275 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
8277 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
8279 ExFreePool( pDirNode->NonPaged);
8281 ExFreePool( pDirNode);
8283 pDirNode = pLastDirNode;
8286 AFSSpecialShareNames = NULL;
8294 AFSDefaultLogMsg( IN ULONG Subsystem,
8300 UNREFERENCED_PARAMETER(Subsystem);
8301 UNREFERENCED_PARAMETER(Level);
8302 NTSTATUS ntStatus = STATUS_SUCCESS;
8304 char chDebugBuffer[ 256];
8309 va_start( va_args, Format);
8311 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8316 if( NT_SUCCESS( ntStatus))
8318 DbgPrint( chDebugBuffer);
8328 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8329 IN ULONG InputBufferLength,
8330 IN AFSStatusInfoCB *StatusInfo,
8331 OUT ULONG *ReturnLength)
8334 NTSTATUS ntStatus = STATUS_SUCCESS;
8335 AFSVolumeCB *pVolumeCB = NULL;
8336 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8337 AFSObjectInfoCB *pObjectInfo = NULL;
8338 ULONGLONG ullIndex = 0;
8339 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8340 AFSNameArrayHdr *pNameArray = NULL;
8341 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8348 // If we are given a FID then look up the entry by that, otherwise
8352 if( GetStatusInfo->FileID.Cell != 0 &&
8353 GetStatusInfo->FileID.Volume != 0 &&
8354 GetStatusInfo->FileID.Vnode != 0 &&
8355 GetStatusInfo->FileID.Unique != 0)
8358 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8361 // Locate the volume node
8364 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8366 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8368 (AFSBTreeEntry **)&pVolumeCB);
8370 if( pVolumeCB != NULL)
8373 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8375 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8376 AFS_TRACE_LEVEL_VERBOSE,
8377 "AFSGetObjectStatus Increment count on volume %p Cnt %d\n",
8382 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8384 if( !NT_SUCCESS( ntStatus) ||
8387 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8390 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8393 pObjectInfo = &pVolumeCB->ObjectInformation;
8395 lCount = AFSObjectInfoIncrement( pObjectInfo,
8396 AFS_OBJECT_REFERENCE_STATUS);
8398 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8399 AFS_TRACE_LEVEL_VERBOSE,
8400 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8404 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8406 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8407 AFS_TRACE_LEVEL_VERBOSE,
8408 "AFSGetObjectStatus Decrement count on volume %p Cnt %d\n",
8415 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8418 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8420 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8421 AFS_TRACE_LEVEL_VERBOSE,
8422 "AFSGetObjectStatus Decrement2 count on volume %p Cnt %d\n",
8426 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8428 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8430 (AFSBTreeEntry **)&pObjectInfo);
8432 if( pObjectInfo != NULL)
8436 // Reference the node so it won't be torn down
8439 lCount = AFSObjectInfoIncrement( pObjectInfo,
8440 AFS_OBJECT_REFERENCE_STATUS);
8442 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8443 AFS_TRACE_LEVEL_VERBOSE,
8444 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8449 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8451 if( !NT_SUCCESS( ntStatus) ||
8452 pObjectInfo == NULL)
8454 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8461 if( GetStatusInfo->FileNameLength == 0 ||
8462 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8464 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8467 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8468 uniFullPathName.MaximumLength = uniFullPathName.Length;
8470 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8473 // This name should begin with the \afs server so parse it off and check it
8476 FsRtlDissectName( uniFullPathName,
8480 if( RtlCompareUnicodeString( &uniComponentName,
8484 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8485 AFS_TRACE_LEVEL_ERROR,
8486 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8489 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8492 uniFullPathName = uniRemainingPath;
8494 uniParsedName = uniFullPathName;
8500 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8503 if( pNameArray == NULL)
8505 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8508 pVolumeCB = AFSGlobalRoot;
8510 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8513 // Increment the ref count on the volume and dir entry for correct processing below
8516 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8518 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8519 AFS_TRACE_LEVEL_VERBOSE,
8520 "AFSGetObjectStatus Increment2 count on volume %p Cnt %d\n",
8524 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8526 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8527 AFS_TRACE_LEVEL_VERBOSE,
8528 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8529 &pParentDirEntry->NameInformation.FileName,
8534 ntStatus = AFSLocateNameEntry( NULL,
8539 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8540 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8546 if( !NT_SUCCESS( ntStatus) ||
8547 ntStatus == STATUS_REPARSE)
8551 // The volume lock was released on failure or reparse above
8552 // Except for STATUS_OBJECT_NAME_NOT_FOUND
8555 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
8558 if( pVolumeCB != NULL)
8561 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8563 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8564 AFS_TRACE_LEVEL_VERBOSE,
8565 "AFSGetObjectStatus Decrement3 count on volume %p Cnt %d\n",
8570 if( pDirectoryEntry != NULL)
8573 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8575 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8576 AFS_TRACE_LEVEL_VERBOSE,
8577 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8578 &pDirectoryEntry->NameInformation.FileName,
8583 ASSERT( lCount >= 0);
8588 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8590 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8591 AFS_TRACE_LEVEL_VERBOSE,
8592 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8593 &pParentDirEntry->NameInformation.FileName,
8598 ASSERT( lCount >= 0);
8604 try_return( ntStatus);
8608 // Remove the reference obtained from AFSLocateNameEntry
8611 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8613 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8614 AFS_TRACE_LEVEL_VERBOSE,
8615 "AFSGetObjectStatus Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
8616 &pDirectoryEntry->NameInformation.FileName,
8621 ASSERT( lCount >= 0);
8623 pObjectInfo = pDirectoryEntry->ObjectInformation;
8625 lCount = AFSObjectInfoIncrement( pObjectInfo,
8626 AFS_OBJECT_REFERENCE_STATUS);
8628 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8629 AFS_TRACE_LEVEL_VERBOSE,
8630 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8634 if( pVolumeCB != NULL)
8637 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8639 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8640 AFS_TRACE_LEVEL_VERBOSE,
8641 "AFSGetObjectStatus Decrement4 count on volume %p Cnt %d\n",
8648 // At this point we have an object info block, return the information
8651 StatusInfo->FileId = pObjectInfo->FileId;
8653 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8655 StatusInfo->Expiration = pObjectInfo->Expiration;
8657 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8659 StatusInfo->FileType = pObjectInfo->FileType;
8661 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8663 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8665 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8667 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8669 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8671 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8673 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8675 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8677 StatusInfo->EaSize = pObjectInfo->EaSize;
8679 StatusInfo->Links = pObjectInfo->Links;
8682 // Return the information length
8685 *ReturnLength = sizeof( AFSStatusInfoCB);
8689 if( pObjectInfo != NULL)
8692 lCount = AFSObjectInfoDecrement( pObjectInfo,
8693 AFS_OBJECT_REFERENCE_STATUS);
8695 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8696 AFS_TRACE_LEVEL_VERBOSE,
8697 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8702 if( pNameArray != NULL)
8705 AFSFreeNameArray( pNameArray);
8713 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8714 IN UNICODE_STRING *ComponentName)
8717 NTSTATUS ntStatus = STATUS_SUCCESS;
8718 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8719 AFSDirectoryCB *pDirEntry = NULL;
8727 // Search for the entry in the parent
8730 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8731 AFS_TRACE_LEVEL_VERBOSE_2,
8732 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8735 ulCRC = AFSGenerateCRC( ComponentName,
8738 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8741 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8745 if( pDirEntry == NULL)
8749 // Missed so perform a case insensitive lookup
8752 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8753 AFS_TRACE_LEVEL_VERBOSE_2,
8754 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8757 ulCRC = AFSGenerateCRC( ComponentName,
8760 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8764 if( pDirEntry == NULL)
8768 // OK, if this component is a valid short name then try
8769 // a lookup in the short name tree
8772 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8773 RtlIsNameLegalDOS8Dot3( ComponentName,
8778 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8779 AFS_TRACE_LEVEL_VERBOSE_2,
8780 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8783 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8790 if( pDirEntry != NULL)
8792 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8794 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8795 AFS_TRACE_LEVEL_VERBOSE,
8796 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8797 &pDirEntry->NameInformation.FileName,
8802 ASSERT( lCount >= 0);
8805 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8807 if( pDirEntry == NULL)
8810 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8811 AFS_TRACE_LEVEL_VERBOSE_2,
8812 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8814 STATUS_OBJECT_NAME_NOT_FOUND);
8816 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8820 // We have the symlink object but previously failed to process it so return access
8824 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8825 AFS_TRACE_LEVEL_VERBOSE_2,
8826 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8829 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8831 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8833 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8834 AFS_TRACE_LEVEL_VERBOSE,
8835 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8836 &pDirEntry->NameInformation.FileName,
8841 ASSERT( lCount >= 0);
8852 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8853 OUT UNICODE_STRING *ComponentName)
8856 NTSTATUS ntStatus = STATUS_SUCCESS;
8857 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8859 uniFullPathName = *FullPathName;
8864 FsRtlDissectName( uniFullPathName,
8868 if( uniRemainingPath.Length == 0)
8873 uniFullPathName = uniRemainingPath;
8876 if( uniComponentName.Length > 0)
8878 *ComponentName = uniComponentName;
8885 AFSDumpTraceFiles_Default()
8891 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8894 BOOLEAN bIsValidName = TRUE;
8900 while( usIndex < FileName->Length/sizeof( WCHAR))
8903 if( FileName->Buffer[ usIndex] == L':' ||
8904 FileName->Buffer[ usIndex] == L'*' ||
8905 FileName->Buffer[ usIndex] == L'?' ||
8906 FileName->Buffer[ usIndex] == L'"' ||
8907 FileName->Buffer[ usIndex] == L'<' ||
8908 FileName->Buffer[ usIndex] == L'>')
8910 bIsValidName = FALSE;
8918 return bIsValidName;
8922 AFSCreateDefaultSecurityDescriptor()
8925 NTSTATUS ntStatus = STATUS_SUCCESS;
8927 ULONG ulSACLSize = 0;
8928 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8929 ULONG ulACESize = 0;
8930 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8931 ULONG ulSDLength = 0;
8932 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8933 PSID pWorldSID = NULL;
8934 ULONG *pulSubAuthority = NULL;
8935 ULONG ulWorldSIDLEngth = 0;
8940 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8942 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8944 AFS_GENERIC_MEMORY_29_TAG);
8946 if( pWorldSID == NULL)
8948 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8949 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8952 RtlZeroMemory( pWorldSID,
8955 RtlInitializeSid( pWorldSID,
8956 &SeWorldSidAuthority,
8959 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8960 *pulSubAuthority = SECURITY_WORLD_RID;
8962 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8965 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8970 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8972 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8974 AFS_GENERIC_MEMORY_29_TAG);
8979 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8981 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8984 RtlZeroMemory( pACE,
8987 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8988 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8989 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8990 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8992 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8994 SeExports->SeLowMandatorySid);
8996 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8997 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8999 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
9001 AFS_GENERIC_MEMORY_29_TAG);
9006 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
9008 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9011 ntStatus = RtlCreateAcl( pSACL,
9015 if( !NT_SUCCESS( ntStatus))
9018 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
9021 try_return( ntStatus);
9024 ntStatus = RtlAddAce( pSACL,
9028 pACE->Header.AceSize);
9030 if( !NT_SUCCESS( ntStatus))
9033 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
9036 try_return( ntStatus);
9040 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
9041 sizeof( SECURITY_DESCRIPTOR),
9042 AFS_GENERIC_MEMORY_27_TAG);
9044 if( pSecurityDescr == NULL)
9047 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9049 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9052 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
9053 SECURITY_DESCRIPTOR_REVISION);
9055 if( !NT_SUCCESS( ntStatus))
9058 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
9061 try_return( ntStatus);
9064 if( AFSRtlSetSaclSecurityDescriptor != NULL)
9066 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
9071 if( !NT_SUCCESS( ntStatus))
9074 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
9077 try_return( ntStatus);
9082 // Add in the group and owner to the SD
9085 if( AFSRtlSetGroupSecurityDescriptor != NULL)
9087 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
9091 if( !NT_SUCCESS( ntStatus))
9094 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
9097 try_return( ntStatus);
9101 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
9105 if( !NT_SUCCESS( ntStatus))
9108 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
9111 try_return( ntStatus);
9114 if( !RtlValidSecurityDescriptor( pSecurityDescr))
9117 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
9119 try_return( ntStatus = STATUS_INVALID_PARAMETER);
9122 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
9124 AFS_GENERIC_MEMORY_27_TAG);
9126 if( pRelativeSecurityDescr == NULL)
9129 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9131 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9134 ulSDLength = PAGE_SIZE;
9136 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
9137 pRelativeSecurityDescr,
9140 if( !NT_SUCCESS( ntStatus))
9143 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
9146 try_return( ntStatus);
9149 AFSDefaultSD = pRelativeSecurityDescr;
9153 if( !NT_SUCCESS( ntStatus))
9156 if( pRelativeSecurityDescr != NULL)
9158 ExFreePool( pRelativeSecurityDescr);
9162 if( pSecurityDescr != NULL)
9164 ExFreePool( pSecurityDescr);
9177 if( pWorldSID != NULL)
9179 ExFreePool( pWorldSID);
9187 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
9188 OUT UNICODE_STRING *ParentPath)
9191 *ParentPath = *FullFileName;
9194 // If the final character is a \, jump over it
9197 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
9199 ParentPath->Length -= sizeof( WCHAR);
9202 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
9204 ParentPath->Length -= sizeof( WCHAR);
9208 // And the separator
9211 ParentPath->Length -= sizeof( WCHAR);
9217 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
9218 IN AFSObjectInfoCB *ObjectInfo,
9219 IN BOOLEAN WriteAccess,
9220 OUT GUID *AuthGroup)
9223 NTSTATUS ntStatus = STATUS_SUCCESS;
9224 GUID stAuthGroup, stZeroAuthGroup;
9225 BOOLEAN bFoundAuthGroup = FALSE;
9226 AFSCcb *pCcb = NULL;
9232 RtlZeroMemory( &stAuthGroup,
9235 RtlZeroMemory( &stZeroAuthGroup,
9241 if( ObjectInfo != NULL &&
9242 ObjectInfo->Fcb != NULL)
9244 pFcb = ObjectInfo->Fcb;
9251 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
9254 pCcb = Fcb->CcbListHead;
9256 while( pCcb != NULL)
9260 pCcb->GrantedAccess & FILE_WRITE_DATA)
9262 RtlCopyMemory( &stAuthGroup,
9266 bFoundAuthGroup = TRUE;
9270 else if( pCcb->GrantedAccess & FILE_READ_DATA)
9273 // At least get the read-only access
9276 RtlCopyMemory( &stAuthGroup,
9280 bFoundAuthGroup = TRUE;
9283 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9286 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9289 if( !bFoundAuthGroup)
9292 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9293 (ULONGLONG)PsGetCurrentThreadId(),
9296 if( RtlCompareMemory( &stZeroAuthGroup,
9298 sizeof( GUID)) == sizeof( GUID))
9301 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9303 try_return( ntStatus = STATUS_ACCESS_DENIED);
9307 RtlCopyMemory( AuthGroup,
9320 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9321 IN ULONG InvalidateReason)
9324 NTSTATUS ntStatus = STATUS_SUCCESS;
9327 ULONG ulProcessCount = 0;
9334 switch( InvalidateReason)
9337 case AFS_INVALIDATE_DELETED:
9340 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9341 ObjectInfo->Fcb != NULL)
9344 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9347 ObjectInfo->Links = 0;
9349 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9351 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9356 // Clear out the extents
9357 // And get rid of them (note this involves waiting
9358 // for any writes or reads to the cache to complete)
9361 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9364 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9370 case AFS_INVALIDATE_DATA_VERSION:
9373 LARGE_INTEGER liCurrentOffset = {0,0};
9374 LARGE_INTEGER liFlushLength = {0,0};
9375 ULONG ulFlushLength = 0;
9376 BOOLEAN bLocked = FALSE;
9377 BOOLEAN bExtentsLocked = FALSE;
9378 BOOLEAN bCleanExtents = FALSE;
9380 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9381 ObjectInfo->Fcb != NULL)
9384 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9389 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9390 AFS_TRACE_LEVEL_VERBOSE,
9391 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9392 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9393 PsGetCurrentThread());
9395 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9398 bExtentsLocked = TRUE;
9401 // There are several possibilities here:
9403 // 0. If there are no extents or all of the extents are dirty, do nothing.
9405 // 1. There could be nothing dirty and an open reference count of zero
9406 // in which case we can just tear down all of the extents without
9407 // holding any resources.
9409 // 2. There could be nothing dirty and a non-zero open reference count
9410 // in which case we can issue a CcPurge against the entire file
9411 // while holding just the Fcb Resource.
9413 // 3. There can be dirty extents in which case we need to identify
9414 // the non-dirty ranges and then perform a CcPurge on just the
9415 // non-dirty ranges while holding just the Fcb Resource.
9418 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9421 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9424 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9426 bExtentsLocked = FALSE;
9428 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9431 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9435 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9441 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9442 AFS_TRACE_LEVEL_VERBOSE,
9443 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9444 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9445 PsGetCurrentThread());
9447 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9450 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9457 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9458 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9464 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9465 AFS_TRACE_LEVEL_WARNING,
9466 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9467 ObjectInfo->FileId.Cell,
9468 ObjectInfo->FileId.Volume,
9469 ObjectInfo->FileId.Vnode,
9470 ObjectInfo->FileId.Unique);
9472 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9477 bCleanExtents = TRUE;
9480 __except( EXCEPTION_EXECUTE_HANDLER)
9483 ntStatus = GetExceptionCode();
9487 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9488 ObjectInfo->FileId.Cell,
9489 ObjectInfo->FileId.Volume,
9490 ObjectInfo->FileId.Vnode,
9491 ObjectInfo->FileId.Unique,
9494 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9497 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9498 AFS_TRACE_LEVEL_VERBOSE,
9499 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9500 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9501 PsGetCurrentThread());
9503 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9509 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9511 bExtentsLocked = FALSE;
9513 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9514 AFS_TRACE_LEVEL_VERBOSE,
9515 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9516 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9517 PsGetCurrentThread());
9519 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9522 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9527 // Must build a list of non-dirty ranges from the beginning of the file
9528 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9529 // ranges. In all but the most extreme random data write scenario there will
9530 // be significantly fewer.
9532 // For each range we need offset and size.
9535 AFSByteRange * ByteRangeList = NULL;
9536 ULONG ulByteRangeCount = 0;
9538 BOOLEAN bPurgeOnClose = FALSE;
9543 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9546 if ( ByteRangeList != NULL ||
9547 ulByteRangeCount == 0)
9550 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9557 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9559 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9560 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9561 &ByteRangeList[ulIndex].FileOffset,
9566 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9567 AFS_TRACE_LEVEL_WARNING,
9568 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9569 ObjectInfo->FileId.Cell,
9570 ObjectInfo->FileId.Volume,
9571 ObjectInfo->FileId.Vnode,
9572 ObjectInfo->FileId.Unique);
9574 bPurgeOnClose = TRUE;
9579 bCleanExtents = TRUE;
9582 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9584 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9586 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9593 // We couldn't allocate the memory to build the purge list
9594 // so just walk the extent list while holding the ExtentsList Resource.
9595 // This could deadlock but we do not have much choice.
9598 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9600 bExtentsLocked = TRUE;
9602 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9606 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9610 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9612 while( ulProcessCount < ulCount)
9614 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9616 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9618 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9619 &pEntry->FileOffset,
9624 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9625 AFS_TRACE_LEVEL_WARNING,
9626 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9627 ObjectInfo->FileId.Cell,
9628 ObjectInfo->FileId.Volume,
9629 ObjectInfo->FileId.Vnode,
9630 ObjectInfo->FileId.Unique);
9632 bPurgeOnClose = TRUE;
9637 bCleanExtents = TRUE;
9641 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9644 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9646 while( liFlushLength.QuadPart > 0)
9649 if( liFlushLength.QuadPart > 512 * 1024000)
9651 ulFlushLength = 512 * 1024000;
9655 ulFlushLength = liFlushLength.LowPart;
9658 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9664 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9665 AFS_TRACE_LEVEL_WARNING,
9666 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9667 ObjectInfo->FileId.Cell,
9668 ObjectInfo->FileId.Volume,
9669 ObjectInfo->FileId.Vnode,
9670 ObjectInfo->FileId.Unique);
9672 bPurgeOnClose = TRUE;
9677 bCleanExtents = TRUE;
9680 liFlushLength.QuadPart -= ulFlushLength;
9684 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9692 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9698 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9699 AFS_TRACE_LEVEL_WARNING,
9700 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9701 ObjectInfo->FileId.Cell,
9702 ObjectInfo->FileId.Volume,
9703 ObjectInfo->FileId.Vnode,
9704 ObjectInfo->FileId.Unique);
9706 bPurgeOnClose = TRUE;
9711 bCleanExtents = TRUE;
9718 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9722 __except( EXCEPTION_EXECUTE_HANDLER)
9725 ntStatus = GetExceptionCode();
9729 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9730 ObjectInfo->FileId.Cell,
9731 ObjectInfo->FileId.Volume,
9732 ObjectInfo->FileId.Vnode,
9733 ObjectInfo->FileId.Unique,
9737 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9738 AFS_TRACE_LEVEL_VERBOSE,
9739 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9740 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9741 PsGetCurrentThread());
9743 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9747 if ( bExtentsLocked)
9750 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9756 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9762 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9772 // Destroy the reference passed in by the caller to AFSInvalidateObject
9773 // or AFSQueueInvalidateObject
9776 lCount = AFSObjectInfoDecrement( ObjectInfo,
9777 AFS_OBJECT_REFERENCE_INVALIDATION);
9779 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9780 AFS_TRACE_LEVEL_VERBOSE,
9781 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",