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;
1595 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1596 AFS_TRACE_LEVEL_VERBOSE,
1597 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1598 (*ppObjectInfo)->FileType,
1599 (*ppObjectInfo)->FileId.Cell,
1600 (*ppObjectInfo)->FileId.Volume,
1601 (*ppObjectInfo)->FileId.Vnode,
1602 (*ppObjectInfo)->FileId.Unique,
1605 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1606 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1607 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1610 // We only act on the mount point itself, not the target. If the
1611 // node has been deleted then mark it as such otherwise indicate
1612 // it requires verification
1615 if( Reason == AFS_INVALIDATE_DELETED)
1617 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1622 if( Reason == AFS_INVALIDATE_FLUSHED)
1625 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1627 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1630 (*ppObjectInfo)->Expiration.QuadPart = 0;
1632 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1634 (*ppObjectInfo)->TargetFileId.Unique = 0;
1636 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1637 AFS_TRACE_LEVEL_VERBOSE,
1638 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1639 (*ppObjectInfo)->FileId.Cell,
1640 (*ppObjectInfo)->FileId.Volume,
1641 (*ppObjectInfo)->FileId.Vnode,
1642 (*ppObjectInfo)->FileId.Unique);
1644 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1647 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1649 if( Reason == AFS_INVALIDATE_CREDS)
1651 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1654 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1655 Reason == AFS_INVALIDATE_FLUSHED)
1657 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1661 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1664 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1667 FILE_ACTION_MODIFIED);
1669 try_return( ntStatus);
1673 // Depending on the reason for invalidation then perform work on the node
1679 case AFS_INVALIDATE_DELETED:
1683 // Mark this node as invalid
1686 (*ppObjectInfo)->Links = 0;
1688 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1690 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1691 AFS_TRACE_LEVEL_VERBOSE,
1692 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1693 (*ppObjectInfo)->FileId.Cell,
1694 (*ppObjectInfo)->FileId.Volume,
1695 (*ppObjectInfo)->FileId.Vnode,
1696 (*ppObjectInfo)->FileId.Unique);
1698 if( (*ppObjectInfo)->ParentObjectInformation != NULL)
1701 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1702 AFS_TRACE_LEVEL_VERBOSE,
1703 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1704 (*ppObjectInfo)->ParentObjectInformation->FileId.Cell,
1705 (*ppObjectInfo)->ParentObjectInformation->FileId.Volume,
1706 (*ppObjectInfo)->ParentObjectInformation->FileId.Vnode,
1707 (*ppObjectInfo)->ParentObjectInformation->FileId.Unique);
1709 SetFlag( (*ppObjectInfo)->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1711 (*ppObjectInfo)->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1713 (*ppObjectInfo)->ParentObjectInformation->Expiration.QuadPart = 0;
1716 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1718 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1722 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1725 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1728 FILE_ACTION_REMOVED);
1730 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1733 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1739 case AFS_INVALIDATE_FLUSHED:
1742 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1743 (*ppObjectInfo)->Fcb != NULL)
1746 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1747 AFS_TRACE_LEVEL_VERBOSE,
1748 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1749 (*ppObjectInfo)->FileId.Cell,
1750 (*ppObjectInfo)->FileId.Volume,
1751 (*ppObjectInfo)->FileId.Vnode,
1752 (*ppObjectInfo)->FileId.Unique);
1754 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1760 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1765 if( !NT_SUCCESS( stIoStatus.Status))
1768 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1769 AFS_TRACE_LEVEL_ERROR,
1770 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1771 (*ppObjectInfo)->FileId.Cell,
1772 (*ppObjectInfo)->FileId.Volume,
1773 (*ppObjectInfo)->FileId.Vnode,
1774 (*ppObjectInfo)->FileId.Unique,
1776 stIoStatus.Information);
1778 ntStatus = stIoStatus.Status;
1782 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1785 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1791 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1792 AFS_TRACE_LEVEL_WARNING,
1793 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1794 (*ppObjectInfo)->FileId.Cell,
1795 (*ppObjectInfo)->FileId.Volume,
1796 (*ppObjectInfo)->FileId.Vnode,
1797 (*ppObjectInfo)->FileId.Unique);
1799 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1803 __except( EXCEPTION_EXECUTE_HANDLER)
1806 ntStatus = GetExceptionCode();
1810 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1811 (*ppObjectInfo)->FileId.Cell,
1812 (*ppObjectInfo)->FileId.Volume,
1813 (*ppObjectInfo)->FileId.Vnode,
1814 (*ppObjectInfo)->FileId.Unique,
1817 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1820 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1823 // Clear out the extents
1824 // Get rid of them (note this involves waiting
1825 // for any writes or reads to the cache to complete)
1828 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1832 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1835 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1838 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1839 AFS_TRACE_LEVEL_VERBOSE,
1840 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1841 (*ppObjectInfo)->FileId.Cell,
1842 (*ppObjectInfo)->FileId.Volume,
1843 (*ppObjectInfo)->FileId.Vnode,
1844 (*ppObjectInfo)->FileId.Unique);
1846 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1849 // Fall through to the default processing
1855 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1857 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1861 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1864 if( Reason == AFS_INVALIDATE_CREDS)
1866 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1869 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1871 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1875 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1878 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1881 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1884 FILE_ACTION_MODIFIED);
1889 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1892 FILE_ACTION_MODIFIED);
1896 // Indicate this node requires re-evaluation for the remaining reasons
1899 (*ppObjectInfo)->Expiration.QuadPart = 0;
1901 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1902 AFS_TRACE_LEVEL_VERBOSE,
1903 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1904 (*ppObjectInfo)->FileId.Cell,
1905 (*ppObjectInfo)->FileId.Volume,
1906 (*ppObjectInfo)->FileId.Vnode,
1907 (*ppObjectInfo)->FileId.Unique);
1909 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1911 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1912 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1913 ( Reason == AFS_INVALIDATE_CALLBACK ||
1914 Reason == AFS_INVALIDATE_EXPIRED))
1916 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1917 AFS_INVALIDATE_DATA_VERSION)))
1920 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1934 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1937 NTSTATUS ntStatus = STATUS_SUCCESS;
1938 AFSVolumeCB *pVolumeCB = NULL;
1939 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1940 ULONGLONG ullIndex = 0;
1941 AFSObjectInfoCB *pObjectInfo = NULL;
1947 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1948 AFS_TRACE_LEVEL_VERBOSE,
1949 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1950 InvalidateCB->FileID.Cell,
1951 InvalidateCB->FileID.Volume,
1952 InvalidateCB->FileID.Vnode,
1953 InvalidateCB->FileID.Unique,
1954 InvalidateCB->FileType,
1955 InvalidateCB->WholeVolume,
1956 InvalidateCB->Reason);
1959 // Need to locate the Fcb for the directory to purge
1962 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1963 AFS_TRACE_LEVEL_VERBOSE,
1964 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
1965 &pDevExt->Specific.RDR.VolumeTreeLock,
1966 PsGetCurrentThread());
1969 // Starve any exclusive waiters on this paticular call
1972 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1975 // Locate the volume node
1978 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1980 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1982 (AFSBTreeEntry **)&pVolumeCB);
1984 if( pVolumeCB != NULL)
1987 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1989 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1990 AFS_TRACE_LEVEL_VERBOSE,
1991 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
1996 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1998 if( !NT_SUCCESS( ntStatus) ||
2002 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2003 AFS_TRACE_LEVEL_WARNING,
2004 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2005 InvalidateCB->FileID.Cell,
2006 InvalidateCB->FileID.Volume,
2007 InvalidateCB->FileID.Vnode,
2008 InvalidateCB->FileID.Unique,
2011 try_return( ntStatus = STATUS_SUCCESS);
2015 // If this is a whole volume invalidation then go do it now
2018 if( InvalidateCB->WholeVolume)
2021 ntStatus = AFSInvalidateVolume( pVolumeCB,
2022 InvalidateCB->Reason);
2024 try_return( ntStatus);
2027 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
2030 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2033 pObjectInfo = &pVolumeCB->ObjectInformation;
2038 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2040 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2042 (AFSBTreeEntry **)&pObjectInfo);
2045 if( pObjectInfo != NULL)
2049 // Reference the node so it won't be torn down
2052 lCount = AFSObjectInfoIncrement( pObjectInfo,
2053 AFS_OBJECT_REFERENCE_INVALIDATION);
2055 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2056 AFS_TRACE_LEVEL_VERBOSE,
2057 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2062 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2064 if( !NT_SUCCESS( ntStatus) ||
2065 pObjectInfo == NULL)
2068 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2069 AFS_TRACE_LEVEL_VERBOSE,
2070 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2071 InvalidateCB->FileID.Cell,
2072 InvalidateCB->FileID.Volume,
2073 InvalidateCB->FileID.Vnode,
2074 InvalidateCB->FileID.Unique,
2077 try_return( ntStatus = STATUS_SUCCESS);
2080 AFSInvalidateObject( &pObjectInfo,
2081 InvalidateCB->Reason);
2085 if( pObjectInfo != NULL)
2088 lCount = AFSObjectInfoDecrement( pObjectInfo,
2089 AFS_OBJECT_REFERENCE_INVALIDATION);
2091 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2092 AFS_TRACE_LEVEL_VERBOSE,
2093 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2098 if ( pVolumeCB != NULL)
2101 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2103 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2104 AFS_TRACE_LEVEL_VERBOSE,
2105 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2115 AFSIsChildOfParent( IN AFSFcb *Dcb,
2119 BOOLEAN bIsChild = FALSE;
2120 AFSFcb *pCurrentFcb = Fcb;
2122 while( pCurrentFcb != NULL)
2125 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2133 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2141 AFSCreateHighIndex( IN AFSFileID *FileID)
2144 ULONGLONG ullIndex = 0;
2146 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2153 AFSCreateLowIndex( IN AFSFileID *FileID)
2156 ULONGLONG ullIndex = 0;
2158 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2164 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2165 IN ACCESS_MASK GrantedAccess,
2166 IN BOOLEAN DirectoryEntry)
2169 BOOLEAN bAccessGranted = TRUE;
2172 // Check if we are asking for read/write and granted only read only
2173 // NOTE: There will be more checks here
2176 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2178 AFSCheckForReadOnlyAccess( GrantedAccess,
2182 bAccessGranted = FALSE;
2185 return bAccessGranted;
2189 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2192 NTSTATUS ntStatus = STATUS_SUCCESS;
2193 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2199 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2201 if( AFSGlobalRoot == NULL)
2208 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2211 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2218 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2225 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2226 IN UNICODE_STRING *SubstituteName,
2227 IN ULONG StringIndex)
2230 NTSTATUS ntStatus = STATUS_SUCCESS;
2231 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2232 AFSSysNameCB *pSysName = NULL;
2233 ERESOURCE *pSysNameLock = NULL;
2236 UNICODE_STRING uniSysName;
2243 if( IoIs32bitProcess( NULL))
2246 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2248 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2253 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2255 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2259 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2261 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2265 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2266 AFS_TRACE_LEVEL_VERBOSE,
2267 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2269 PsGetCurrentThread());
2271 AFSAcquireShared( pSysNameLock,
2275 // Find where we are in the list
2278 while( pSysName != NULL &&
2279 ulIndex < StringIndex)
2282 pSysName = pSysName->fLink;
2287 if( pSysName == NULL)
2290 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2291 AFS_TRACE_LEVEL_VERBOSE_2,
2292 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2294 STATUS_OBJECT_NAME_NOT_FOUND);
2296 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2299 RtlInitUnicodeString( &uniSysName,
2302 // If it is a full component of @SYS then just substitue the
2306 if( RtlCompareUnicodeString( &uniSysName,
2311 SubstituteName->Length = pSysName->SysName.Length;
2312 SubstituteName->MaximumLength = SubstituteName->Length;
2314 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2315 SubstituteName->Length,
2316 AFS_SUBST_BUFFER_TAG);
2318 if( SubstituteName->Buffer == NULL)
2321 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2324 RtlCopyMemory( SubstituteName->Buffer,
2325 pSysName->SysName.Buffer,
2326 pSysName->SysName.Length);
2333 while( ComponentName->Buffer[ usIndex] != L'@')
2339 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2340 SubstituteName->MaximumLength = SubstituteName->Length;
2342 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2343 SubstituteName->Length,
2344 AFS_SUBST_BUFFER_TAG);
2346 if( SubstituteName->Buffer == NULL)
2349 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2352 RtlCopyMemory( SubstituteName->Buffer,
2353 ComponentName->Buffer,
2354 usIndex * sizeof( WCHAR));
2356 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2357 pSysName->SysName.Buffer,
2358 pSysName->SysName.Length);
2363 AFSReleaseResource( pSysNameLock);
2370 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2371 IN OUT UNICODE_STRING *ComponentName,
2372 IN UNICODE_STRING *SubstituteName,
2373 IN OUT UNICODE_STRING *RemainingPath,
2374 IN BOOLEAN FreePathName)
2377 NTSTATUS ntStatus = STATUS_SUCCESS;
2378 UNICODE_STRING uniPathName;
2379 USHORT usPrefixNameLen = 0;
2380 SHORT sNameLenDelta = 0;
2386 // If the passed in name can handle the additional length
2387 // then just moves things around
2390 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2392 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2394 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2397 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2400 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2401 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2402 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2405 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2406 SubstituteName->Buffer,
2407 SubstituteName->Length);
2409 FullPathName->Length += sNameLenDelta;
2411 ComponentName->Length += sNameLenDelta;
2413 ComponentName->MaximumLength = ComponentName->Length;
2415 if ( RemainingPath->Buffer)
2418 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2421 try_return( ntStatus);
2425 // Need to re-allocate the buffer
2428 uniPathName.Length = FullPathName->Length -
2429 ComponentName->Length +
2430 SubstituteName->Length;
2432 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2434 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2435 uniPathName.MaximumLength,
2436 AFS_NAME_BUFFER_FOUR_TAG);
2438 if( uniPathName.Buffer == NULL)
2441 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2444 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2446 usPrefixNameLen *= sizeof( WCHAR);
2448 RtlZeroMemory( uniPathName.Buffer,
2449 uniPathName.MaximumLength);
2451 RtlCopyMemory( uniPathName.Buffer,
2452 FullPathName->Buffer,
2455 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2456 SubstituteName->Buffer,
2457 SubstituteName->Length);
2459 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2462 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2463 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2464 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2467 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2469 ComponentName->Length += sNameLenDelta;
2471 ComponentName->MaximumLength = ComponentName->Length;
2473 if ( RemainingPath->Buffer)
2476 RemainingPath->Buffer = uniPathName.Buffer
2477 + (RemainingPath->Buffer - FullPathName->Buffer)
2478 + sNameLenDelta/sizeof( WCHAR);
2483 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2486 *FullPathName = uniPathName;
2497 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2501 NTSTATUS ntStatus = STATUS_SUCCESS;
2502 AFSObjectInfoCB *pCurrentObject = NULL;
2503 AFSObjectInfoCB *pNextObject = NULL;
2509 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2510 AFS_TRACE_LEVEL_VERBOSE,
2511 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2512 VolumeCB->ObjectInformation.FileId.Cell,
2513 VolumeCB->ObjectInformation.FileId.Volume,
2514 VolumeCB->ObjectInformation.FileId.Vnode,
2515 VolumeCB->ObjectInformation.FileId.Unique,
2519 // Depending on the reason for invalidation then perform work on the node
2525 case AFS_INVALIDATE_DELETED:
2529 // Mark this volume as invalid
2532 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2534 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2541 // Invalidate the volume root directory
2544 pCurrentObject = &VolumeCB->ObjectInformation;
2546 if ( pCurrentObject )
2549 lCount = AFSObjectInfoIncrement( pCurrentObject,
2550 AFS_OBJECT_REFERENCE_INVALIDATION);
2552 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2553 AFS_TRACE_LEVEL_VERBOSE,
2554 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2558 AFSInvalidateObject( &pCurrentObject,
2561 if ( pCurrentObject)
2564 lCount = AFSObjectInfoDecrement( pCurrentObject,
2565 AFS_OBJECT_REFERENCE_INVALIDATION);
2567 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2568 AFS_TRACE_LEVEL_VERBOSE,
2569 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2576 // Apply invalidation to all other volume objects
2579 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2582 pCurrentObject = VolumeCB->ObjectInfoListHead;
2584 if ( pCurrentObject)
2588 // Reference the node so it won't be torn down
2591 lCount = AFSObjectInfoIncrement( pCurrentObject,
2592 AFS_OBJECT_REFERENCE_INVALIDATION);
2594 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2595 AFS_TRACE_LEVEL_VERBOSE,
2596 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2601 while( pCurrentObject != NULL)
2604 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2610 // Reference the node so it won't be torn down
2613 lCount = AFSObjectInfoIncrement( pNextObject,
2614 AFS_OBJECT_REFERENCE_INVALIDATION);
2616 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2617 AFS_TRACE_LEVEL_VERBOSE,
2618 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2623 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2625 AFSInvalidateObject( &pCurrentObject,
2628 if ( pCurrentObject )
2631 lCount = AFSObjectInfoDecrement( pCurrentObject,
2632 AFS_OBJECT_REFERENCE_INVALIDATION);
2634 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2635 AFS_TRACE_LEVEL_VERBOSE,
2636 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2641 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2644 pCurrentObject = pNextObject;
2647 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2654 AFSInvalidateAllVolumes( VOID)
2656 AFSVolumeCB *pVolumeCB = NULL;
2657 AFSVolumeCB *pNextVolumeCB = NULL;
2658 AFSDeviceExt *pRDRDeviceExt = NULL;
2661 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2663 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2664 AFS_TRACE_LEVEL_VERBOSE,
2665 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2666 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2667 PsGetCurrentThread());
2669 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2672 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2677 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2678 AFS_TRACE_LEVEL_VERBOSE,
2679 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2680 pVolumeCB->ObjectInfoTree.TreeLock,
2681 PsGetCurrentThread());
2683 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
2685 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2686 AFS_TRACE_LEVEL_VERBOSE,
2687 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2692 while( pVolumeCB != NULL)
2695 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2700 lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
2702 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2703 AFS_TRACE_LEVEL_VERBOSE,
2704 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2709 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2711 // do I need to hold the volume lock here?
2713 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2715 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2718 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2720 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2721 AFS_TRACE_LEVEL_VERBOSE,
2722 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2726 pVolumeCB = pNextVolumeCB;
2729 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2733 AFSVerifyEntry( IN GUID *AuthGroup,
2734 IN AFSDirectoryCB *DirEntry)
2737 NTSTATUS ntStatus = STATUS_SUCCESS;
2738 AFSDirEnumEntry *pDirEnumEntry = NULL;
2739 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2740 IO_STATUS_BLOCK stIoStatus;
2745 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2746 AFS_TRACE_LEVEL_VERBOSE_2,
2747 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2748 &DirEntry->NameInformation.FileName,
2749 pObjectInfo->FileId.Cell,
2750 pObjectInfo->FileId.Volume,
2751 pObjectInfo->FileId.Vnode,
2752 pObjectInfo->FileId.Unique);
2754 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2759 if( !NT_SUCCESS( ntStatus))
2762 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2763 AFS_TRACE_LEVEL_ERROR,
2764 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2765 &DirEntry->NameInformation.FileName,
2766 pObjectInfo->FileId.Cell,
2767 pObjectInfo->FileId.Volume,
2768 pObjectInfo->FileId.Vnode,
2769 pObjectInfo->FileId.Unique,
2772 try_return( ntStatus);
2776 // Check the data version of the file
2779 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2781 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2784 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2785 AFS_TRACE_LEVEL_VERBOSE,
2786 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2787 pObjectInfo->DataVersion.QuadPart,
2788 &DirEntry->NameInformation.FileName,
2789 pObjectInfo->FileId.Cell,
2790 pObjectInfo->FileId.Volume,
2791 pObjectInfo->FileId.Vnode,
2792 pObjectInfo->FileId.Unique);
2795 // We are ok, just get out
2798 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2800 try_return( ntStatus = STATUS_SUCCESS);
2805 // New data version so we will need to process the node based on the type
2808 switch( pDirEnumEntry->FileType)
2811 case AFS_FILE_TYPE_MOUNTPOINT:
2815 // For a mount point we need to ensure the target is the same
2818 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2819 &pDirEnumEntry->TargetFileId))
2825 // Update the metadata for the entry
2828 ntStatus = AFSUpdateMetaData( DirEntry,
2831 if( NT_SUCCESS( ntStatus))
2834 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2840 case AFS_FILE_TYPE_SYMLINK:
2844 // Update the metadata for the entry
2847 ntStatus = AFSUpdateMetaData( DirEntry,
2850 if( NT_SUCCESS( ntStatus))
2853 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2859 case AFS_FILE_TYPE_FILE:
2861 FILE_OBJECT * pCCFileObject = NULL;
2862 BOOLEAN bPurgeExtents = FALSE;
2864 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
2867 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2868 AFS_TRACE_LEVEL_VERBOSE,
2869 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
2870 &DirEntry->NameInformation.FileName,
2871 pObjectInfo->FileId.Cell,
2872 pObjectInfo->FileId.Volume,
2873 pObjectInfo->FileId.Vnode,
2874 pObjectInfo->FileId.Unique,
2875 pObjectInfo->DataVersion.LowPart,
2876 pDirEnumEntry->DataVersion.LowPart
2879 bPurgeExtents = TRUE;
2882 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2885 bPurgeExtents = TRUE;
2887 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2888 AFS_TRACE_LEVEL_VERBOSE,
2889 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2890 &DirEntry->NameInformation.FileName,
2891 pObjectInfo->FileId.Cell,
2892 pObjectInfo->FileId.Volume,
2893 pObjectInfo->FileId.Vnode,
2894 pObjectInfo->FileId.Unique);
2896 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2899 if( pObjectInfo->Fcb != NULL)
2902 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2903 AFS_TRACE_LEVEL_VERBOSE,
2904 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2905 &DirEntry->NameInformation.FileName,
2906 pObjectInfo->FileId.Cell,
2907 pObjectInfo->FileId.Volume,
2908 pObjectInfo->FileId.Vnode,
2909 pObjectInfo->FileId.Unique);
2911 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2917 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2922 if( !NT_SUCCESS( stIoStatus.Status))
2925 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2926 AFS_TRACE_LEVEL_ERROR,
2927 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2928 &DirEntry->NameInformation.FileName,
2929 pObjectInfo->FileId.Cell,
2930 pObjectInfo->FileId.Volume,
2931 pObjectInfo->FileId.Vnode,
2932 pObjectInfo->FileId.Unique,
2934 stIoStatus.Information);
2936 ntStatus = stIoStatus.Status;
2939 if ( bPurgeExtents &&
2940 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2943 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2949 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2950 AFS_TRACE_LEVEL_WARNING,
2951 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2952 &DirEntry->NameInformation.FileName,
2953 pObjectInfo->FileId.Cell,
2954 pObjectInfo->FileId.Volume,
2955 pObjectInfo->FileId.Vnode,
2956 pObjectInfo->FileId.Unique);
2958 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2962 __except( EXCEPTION_EXECUTE_HANDLER)
2964 ntStatus = GetExceptionCode();
2968 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2969 &DirEntry->NameInformation.FileName,
2970 pObjectInfo->FileId.Cell,
2971 pObjectInfo->FileId.Volume,
2972 pObjectInfo->FileId.Vnode,
2973 pObjectInfo->FileId.Unique,
2976 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2979 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
2983 AFSFlushExtents( pObjectInfo->Fcb,
2988 // Reacquire the Fcb to purge the cache
2991 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2992 AFS_TRACE_LEVEL_VERBOSE,
2993 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
2994 &pObjectInfo->Fcb->NPFcb->Resource,
2995 PsGetCurrentThread());
2997 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3001 // Update the metadata for the entry
3004 ntStatus = AFSUpdateMetaData( DirEntry,
3007 if( !NT_SUCCESS( ntStatus))
3010 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3011 AFS_TRACE_LEVEL_ERROR,
3012 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3013 &DirEntry->NameInformation.FileName,
3014 pObjectInfo->FileId.Cell,
3015 pObjectInfo->FileId.Volume,
3016 pObjectInfo->FileId.Vnode,
3017 pObjectInfo->FileId.Unique,
3024 // Update file sizes
3027 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3028 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3029 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3031 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3032 AFS_TRACE_LEVEL_VERBOSE,
3033 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3034 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3035 PsGetCurrentThread());
3037 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3040 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3042 if ( pCCFileObject != NULL)
3044 CcSetFileSizes( pCCFileObject,
3045 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3048 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3049 AFS_TRACE_LEVEL_VERBOSE,
3050 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3051 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3052 PsGetCurrentThread());
3054 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3056 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3062 // Update the metadata for the entry
3065 ntStatus = AFSUpdateMetaData( DirEntry,
3068 if( !NT_SUCCESS( ntStatus))
3071 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3072 AFS_TRACE_LEVEL_ERROR,
3073 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3074 &DirEntry->NameInformation.FileName,
3075 pObjectInfo->FileId.Cell,
3076 pObjectInfo->FileId.Volume,
3077 pObjectInfo->FileId.Vnode,
3078 pObjectInfo->FileId.Unique,
3084 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3085 AFS_TRACE_LEVEL_WARNING,
3086 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3087 &DirEntry->NameInformation.FileName,
3088 pObjectInfo->FileId.Cell,
3089 pObjectInfo->FileId.Volume,
3090 pObjectInfo->FileId.Vnode,
3091 pObjectInfo->FileId.Unique);
3094 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3099 case AFS_FILE_TYPE_DIRECTORY:
3103 // For a directory or root entry flush the content of
3104 // the directory enumeration.
3107 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3110 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3111 AFS_TRACE_LEVEL_VERBOSE_2,
3112 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3113 &DirEntry->NameInformation.FileName,
3114 pObjectInfo->FileId.Cell,
3115 pObjectInfo->FileId.Volume,
3116 pObjectInfo->FileId.Vnode,
3117 pObjectInfo->FileId.Unique);
3119 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3122 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3125 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3127 if ( !NT_SUCCESS( ntStatus))
3130 try_return( ntStatus);
3135 // Update the metadata for the entry
3138 ntStatus = AFSUpdateMetaData( DirEntry,
3141 if( NT_SUCCESS( ntStatus))
3144 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3150 case AFS_FILE_TYPE_DFSLINK:
3153 UNICODE_STRING uniTargetName;
3156 // For a DFS link need to check the target name has not changed
3159 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3161 uniTargetName.MaximumLength = uniTargetName.Length;
3163 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3165 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3168 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3169 RtlCompareUnicodeString( &uniTargetName,
3170 &DirEntry->NameInformation.TargetName,
3175 // Update the target name
3178 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3180 uniTargetName.Buffer,
3181 uniTargetName.Length);
3183 if( !NT_SUCCESS( ntStatus))
3186 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3192 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3195 // Update the metadata for the entry
3198 ntStatus = AFSUpdateMetaData( DirEntry,
3201 if( NT_SUCCESS( ntStatus))
3204 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3212 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3213 AFS_TRACE_LEVEL_WARNING,
3214 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3215 pObjectInfo->FileType,
3216 &DirEntry->NameInformation.FileName,
3217 pObjectInfo->FileId.Cell,
3218 pObjectInfo->FileId.Volume,
3219 pObjectInfo->FileId.Vnode,
3220 pObjectInfo->FileId.Unique);
3227 if( pDirEnumEntry != NULL)
3230 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3238 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3241 NTSTATUS ntStatus = STATUS_SUCCESS;
3242 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3243 ULONGLONG ullIndex = 0;
3244 AFSVolumeCB *pVolumeCB = NULL;
3250 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3251 AFS_TRACE_LEVEL_VERBOSE,
3252 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3253 VolumeStatus->Online,
3254 VolumeStatus->FileID.Cell,
3255 VolumeStatus->FileID.Volume);
3258 // Need to locate the Fcb for the directory to purge
3261 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3262 AFS_TRACE_LEVEL_VERBOSE,
3263 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3264 &pDevExt->Specific.RDR.VolumeTreeLock,
3265 PsGetCurrentThread());
3267 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3270 // Locate the volume node
3273 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3275 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3277 (AFSBTreeEntry **)&pVolumeCB);
3279 if( pVolumeCB != NULL)
3282 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3284 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3285 AFS_TRACE_LEVEL_VERBOSE,
3286 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3290 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3293 // Set the volume state accordingly
3296 if( VolumeStatus->Online)
3299 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3304 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3313 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3316 NTSTATUS ntStatus = STATUS_SUCCESS;
3321 if( AFSGlobalRoot == NULL)
3324 try_return( ntStatus);
3327 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3331 // Set the network state according to the information
3334 if( NetworkStatus->Online)
3337 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3342 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3345 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3356 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3360 NTSTATUS ntStatus = STATUS_SUCCESS;
3361 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3362 BOOLEAN bAcquiredLock = FALSE;
3363 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3368 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3369 AFS_TRACE_LEVEL_VERBOSE,
3370 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3371 ObjectInfo->FileId.Cell,
3372 ObjectInfo->FileId.Volume,
3373 ObjectInfo->FileId.Vnode,
3374 ObjectInfo->FileId.Unique);
3376 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3379 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3380 AFS_TRACE_LEVEL_VERBOSE,
3381 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3382 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3383 PsGetCurrentThread());
3385 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3388 bAcquiredLock = TRUE;
3392 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3395 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3396 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3399 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3400 AFS_TRACE_LEVEL_ERROR,
3401 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3402 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3403 ObjectInfo->FileId.Cell,
3404 ObjectInfo->FileId.Volume,
3405 ObjectInfo->FileId.Vnode,
3406 ObjectInfo->FileId.Unique);
3410 // Reset the directory list information by clearing all valid entries
3413 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3415 while( pCurrentDirEntry != NULL)
3418 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3420 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3424 // If this entry has been deleted then process it here
3427 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3428 pCurrentDirEntry->DirOpenReferenceCount <= 0)
3431 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3432 AFS_TRACE_LEVEL_VERBOSE,
3433 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3435 &pCurrentDirEntry->NameInformation.FileName);
3437 AFSDeleteDirEntry( ObjectInfo,
3443 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3445 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3446 AFS_TRACE_LEVEL_VERBOSE,
3447 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3449 pCurrentDirEntry->DirOpenReferenceCount);
3452 // We pull the short name from the parent tree since it could change below
3455 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3458 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3459 AFS_TRACE_LEVEL_VERBOSE,
3460 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3462 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3463 &pCurrentDirEntry->NameInformation.FileName);
3465 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3468 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3473 pCurrentDirEntry = pNextDirEntry;
3477 // Reget the directory contents
3480 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3483 if ( !NT_SUCCESS( ntStatus))
3485 try_return( ntStatus);
3489 // Now start again and tear down any entries not valid
3492 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3494 while( pCurrentDirEntry != NULL)
3497 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3499 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3502 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3503 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3504 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3507 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3510 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3512 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3513 AFS_TRACE_LEVEL_VERBOSE,
3514 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3516 &pCurrentDirEntry->NameInformation.FileName);
3518 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3523 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3526 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3527 AFS_TRACE_LEVEL_VERBOSE,
3528 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3530 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3531 &pCurrentDirEntry->NameInformation.FileName);
3535 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3537 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3538 AFS_TRACE_LEVEL_VERBOSE,
3539 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3541 &pCurrentDirEntry->NameInformation.FileName);
3546 pCurrentDirEntry = pNextDirEntry;
3551 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3552 AFS_TRACE_LEVEL_VERBOSE,
3553 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3555 pCurrentDirEntry->DirOpenReferenceCount);
3557 if( pCurrentDirEntry->DirOpenReferenceCount <= 0)
3560 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3561 AFS_TRACE_LEVEL_VERBOSE,
3562 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3563 &pCurrentDirEntry->NameInformation.FileName,
3564 ObjectInfo->FileId.Cell,
3565 ObjectInfo->FileId.Volume,
3566 ObjectInfo->FileId.Vnode,
3567 ObjectInfo->FileId.Unique);
3569 AFSDeleteDirEntry( ObjectInfo,
3575 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3576 AFS_TRACE_LEVEL_VERBOSE,
3577 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3579 &pCurrentDirEntry->NameInformation.FileName,
3580 ObjectInfo->FileId.Cell,
3581 ObjectInfo->FileId.Volume,
3582 ObjectInfo->FileId.Vnode,
3583 ObjectInfo->FileId.Unique);
3585 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3587 AFSRemoveNameEntry( ObjectInfo,
3591 pCurrentDirEntry = pNextDirEntry;
3595 if( !AFSValidateDirList( ObjectInfo))
3598 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3607 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3615 AFSIsVolumeFID( IN AFSFileID *FileID)
3618 BOOLEAN bIsVolume = FALSE;
3620 if( FileID->Vnode == 1 &&
3621 FileID->Unique == 1)
3631 AFSIsFinalNode( IN AFSFcb *Fcb)
3634 BOOLEAN bIsFinalNode = FALSE;
3636 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3637 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3638 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3639 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3640 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3643 bIsFinalNode = TRUE;
3648 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3649 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3652 return bIsFinalNode;
3656 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3657 IN AFSDirEnumEntry *DirEnumEntry)
3660 NTSTATUS ntStatus = STATUS_SUCCESS;
3661 UNICODE_STRING uniTargetName;
3662 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3667 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3669 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3671 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3673 pObjectInfo->FileType = DirEnumEntry->FileType;
3675 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3677 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3679 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3681 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3683 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3685 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3687 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3689 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3692 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3695 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3696 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3699 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3702 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3704 pObjectInfo->Links = DirEnumEntry->Links;
3706 if( DirEnumEntry->TargetNameLength > 0 &&
3707 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3708 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3712 // Update the target name information if needed
3715 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3717 uniTargetName.MaximumLength = uniTargetName.Length;
3719 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3721 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3724 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3725 RtlCompareUnicodeString( &uniTargetName,
3726 &DirEntry->NameInformation.TargetName,
3731 // Update the target name
3734 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3736 uniTargetName.Buffer,
3737 uniTargetName.Length);
3739 if( !NT_SUCCESS( ntStatus))
3742 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3744 try_return( ntStatus);
3748 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3750 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3751 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3754 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3757 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3758 DirEntry->NameInformation.TargetName.Buffer != NULL)
3760 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3763 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3765 DirEntry->NameInformation.TargetName.Length = 0;
3766 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3767 DirEntry->NameInformation.TargetName.Buffer = NULL;
3769 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3781 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3783 IN BOOLEAN FastCall,
3784 IN BOOLEAN bSafeToPurge)
3787 NTSTATUS ntStatus = STATUS_SUCCESS;
3788 LARGE_INTEGER liSystemTime;
3789 AFSDirEnumEntry *pDirEnumEntry = NULL;
3790 AFSFcb *pCurrentFcb = NULL;
3791 BOOLEAN bReleaseFcb = FALSE;
3792 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3798 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3802 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3803 AFS_TRACE_LEVEL_VERBOSE_2,
3804 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3805 &DirEntry->NameInformation.FileName,
3806 pObjectInfo->FileId.Cell,
3807 pObjectInfo->FileId.Volume,
3808 pObjectInfo->FileId.Vnode,
3809 pObjectInfo->FileId.Unique,
3813 // If this is a fake node then bail since the service knows nothing about it
3816 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3819 try_return( ntStatus);
3823 // This routine ensures that the current entry is valid by:
3825 // 1) Checking that the expiration time is non-zero and after where we
3829 KeQuerySystemTime( &liSystemTime);
3831 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3832 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3833 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3834 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3837 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3838 AFS_TRACE_LEVEL_VERBOSE_2,
3839 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3840 &DirEntry->NameInformation.FileName,
3841 pObjectInfo->FileId.Cell,
3842 pObjectInfo->FileId.Volume,
3843 pObjectInfo->FileId.Vnode,
3844 pObjectInfo->FileId.Unique);
3846 try_return( ntStatus);
3850 // This node requires updating
3853 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3858 if( !NT_SUCCESS( ntStatus))
3861 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3862 AFS_TRACE_LEVEL_ERROR,
3863 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3865 &DirEntry->NameInformation.FileName,
3866 pObjectInfo->FileId.Cell,
3867 pObjectInfo->FileId.Volume,
3868 pObjectInfo->FileId.Vnode,
3869 pObjectInfo->FileId.Unique,
3873 // Failed validation of node so return access-denied
3876 try_return( ntStatus);
3879 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3880 AFS_TRACE_LEVEL_VERBOSE,
3881 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3883 &DirEntry->NameInformation.FileName,
3884 pObjectInfo->FileId.Cell,
3885 pObjectInfo->FileId.Volume,
3886 pObjectInfo->FileId.Vnode,
3887 pObjectInfo->FileId.Unique,
3888 pObjectInfo->DataVersion.QuadPart,
3889 pDirEnumEntry->DataVersion.QuadPart,
3890 pDirEnumEntry->FileType);
3894 // Based on the file type, process the node
3897 switch( pDirEnumEntry->FileType)
3900 case AFS_FILE_TYPE_MOUNTPOINT:
3904 // Update the metadata for the entry
3907 ntStatus = AFSUpdateMetaData( DirEntry,
3910 if( NT_SUCCESS( ntStatus))
3913 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3919 case AFS_FILE_TYPE_SYMLINK:
3920 case AFS_FILE_TYPE_DFSLINK:
3924 // Update the metadata for the entry
3927 ntStatus = AFSUpdateMetaData( DirEntry,
3930 if( NT_SUCCESS( ntStatus))
3933 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3939 case AFS_FILE_TYPE_FILE:
3942 BOOLEAN bPurgeExtents = FALSE;
3945 // For a file where the data version has become invalid we need to
3946 // fail any current extent requests and purge the cache for the file
3947 // Can't hold the Fcb resource while doing this
3950 if( pObjectInfo->Fcb != NULL &&
3951 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3952 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3955 pCurrentFcb = pObjectInfo->Fcb;
3957 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3960 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3961 AFS_TRACE_LEVEL_VERBOSE,
3962 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
3963 &pCurrentFcb->NPFcb->Resource,
3964 PsGetCurrentThread());
3966 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3972 if( pCurrentFcb != NULL)
3975 IO_STATUS_BLOCK stIoStatus;
3977 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3978 AFS_TRACE_LEVEL_VERBOSE_2,
3979 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3980 &DirEntry->NameInformation.FileName,
3981 pObjectInfo->FileId.Cell,
3982 pObjectInfo->FileId.Volume,
3983 pObjectInfo->FileId.Vnode,
3984 pObjectInfo->FileId.Unique);
3986 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3989 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3990 AFS_TRACE_LEVEL_VERBOSE,
3991 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
3992 &DirEntry->NameInformation.FileName,
3993 pObjectInfo->FileId.Cell,
3994 pObjectInfo->FileId.Volume,
3995 pObjectInfo->FileId.Vnode,
3996 pObjectInfo->FileId.Unique,
3997 pObjectInfo->DataVersion.LowPart,
3998 pDirEnumEntry->DataVersion.LowPart
4001 bPurgeExtents = TRUE;
4007 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4009 bPurgeExtents = TRUE;
4011 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4012 AFS_TRACE_LEVEL_VERBOSE,
4013 "AFSVerifyEntry Clearing VERIFY_DATA flag %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 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4023 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4024 AFS_TRACE_LEVEL_VERBOSE,
4025 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4026 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4027 PsGetCurrentThread());
4029 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4033 // Release Fcb->Resource to avoid Trend Micro deadlock
4036 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
4041 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4046 if( !NT_SUCCESS( stIoStatus.Status))
4049 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4050 AFS_TRACE_LEVEL_ERROR,
4051 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4052 &DirEntry->NameInformation.FileName,
4053 pObjectInfo->FileId.Cell,
4054 pObjectInfo->FileId.Volume,
4055 pObjectInfo->FileId.Vnode,
4056 pObjectInfo->FileId.Unique,
4058 stIoStatus.Information);
4060 ntStatus = stIoStatus.Status;
4063 if ( bPurgeExtents &&
4064 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4067 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4073 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4074 AFS_TRACE_LEVEL_WARNING,
4075 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4076 &DirEntry->NameInformation.FileName,
4077 pObjectInfo->FileId.Cell,
4078 pObjectInfo->FileId.Volume,
4079 pObjectInfo->FileId.Vnode,
4080 pObjectInfo->FileId.Unique);
4082 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4086 __except( EXCEPTION_EXECUTE_HANDLER)
4088 ntStatus = GetExceptionCode();
4092 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4093 &DirEntry->NameInformation.FileName,
4094 pObjectInfo->FileId.Cell,
4095 pObjectInfo->FileId.Volume,
4096 pObjectInfo->FileId.Vnode,
4097 pObjectInfo->FileId.Unique,
4100 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4103 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4104 AFS_TRACE_LEVEL_VERBOSE,
4105 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4106 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4107 PsGetCurrentThread());
4109 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4111 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4120 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4125 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4127 bReleaseFcb = FALSE;
4129 if ( bPurgeExtents &&
4132 AFSFlushExtents( pCurrentFcb,
4139 // Update the metadata for the entry but only if it is safe to do so.
4140 // If it was determined that a data version change has occurred or
4141 // that a pending data verification was required, do not update the
4142 // ObjectInfo meta data or the FileObject size information. That
4143 // way it is consistent for the next time that the data is verified
4147 if ( !(bPurgeExtents && bSafeToPurge))
4150 ntStatus = AFSUpdateMetaData( DirEntry,
4153 if( !NT_SUCCESS( ntStatus))
4156 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4157 AFS_TRACE_LEVEL_ERROR,
4158 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4159 &DirEntry->NameInformation.FileName,
4160 pObjectInfo->FileId.Cell,
4161 pObjectInfo->FileId.Volume,
4162 pObjectInfo->FileId.Vnode,
4163 pObjectInfo->FileId.Unique,
4169 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4172 // Update file sizes
4175 if( pObjectInfo->Fcb != NULL)
4177 FILE_OBJECT *pCCFileObject;
4179 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4180 AFS_TRACE_LEVEL_VERBOSE,
4181 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4182 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4183 PsGetCurrentThread());
4185 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4188 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4190 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4191 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4192 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4194 if ( pCCFileObject != NULL)
4196 CcSetFileSizes( pCCFileObject,
4197 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4200 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4201 AFS_TRACE_LEVEL_VERBOSE,
4202 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4203 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4204 PsGetCurrentThread());
4206 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4212 case AFS_FILE_TYPE_DIRECTORY:
4215 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4219 // For a directory or root entry flush the content of
4220 // the directory enumeration.
4223 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4224 AFS_TRACE_LEVEL_VERBOSE,
4225 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4226 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4227 PsGetCurrentThread());
4229 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4232 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4233 AFS_TRACE_LEVEL_VERBOSE_2,
4234 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4235 &DirEntry->NameInformation.FileName,
4236 pObjectInfo->FileId.Cell,
4237 pObjectInfo->FileId.Volume,
4238 pObjectInfo->FileId.Vnode,
4239 pObjectInfo->FileId.Unique);
4241 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4244 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4247 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4250 if( !NT_SUCCESS( ntStatus))
4253 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4254 AFS_TRACE_LEVEL_ERROR,
4255 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4256 &DirEntry->NameInformation.FileName,
4257 pObjectInfo->FileId.Cell,
4258 pObjectInfo->FileId.Volume,
4259 pObjectInfo->FileId.Vnode,
4260 pObjectInfo->FileId.Unique,
4268 // Update the metadata for the entry
4271 ntStatus = AFSUpdateMetaData( DirEntry,
4274 if( NT_SUCCESS( ntStatus))
4277 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4285 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4286 AFS_TRACE_LEVEL_WARNING,
4287 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4288 pObjectInfo->FileType,
4290 &DirEntry->NameInformation.FileName,
4291 pObjectInfo->FileId.Cell,
4292 pObjectInfo->FileId.Volume,
4293 pObjectInfo->FileId.Vnode,
4294 pObjectInfo->FileId.Unique);
4304 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4307 if( pDirEnumEntry != NULL)
4310 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4318 AFSInitializeSpecialShareNameList()
4321 NTSTATUS ntStatus = STATUS_SUCCESS;
4322 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4323 AFSObjectInfoCB *pObjectInfoCB = NULL;
4324 UNICODE_STRING uniShareName;
4325 ULONG ulEntryLength = 0;
4326 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4332 RtlInitUnicodeString( &uniShareName,
4335 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4338 if( pObjectInfoCB == NULL)
4341 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4344 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4345 AFS_OBJECT_REFERENCE_GLOBAL);
4347 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4348 AFS_TRACE_LEVEL_VERBOSE,
4349 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4353 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4355 ulEntryLength = sizeof( AFSDirectoryCB) +
4356 uniShareName.Length;
4358 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4362 if( pDirNode == NULL)
4365 AFSDeleteObjectInfo( pObjectInfoCB);
4367 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4370 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4371 AFS_TRACE_LEVEL_VERBOSE,
4372 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4375 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4376 sizeof( AFSNonPagedDirectoryCB),
4377 AFS_DIR_ENTRY_NP_TAG);
4379 if( pNonPagedDirEntry == NULL)
4382 ExFreePool( pDirNode);
4384 AFSDeleteObjectInfo( pObjectInfoCB);
4386 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4389 RtlZeroMemory( pDirNode,
4392 RtlZeroMemory( pNonPagedDirEntry,
4393 sizeof( AFSNonPagedDirectoryCB));
4395 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4397 pDirNode->NonPaged = pNonPagedDirEntry;
4399 pDirNode->ObjectInformation = pObjectInfoCB;
4405 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4407 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4409 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4411 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4413 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4414 uniShareName.Buffer,
4415 pDirNode->NameInformation.FileName.Length);
4417 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4420 AFSSpecialShareNames = pDirNode;
4422 pLastDirNode = pDirNode;
4425 RtlInitUnicodeString( &uniShareName,
4428 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4431 if( pObjectInfoCB == NULL)
4434 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4437 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4438 AFS_OBJECT_REFERENCE_GLOBAL);
4440 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4441 AFS_TRACE_LEVEL_VERBOSE,
4442 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4446 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4448 ulEntryLength = sizeof( AFSDirectoryCB) +
4449 uniShareName.Length;
4451 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4455 if( pDirNode == NULL)
4458 AFSDeleteObjectInfo( pObjectInfoCB);
4460 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4463 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4464 AFS_TRACE_LEVEL_VERBOSE,
4465 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4468 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4469 sizeof( AFSNonPagedDirectoryCB),
4470 AFS_DIR_ENTRY_NP_TAG);
4472 if( pNonPagedDirEntry == NULL)
4475 ExFreePool( pDirNode);
4477 AFSDeleteObjectInfo( pObjectInfoCB);
4479 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4482 RtlZeroMemory( pDirNode,
4485 RtlZeroMemory( pNonPagedDirEntry,
4486 sizeof( AFSNonPagedDirectoryCB));
4488 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4490 pDirNode->NonPaged = pNonPagedDirEntry;
4492 pDirNode->ObjectInformation = pObjectInfoCB;
4498 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4500 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4502 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4504 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4506 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4507 uniShareName.Buffer,
4508 pDirNode->NameInformation.FileName.Length);
4510 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4513 pLastDirNode->ListEntry.fLink = pDirNode;
4515 pDirNode->ListEntry.bLink = pLastDirNode;
4519 if( !NT_SUCCESS( ntStatus))
4522 if( AFSSpecialShareNames != NULL)
4525 pDirNode = AFSSpecialShareNames;
4527 while( pDirNode != NULL)
4530 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4532 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4534 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4536 ExFreePool( pDirNode->NonPaged);
4538 ExFreePool( pDirNode);
4540 pDirNode = pLastDirNode;
4543 AFSSpecialShareNames = NULL;
4552 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4553 IN UNICODE_STRING *SecondaryName)
4556 AFSDirectoryCB *pDirectoryCB = NULL;
4557 ULONGLONG ullHash = 0;
4558 UNICODE_STRING uniFullShareName;
4564 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4565 AFS_TRACE_LEVEL_VERBOSE_2,
4566 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4570 uniFullShareName = *ShareName;
4573 // Generate our hash value
4576 ullHash = AFSGenerateCRC( &uniFullShareName,
4580 // Loop through our special share names to see if this is one of them
4583 pDirectoryCB = AFSSpecialShareNames;
4585 while( pDirectoryCB != NULL)
4588 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4594 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4598 return pDirectoryCB;
4602 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4606 // Block on the queue flush event
4609 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4619 AFSWaitOnQueuedReleases()
4622 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4625 // Block on the queue flush event
4628 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4638 AFSIsEqualFID( IN AFSFileID *FileId1,
4639 IN AFSFileID *FileId2)
4642 BOOLEAN bIsEqual = FALSE;
4644 if( FileId1->Hash == FileId2->Hash &&
4645 FileId1->Unique == FileId2->Unique &&
4646 FileId1->Vnode == FileId2->Vnode &&
4647 FileId1->Volume == FileId2->Volume &&
4648 FileId1->Cell == FileId2->Cell)
4658 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4661 NTSTATUS ntStatus = STATUS_SUCCESS;
4662 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4667 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4670 // Reset the directory list information
4673 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4675 while( pCurrentDirEntry != NULL)
4678 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4680 if( pCurrentDirEntry->DirOpenReferenceCount <= 0)
4683 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4684 AFS_TRACE_LEVEL_VERBOSE,
4685 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4687 &pCurrentDirEntry->NameInformation.FileName);
4689 AFSDeleteDirEntry( ObjectInfoCB,
4695 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4696 AFS_TRACE_LEVEL_VERBOSE,
4697 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4699 &pCurrentDirEntry->NameInformation.FileName);
4701 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4703 AFSRemoveNameEntry( ObjectInfoCB,
4707 pCurrentDirEntry = pNextDirEntry;
4710 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4712 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4714 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4716 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4718 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4720 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4722 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4723 AFS_TRACE_LEVEL_VERBOSE,
4724 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4725 ObjectInfoCB->FileId.Cell,
4726 ObjectInfoCB->FileId.Volume,
4727 ObjectInfoCB->FileId.Vnode,
4728 ObjectInfoCB->FileId.Unique);
4735 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4738 NTSTATUS ntStatus = STATUS_SUCCESS;
4739 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4740 UNICODE_STRING uniFullName;
4745 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4746 AFS_TRACE_LEVEL_VERBOSE,
4747 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4748 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4749 PsGetCurrentThread());
4751 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4754 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4757 try_return( ntStatus);
4761 // Initialize the root information
4764 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4767 // Enumerate the shares in the volume
4770 ntStatus = AFSEnumerateDirectory( AuthGroup,
4771 &AFSGlobalRoot->ObjectInformation,
4774 if( !NT_SUCCESS( ntStatus))
4777 try_return( ntStatus);
4780 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4783 // Indicate the node is initialized
4786 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4788 uniFullName.MaximumLength = PAGE_SIZE;
4789 uniFullName.Length = 0;
4791 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4792 uniFullName.MaximumLength,
4793 AFS_GENERIC_MEMORY_12_TAG);
4795 if( uniFullName.Buffer == NULL)
4799 // Reset the directory content
4802 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4804 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4806 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4810 // Populate our list of entries in the NP enumeration list
4813 while( pDirGlobalDirNode != NULL)
4816 uniFullName.Buffer[ 0] = L'\\';
4817 uniFullName.Buffer[ 1] = L'\\';
4819 uniFullName.Length = 2 * sizeof( WCHAR);
4821 RtlCopyMemory( &uniFullName.Buffer[ 2],
4822 AFSServerName.Buffer,
4823 AFSServerName.Length);
4825 uniFullName.Length += AFSServerName.Length;
4827 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4829 uniFullName.Length += sizeof( WCHAR);
4831 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4832 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4833 pDirGlobalDirNode->NameInformation.FileName.Length);
4835 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4837 AFSAddConnectionEx( &uniFullName,
4838 RESOURCEDISPLAYTYPE_SHARE,
4841 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4844 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
4848 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4855 AFSIsRelativeName( IN UNICODE_STRING *Name)
4858 BOOLEAN bIsRelative = FALSE;
4860 if( Name->Length > 0 &&
4861 Name->Buffer[ 0] != L'\\')
4871 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
4873 UNICODE_STRING uniTempName;
4874 BOOLEAN bIsAbsolute = FALSE;
4877 // An absolute AFS path must begin with \afs\... or equivalent
4880 if ( Name->Length == 0 ||
4881 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
4882 Name->Buffer[ 0] != L'\\' ||
4883 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
4889 uniTempName.Length = AFSMountRootName.Length;
4890 uniTempName.MaximumLength = AFSMountRootName.Length;
4892 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4893 uniTempName.MaximumLength,
4894 AFS_NAME_BUFFER_TWO_TAG);
4896 if( uniTempName.Buffer == NULL)
4902 RtlCopyMemory( uniTempName.Buffer,
4904 AFSMountRootName.Length);
4906 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
4910 AFSExFreePoolWithTag( uniTempName.Buffer,
4911 AFS_NAME_BUFFER_TWO_TAG);
4918 AFSUpdateName( IN UNICODE_STRING *Name)
4923 while( usIndex < Name->Length/sizeof( WCHAR))
4926 if( Name->Buffer[ usIndex] == L'/')
4929 Name->Buffer[ usIndex] = L'\\';
4939 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4940 IN OUT ULONG *Flags,
4941 IN WCHAR *NameBuffer,
4942 IN USHORT NameLength)
4945 NTSTATUS ntStatus = STATUS_SUCCESS;
4946 WCHAR *pTmpBuffer = NULL;
4952 // If we have enough space then just move in the name otherwise
4953 // allocate a new buffer
4956 if( TargetName->Length < NameLength)
4959 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4961 AFS_NAME_BUFFER_FIVE_TAG);
4963 if( pTmpBuffer == NULL)
4966 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4969 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4972 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
4975 TargetName->MaximumLength = NameLength;
4977 TargetName->Buffer = pTmpBuffer;
4979 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4982 TargetName->Length = NameLength;
4984 RtlCopyMemory( TargetName->Buffer,
4986 TargetName->Length);
4989 // Update the name in the buffer
4992 AFSUpdateName( TargetName);
5003 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
5004 IN ULONG InitialElementCount)
5007 AFSNameArrayHdr *pNameArray = NULL;
5008 AFSNameArrayCB *pCurrentElement = NULL;
5009 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5015 if( InitialElementCount == 0)
5018 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
5021 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
5022 sizeof( AFSNameArrayHdr) +
5023 (InitialElementCount * sizeof( AFSNameArrayCB)),
5024 AFS_NAME_ARRAY_TAG);
5026 if( pNameArray == NULL)
5029 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5030 AFS_TRACE_LEVEL_ERROR,
5031 "AFSInitNameArray Failed to allocate name array\n");
5033 try_return( pNameArray);
5036 RtlZeroMemory( pNameArray,
5037 sizeof( AFSNameArrayHdr) +
5038 (InitialElementCount * sizeof( AFSNameArrayCB)));
5040 pNameArray->MaxElementCount = InitialElementCount;
5042 if( DirectoryCB != NULL)
5045 pCurrentElement = &pNameArray->ElementArray[ 0];
5047 pNameArray->CurrentEntry = pCurrentElement;
5049 pNameArray->Count = 1;
5051 pNameArray->LinkCount = 0;
5053 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5055 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5056 AFS_TRACE_LEVEL_VERBOSE,
5057 "AFSInitNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5059 &DirectoryCB->NameInformation.FileName,
5063 pCurrentElement->DirectoryCB = DirectoryCB;
5065 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5067 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5069 if( pCurrentElement->FileId.Vnode == 1)
5072 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5075 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5076 AFS_TRACE_LEVEL_VERBOSE,
5077 "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5079 pCurrentElement->DirectoryCB,
5080 pCurrentElement->FileId.Cell,
5081 pCurrentElement->FileId.Volume,
5082 pCurrentElement->FileId.Vnode,
5083 pCurrentElement->FileId.Unique,
5084 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5085 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5097 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
5098 IN UNICODE_STRING *Path,
5099 IN AFSDirectoryCB *DirectoryCB)
5102 NTSTATUS ntStatus = STATUS_SUCCESS;
5103 AFSNameArrayCB *pCurrentElement = NULL;
5109 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5110 AFS_TRACE_LEVEL_VERBOSE,
5111 "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5115 DirectoryCB->ObjectInformation->FileId.Cell,
5116 DirectoryCB->ObjectInformation->FileId.Volume,
5117 DirectoryCB->ObjectInformation->FileId.Vnode,
5118 DirectoryCB->ObjectInformation->FileId.Unique,
5119 &DirectoryCB->NameInformation.FileName,
5120 DirectoryCB->ObjectInformation->FileType);
5123 // Init some info in the header
5126 pCurrentElement = &NameArray->ElementArray[ 0];
5128 NameArray->CurrentEntry = pCurrentElement;
5131 // The first entry points at the root
5134 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
5136 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5138 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5139 AFS_TRACE_LEVEL_VERBOSE,
5140 "AFSPopulateNameArray [NA:%p] Increment count on volume %wZ DE %p Cnt %d\n",
5142 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5143 pCurrentElement->DirectoryCB,
5146 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
5148 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
5150 pCurrentElement->Flags = 0;
5152 if( pCurrentElement->FileId.Vnode == 1)
5155 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5158 NameArray->Count = 1;
5160 NameArray->LinkCount = 0;
5162 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5163 AFS_TRACE_LEVEL_VERBOSE,
5164 "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5166 pCurrentElement->DirectoryCB,
5167 pCurrentElement->FileId.Cell,
5168 pCurrentElement->FileId.Volume,
5169 pCurrentElement->FileId.Vnode,
5170 pCurrentElement->FileId.Unique,
5171 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5172 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5175 // If the root is the parent then we are done ...
5178 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
5180 try_return( ntStatus);
5192 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
5193 IN AFSNameArrayHdr *RelatedNameArray,
5194 IN AFSDirectoryCB *DirectoryCB)
5197 NTSTATUS ntStatus = STATUS_SUCCESS;
5198 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
5204 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5205 AFS_TRACE_LEVEL_VERBOSE,
5206 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5210 DirectoryCB->ObjectInformation->FileId.Cell,
5211 DirectoryCB->ObjectInformation->FileId.Volume,
5212 DirectoryCB->ObjectInformation->FileId.Vnode,
5213 DirectoryCB->ObjectInformation->FileId.Unique,
5214 &DirectoryCB->NameInformation.FileName,
5215 DirectoryCB->ObjectInformation->FileType);
5218 // Init some info in the header
5221 pCurrentElement = &NameArray->ElementArray[ 0];
5223 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5225 NameArray->Count = 0;
5227 NameArray->LinkCount = RelatedNameArray->LinkCount;
5230 // Populate the name array with the data from the related array
5236 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5238 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5240 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5242 pCurrentElement->Flags = 0;
5244 if( pCurrentElement->FileId.Vnode == 1)
5247 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5250 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5252 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5253 AFS_TRACE_LEVEL_VERBOSE,
5254 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5256 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5257 pCurrentElement->DirectoryCB,
5260 lCount = InterlockedIncrement( &NameArray->Count);
5262 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5263 AFS_TRACE_LEVEL_VERBOSE,
5264 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5267 pCurrentElement->DirectoryCB,
5268 pCurrentElement->FileId.Cell,
5269 pCurrentElement->FileId.Volume,
5270 pCurrentElement->FileId.Vnode,
5271 pCurrentElement->FileId.Unique,
5272 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5273 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5275 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5276 NameArray->Count == RelatedNameArray->Count)
5288 pCurrentRelatedElement++;
5291 NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
5298 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5301 NTSTATUS ntStatus = STATUS_SUCCESS;
5302 AFSNameArrayCB *pCurrentElement = NULL;
5303 LONG lCount, lElement;
5308 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5309 AFS_TRACE_LEVEL_VERBOSE,
5310 "AFSFreeNameArray [NA:%p]\n",
5313 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5316 pCurrentElement = &NameArray->ElementArray[ lElement];
5318 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5320 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5321 AFS_TRACE_LEVEL_VERBOSE,
5322 "AFSFreeNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5324 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5325 pCurrentElement->DirectoryCB,
5328 ASSERT( lCount >= 0);
5331 AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
5338 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5339 IN AFSDirectoryCB *DirectoryCB)
5342 NTSTATUS ntStatus = STATUS_SUCCESS;
5343 AFSNameArrayCB *pCurrentElement = NULL;
5349 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5350 AFS_TRACE_LEVEL_VERBOSE,
5351 "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5354 DirectoryCB->ObjectInformation->FileId.Cell,
5355 DirectoryCB->ObjectInformation->FileId.Volume,
5356 DirectoryCB->ObjectInformation->FileId.Vnode,
5357 DirectoryCB->ObjectInformation->FileId.Unique,
5358 &DirectoryCB->NameInformation.FileName,
5359 DirectoryCB->ObjectInformation->FileType);
5361 if( NameArray->Count == (LONG) NameArray->MaxElementCount)
5364 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5365 AFS_TRACE_LEVEL_ERROR,
5366 "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
5369 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5372 for ( lCount = 0; lCount < NameArray->Count; lCount++)
5375 if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
5376 &DirectoryCB->ObjectInformation->FileId) )
5379 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5380 AFS_TRACE_LEVEL_WARNING,
5381 "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
5384 STATUS_ACCESS_DENIED);
5386 try_return( ntStatus = STATUS_ACCESS_DENIED);
5390 if( NameArray->Count > 0)
5393 NameArray->CurrentEntry++;
5397 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5400 pCurrentElement = NameArray->CurrentEntry;
5402 lCount = InterlockedIncrement( &NameArray->Count);
5404 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5406 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5407 AFS_TRACE_LEVEL_VERBOSE,
5408 "AFSInsertNextElement [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5410 &DirectoryCB->NameInformation.FileName,
5414 ASSERT( lCount > 0);
5416 pCurrentElement->DirectoryCB = DirectoryCB;
5418 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5420 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5422 pCurrentElement->Flags = 0;
5424 if( pCurrentElement->FileId.Vnode == 1)
5427 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5430 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5431 AFS_TRACE_LEVEL_VERBOSE,
5432 "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5434 NameArray->Count - 1,
5435 pCurrentElement->DirectoryCB,
5436 pCurrentElement->FileId.Cell,
5437 pCurrentElement->FileId.Volume,
5438 pCurrentElement->FileId.Vnode,
5439 pCurrentElement->FileId.Unique,
5440 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5441 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5452 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5455 AFSDirectoryCB *pDirectoryCB = NULL;
5456 AFSNameArrayCB *pCurrentElement = NULL;
5457 BOOLEAN bVolumeRoot = FALSE;
5463 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5464 AFS_TRACE_LEVEL_VERBOSE,
5465 "AFSBackupEntry [NA:%p]\n",
5468 if( NameArray->Count == 0)
5471 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5472 AFS_TRACE_LEVEL_ERROR,
5473 "AFSBackupEntry [NA:%p] No more entries\n",
5476 try_return( pCurrentElement);
5479 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->NameArrayReferenceCount);
5481 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5482 AFS_TRACE_LEVEL_VERBOSE,
5483 "AFSBackupEntry [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5485 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5486 NameArray->CurrentEntry->DirectoryCB,
5489 ASSERT( lCount >= 0);
5491 NameArray->CurrentEntry->DirectoryCB = NULL;
5493 lCount = InterlockedDecrement( &NameArray->Count);
5497 NameArray->CurrentEntry = NULL;
5499 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5500 AFS_TRACE_LEVEL_ERROR,
5501 "AFSBackupEntry [NA:%p] No more entries\n",
5507 bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5509 NameArray->CurrentEntry--;
5511 pCurrentElement = NameArray->CurrentEntry;
5513 pDirectoryCB = pCurrentElement->DirectoryCB;
5515 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5516 AFS_TRACE_LEVEL_VERBOSE,
5517 "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5519 NameArray->Count - 1,
5520 pCurrentElement->DirectoryCB,
5521 pCurrentElement->FileId.Cell,
5522 pCurrentElement->FileId.Volume,
5523 pCurrentElement->FileId.Vnode,
5524 pCurrentElement->FileId.Unique,
5525 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5526 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5529 // If the entry we are removing is a volume root,
5530 // we must remove the mount point entry as well.
5531 // If the NameArray was constructed by checking the
5532 // share name via the service, the name array can
5533 // contain two volume roots in sequence without a
5534 // mount point separating them.
5538 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
5541 pDirectoryCB = AFSBackupEntry( NameArray);
5551 return pDirectoryCB;
5555 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5558 AFSDirectoryCB *pDirEntry = NULL;
5559 AFSNameArrayCB *pElement = NULL;
5564 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5565 AFS_TRACE_LEVEL_VERBOSE,
5566 "AFSGetParentEntry [NA:%p]\n",
5569 if( NameArray->Count == 0 ||
5570 NameArray->Count == 1)
5573 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5574 AFS_TRACE_LEVEL_ERROR,
5575 "AFSGetParentEntry [NA:%p] No more entries\n",
5578 try_return( pDirEntry = NULL);
5581 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5583 pDirEntry = pElement->DirectoryCB;
5585 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5586 AFS_TRACE_LEVEL_VERBOSE,
5587 "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5589 NameArray->Count - 2,
5590 pElement->DirectoryCB,
5591 pElement->FileId.Cell,
5592 pElement->FileId.Volume,
5593 pElement->FileId.Vnode,
5594 pElement->FileId.Unique,
5595 &pElement->DirectoryCB->NameInformation.FileName,
5596 pElement->DirectoryCB->ObjectInformation->FileType);
5607 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5608 IN AFSDirectoryCB *DirectoryCB)
5611 AFSNameArrayCB *pCurrentElement = NULL;
5612 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5613 LONG lCount, lElement;
5618 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5619 AFS_TRACE_LEVEL_VERBOSE,
5620 "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5623 DirectoryCB->ObjectInformation->FileId.Cell,
5624 DirectoryCB->ObjectInformation->FileId.Volume,
5625 DirectoryCB->ObjectInformation->FileId.Vnode,
5626 DirectoryCB->ObjectInformation->FileId.Unique,
5627 &DirectoryCB->NameInformation.FileName,
5628 DirectoryCB->ObjectInformation->FileType);
5630 // Dereference previous name array contents
5633 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5636 pCurrentElement = &NameArray->ElementArray[ lElement];
5638 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5640 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5641 AFS_TRACE_LEVEL_VERBOSE,
5642 "AFSResetNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5644 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5645 pCurrentElement->DirectoryCB,
5648 ASSERT( lCount >= 0);
5651 RtlZeroMemory( NameArray,
5652 sizeof( AFSNameArrayHdr) +
5653 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5655 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5657 if( DirectoryCB != NULL)
5660 pCurrentElement = &NameArray->ElementArray[ 0];
5662 NameArray->CurrentEntry = pCurrentElement;
5664 NameArray->Count = 1;
5666 NameArray->LinkCount = 0;
5668 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5670 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5671 AFS_TRACE_LEVEL_VERBOSE,
5672 "AFSResetNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5674 &DirectoryCB->NameInformation.FileName,
5678 pCurrentElement->DirectoryCB = DirectoryCB;
5680 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5682 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5684 pCurrentElement->Flags = 0;
5686 if( pCurrentElement->FileId.Vnode == 1)
5689 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5692 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5693 AFS_TRACE_LEVEL_VERBOSE,
5694 "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5696 pCurrentElement->DirectoryCB,
5697 pCurrentElement->FileId.Cell,
5698 pCurrentElement->FileId.Volume,
5699 pCurrentElement->FileId.Vnode,
5700 pCurrentElement->FileId.Unique,
5701 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5702 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5710 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5713 AFSNameArrayCB *pCurrentElement = NULL;
5715 pCurrentElement = &NameArray->ElementArray[ 0];
5717 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5719 while( pCurrentElement->DirectoryCB != NULL)
5722 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5723 pCurrentElement->FileId.Cell,
5724 pCurrentElement->FileId.Volume,
5725 pCurrentElement->FileId.Vnode,
5726 pCurrentElement->FileId.Unique,
5727 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5732 AFSPrint("AFSDumpNameArray End\n\n");
5738 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5743 // Depending on the type of node, set the event
5746 switch( Fcb->Header.NodeTypeCode)
5749 case AFS_DIRECTORY_FCB:
5754 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5764 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5770 // Depending on the type of node, set the event
5773 switch( Fcb->Header.NodeTypeCode)
5776 case AFS_DIRECTORY_FCB:
5781 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5783 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5793 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5796 BOOLEAN bIsInProcess = FALSE;
5801 if( ObjectInfo->Fcb == NULL)
5804 try_return( bIsInProcess);
5807 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5810 case AFS_DIRECTORY_FCB:
5815 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5818 bIsInProcess = TRUE;
5830 return bIsInProcess;
5834 AFSVerifyVolume( IN ULONGLONG ProcessId,
5835 IN AFSVolumeCB *VolumeCB)
5838 UNREFERENCED_PARAMETER(ProcessId);
5839 UNREFERENCED_PARAMETER(VolumeCB);
5840 NTSTATUS ntStatus = STATUS_SUCCESS;
5847 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5850 NTSTATUS ntStatus = STATUS_SUCCESS;
5851 AFSObjectInfoCB *pObjectInfoCB = NULL;
5852 AFSDirectoryCB *pDirNode = NULL;
5853 ULONG ulEntryLength = 0;
5854 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5860 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5863 if( pObjectInfoCB == NULL)
5866 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5869 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5870 AFS_OBJECT_REFERENCE_DIRENTRY);
5872 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5873 AFS_TRACE_LEVEL_VERBOSE,
5874 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5878 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5880 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5882 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5884 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5888 if( pDirNode == NULL)
5891 AFSDeleteObjectInfo( pObjectInfoCB);
5893 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5896 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5897 AFS_TRACE_LEVEL_VERBOSE,
5898 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5901 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5902 sizeof( AFSNonPagedDirectoryCB),
5903 AFS_DIR_ENTRY_NP_TAG);
5905 if( pNonPagedDirEntry == NULL)
5908 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5911 RtlZeroMemory( pDirNode,
5914 RtlZeroMemory( pNonPagedDirEntry,
5915 sizeof( AFSNonPagedDirectoryCB));
5917 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5919 pDirNode->NonPaged = pNonPagedDirEntry;
5921 pDirNode->ObjectInformation = pObjectInfoCB;
5923 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5929 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5931 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5933 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5935 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5937 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5938 AFSPIOCtlName.Buffer,
5939 pDirNode->NameInformation.FileName.Length);
5941 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5944 if ( InterlockedCompareExchangePointer( (PVOID *)&ObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5947 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5948 AFS_TRACE_LEVEL_WARNING,
5949 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5950 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5954 // Increment the open reference and handle on the node
5957 lCount = AFSObjectInfoIncrement( pDirNode->ObjectInformation,
5958 AFS_OBJECT_REFERENCE_DIRENTRY);
5960 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
5961 AFS_TRACE_LEVEL_VERBOSE,
5962 "AFSInitPIOCtlDirectoryCB Increment count on Object %p Cnt %d\n",
5963 pDirNode->ObjectInformation,
5966 try_return( ntStatus = STATUS_REPARSE);
5971 if ( ntStatus != STATUS_SUCCESS)
5974 if ( pDirNode != NULL)
5977 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5978 AFS_TRACE_LEVEL_VERBOSE,
5979 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
5982 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5985 if( pNonPagedDirEntry != NULL)
5988 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5990 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5993 if ( pObjectInfoCB != NULL)
5996 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
5997 AFS_OBJECT_REFERENCE_DIRENTRY);
5999 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6000 AFS_TRACE_LEVEL_VERBOSE,
6001 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
6005 AFSDeleteObjectInfo( pObjectInfoCB);
6014 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
6015 IN AFSDirectoryCB *DirectoryCB,
6016 IN UNICODE_STRING *ParentPathName,
6017 IN AFSNameArrayHdr *RelatedNameArray,
6019 OUT AFSFileInfoCB *FileInfo)
6022 NTSTATUS ntStatus = STATUS_SUCCESS;
6023 AFSDirEnumEntry *pDirEntry = NULL;
6024 UNICODE_STRING uniFullPathName = {0};
6025 AFSNameArrayHdr *pNameArray = NULL;
6026 AFSVolumeCB *pVolumeCB = NULL;
6027 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6028 WCHAR *pwchBuffer = NULL;
6029 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6030 ULONG ulNameDifference = 0;
6037 // Retrieve a target name for the entry
6040 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6043 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6046 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6048 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6053 if( !NT_SUCCESS( ntStatus) ||
6054 pDirEntry->TargetNameLength == 0)
6057 if( pDirEntry != NULL)
6060 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6063 try_return( ntStatus);
6066 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6069 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6073 // Update the target name
6076 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6077 &DirectoryCB->Flags,
6078 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6079 (USHORT)pDirEntry->TargetNameLength);
6081 if( !NT_SUCCESS( ntStatus))
6084 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6086 try_return( ntStatus);
6090 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6094 // Need to pass the full path in for parsing.
6097 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
6100 uniFullPathName.Length = 0;
6101 uniFullPathName.MaximumLength = ParentPathName->Length +
6103 DirectoryCB->NameInformation.TargetName.Length;
6105 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6106 uniFullPathName.MaximumLength,
6107 AFS_NAME_BUFFER_SIX_TAG);
6109 if( uniFullPathName.Buffer == NULL)
6112 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6114 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6117 pwchBuffer = uniFullPathName.Buffer;
6119 RtlZeroMemory( uniFullPathName.Buffer,
6120 uniFullPathName.MaximumLength);
6122 RtlCopyMemory( uniFullPathName.Buffer,
6123 ParentPathName->Buffer,
6124 ParentPathName->Length);
6126 uniFullPathName.Length = ParentPathName->Length;
6128 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
6129 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
6132 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
6134 uniFullPathName.Length += sizeof( WCHAR);
6137 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
6138 DirectoryCB->NameInformation.TargetName.Buffer,
6139 DirectoryCB->NameInformation.TargetName.Length);
6141 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
6143 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
6144 uniParsedName.MaximumLength = uniParsedName.Length;
6146 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
6148 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6151 // We populate up to the current parent
6154 if( RelatedNameArray != NULL)
6157 pNameArray = AFSInitNameArray( NULL,
6158 RelatedNameArray->MaxElementCount);
6160 if( pNameArray == NULL)
6163 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6166 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
6173 pNameArray = AFSInitNameArray( NULL,
6176 if( pNameArray == NULL)
6179 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6182 ntStatus = AFSPopulateNameArray( pNameArray,
6187 if( !NT_SUCCESS( ntStatus))
6190 try_return( ntStatus);
6193 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
6195 pParentDirEntry = ParentDirectoryCB;
6200 uniFullPathName.Length = 0;
6201 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6203 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6204 uniFullPathName.MaximumLength,
6205 AFS_NAME_BUFFER_SEVEN_TAG);
6207 if( uniFullPathName.Buffer == NULL)
6210 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6212 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6215 pwchBuffer = uniFullPathName.Buffer;
6217 RtlZeroMemory( uniFullPathName.Buffer,
6218 uniFullPathName.MaximumLength);
6220 RtlCopyMemory( uniFullPathName.Buffer,
6221 DirectoryCB->NameInformation.TargetName.Buffer,
6222 DirectoryCB->NameInformation.TargetName.Length);
6224 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6227 // This name should begin with the \afs server so parse it off and check it
6230 FsRtlDissectName( uniFullPathName,
6234 if( RtlCompareUnicodeString( &uniComponentName,
6239 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6241 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6242 AFS_TRACE_LEVEL_ERROR,
6243 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
6246 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
6249 uniFullPathName = uniRemainingPath;
6251 uniParsedName = uniFullPathName;
6253 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6255 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6261 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6264 if( pNameArray == NULL)
6267 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6270 pVolumeCB = AFSGlobalRoot;
6272 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6276 // Increment the ref count on the volume and dir entry for correct processing below
6279 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6281 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6282 AFS_TRACE_LEVEL_VERBOSE,
6283 "AFSRetrieveFileAttributes Increment count on volume %p Cnt %d\n",
6287 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6289 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6290 AFS_TRACE_LEVEL_VERBOSE,
6291 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6292 &pParentDirEntry->NameInformation.FileName,
6297 ntStatus = AFSLocateNameEntry( NULL,
6302 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
6308 if( !NT_SUCCESS( ntStatus) ||
6309 ntStatus == STATUS_REPARSE)
6313 // The volume lock was released on failure or reparse above
6314 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6317 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6320 if( pVolumeCB != NULL)
6323 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6325 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6326 AFS_TRACE_LEVEL_VERBOSE,
6327 "AFSRetrieveFileAttributes Decrement count on volume %p Cnt %d\n",
6332 if( pDirectoryEntry != NULL)
6335 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6337 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6338 AFS_TRACE_LEVEL_VERBOSE,
6339 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6340 &pDirectoryEntry->NameInformation.FileName,
6345 ASSERT( lCount >= 0);
6350 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6352 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6353 AFS_TRACE_LEVEL_VERBOSE,
6354 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6355 &pParentDirEntry->NameInformation.FileName,
6360 ASSERT( lCount >= 0);
6366 try_return( ntStatus);
6370 // Store off the information
6373 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6376 // Check for the mount point being returned
6379 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
6382 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6384 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
6385 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6388 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6391 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6396 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6400 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6402 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6404 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6406 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6408 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6410 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6413 // Remove the reference made above
6416 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6418 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6419 AFS_TRACE_LEVEL_VERBOSE,
6420 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
6421 &pDirectoryEntry->NameInformation.FileName,
6426 ASSERT( lCount >= 0);
6430 if( pDirEntry != NULL)
6433 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6436 if( pVolumeCB != NULL)
6439 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6441 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6442 AFS_TRACE_LEVEL_VERBOSE,
6443 "AFSRetrieveFileAttributes Decrement2 count on volume %p Cnt %d\n",
6448 if( pNameArray != NULL)
6451 AFSFreeNameArray( pNameArray);
6454 if( pwchBuffer != NULL)
6458 // Always free the buffer that we allocated as AFSLocateNameEntry
6459 // will not free it. If uniFullPathName.Buffer was allocated by
6460 // AFSLocateNameEntry, then we must free that as well.
6461 // Check that the uniFullPathName.Buffer in the string is not the same
6462 // offset by the length of the server name
6465 if( uniFullPathName.Length > 0 &&
6466 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6469 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6472 AFSExFreePoolWithTag( pwchBuffer, 0);
6480 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6481 IN ULONGLONG HashIndex)
6484 NTSTATUS ntStatus = STATUS_SUCCESS;
6485 AFSObjectInfoCB *pObjectInfo = NULL;
6491 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6492 sizeof( AFSObjectInfoCB),
6493 AFS_OBJECT_INFO_TAG);
6495 if( pObjectInfo == NULL)
6498 try_return( pObjectInfo);
6501 RtlZeroMemory( pObjectInfo,
6502 sizeof( AFSObjectInfoCB));
6504 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6505 sizeof( AFSNonPagedObjectInfoCB),
6506 AFS_NP_OBJECT_INFO_TAG);
6508 if( pObjectInfo->NonPagedInfo == NULL)
6511 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6513 try_return( pObjectInfo = NULL);
6516 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6518 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6520 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6522 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6524 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6526 if( ParentObjectInfo != NULL)
6529 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6530 AFS_OBJECT_REFERENCE_CHILD);
6532 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6533 AFS_TRACE_LEVEL_VERBOSE,
6534 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6540 // Initialize the access time
6543 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6549 // Insert the entry into the object tree and list
6552 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6554 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6557 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6562 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6563 &pObjectInfo->TreeEntry);
6565 ASSERT( NT_SUCCESS( ntStatus));
6569 // And the object list in the volume
6572 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6575 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6580 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6582 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6585 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6588 // Indicate the object is in the hash tree and linked list in the volume
6591 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6603 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6609 if ( ObjectInfo->ObjectReferenceCount == 0)
6612 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6615 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6620 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6623 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6628 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6630 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6635 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6637 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6643 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6649 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6652 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6657 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6659 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6661 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6664 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6667 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6669 ASSERT( lCount >= 0);
6671 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6679 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6682 BOOLEAN bAcquiredTreeLock = FALSE;
6685 if ( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_ROOT_VOLUME))
6689 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6690 // embedded in the VolumeCB.
6698 ASSERT( ObjectInfo->ObjectReferenceCount == 0);
6700 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6703 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6705 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6708 bAcquiredTreeLock = TRUE;
6712 // Remove it from the tree and list if it was inserted
6715 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6718 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6719 &ObjectInfo->TreeEntry);
6722 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6725 if( ObjectInfo->ListEntry.fLink == NULL)
6728 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6730 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6733 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6739 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6742 if( ObjectInfo->ListEntry.bLink == NULL)
6745 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6747 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6750 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6756 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6760 if( ObjectInfo->ParentObjectInformation != NULL)
6763 lCount = AFSObjectInfoDecrement( ObjectInfo->ParentObjectInformation,
6764 AFS_OBJECT_REFERENCE_CHILD);
6766 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6767 AFS_TRACE_LEVEL_VERBOSE,
6768 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6769 ObjectInfo->ParentObjectInformation,
6773 if( bAcquiredTreeLock)
6776 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6780 // Release the fid in the service
6783 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6786 AFSReleaseFid( &ObjectInfo->FileId);
6789 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6791 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6793 AFSExFreePoolWithTag( ObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6795 AFSExFreePoolWithTag( ObjectInfo, AFS_OBJECT_INFO_TAG);
6801 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6802 OUT AFSDirectoryCB **TargetDirEntry)
6805 NTSTATUS ntStatus = STATUS_SUCCESS;
6806 AFSDirEnumEntry *pDirEntry = NULL;
6807 UNICODE_STRING uniFullPathName = {0};
6808 AFSNameArrayHdr *pNameArray = NULL;
6809 AFSVolumeCB *pVolumeCB = NULL;
6810 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6811 WCHAR *pwchBuffer = NULL;
6812 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6813 ULONG ulNameDifference = 0;
6820 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6821 DirectoryCB->ObjectInformation,
6825 if( !NT_SUCCESS( ntStatus))
6827 try_return( ntStatus);
6831 // Retrieve a target name for the entry
6834 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6837 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6840 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6842 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6847 if( !NT_SUCCESS( ntStatus) ||
6848 pDirEntry->TargetNameLength == 0)
6851 if( pDirEntry != NULL)
6854 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6857 try_return( ntStatus);
6860 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6863 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6867 // Update the target name
6870 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6871 &DirectoryCB->Flags,
6872 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6873 (USHORT)pDirEntry->TargetNameLength);
6875 if( !NT_SUCCESS( ntStatus))
6878 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6880 try_return( ntStatus);
6884 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6888 // Need to pass the full path in for parsing.
6891 uniFullPathName.Length = 0;
6892 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6894 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6895 uniFullPathName.MaximumLength,
6896 AFS_NAME_BUFFER_EIGHT_TAG);
6898 if( uniFullPathName.Buffer == NULL)
6901 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6903 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6906 pwchBuffer = uniFullPathName.Buffer;
6908 RtlZeroMemory( uniFullPathName.Buffer,
6909 uniFullPathName.MaximumLength);
6911 RtlCopyMemory( uniFullPathName.Buffer,
6912 DirectoryCB->NameInformation.TargetName.Buffer,
6913 DirectoryCB->NameInformation.TargetName.Length);
6915 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6918 // This name should begin with the \afs server so parse it off and chech it
6921 FsRtlDissectName( uniFullPathName,
6925 if( RtlCompareUnicodeString( &uniComponentName,
6931 // Try evaluating the full path
6934 uniFullPathName.Buffer = pwchBuffer;
6936 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6938 uniFullPathName.MaximumLength = uniFullPathName.Length;
6943 uniFullPathName = uniRemainingPath;
6946 uniParsedName = uniFullPathName;
6948 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6950 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6956 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6959 if( pNameArray == NULL)
6962 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6965 pVolumeCB = AFSGlobalRoot;
6967 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6969 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6971 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6972 AFS_TRACE_LEVEL_VERBOSE,
6973 "AFSEvaluateRootEntry Increment count on volume %p Cnt %d\n",
6977 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6979 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6980 AFS_TRACE_LEVEL_VERBOSE,
6981 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6982 &pParentDirEntry->NameInformation.FileName,
6987 ntStatus = AFSLocateNameEntry( NULL,
6998 if( !NT_SUCCESS( ntStatus) ||
6999 ntStatus == STATUS_REPARSE)
7003 // The volume lock was released on failure or reparse above
7004 // Except for STATUS_OBJECT_NAME_NOT_FOUND
7007 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
7010 if( pVolumeCB != NULL)
7013 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7015 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7016 AFS_TRACE_LEVEL_VERBOSE,
7017 "AFSEvaluateRootEntry Decrement count on volume %p Cnt %d\n",
7022 if( pDirectoryEntry != NULL)
7025 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
7027 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7028 AFS_TRACE_LEVEL_VERBOSE,
7029 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7030 &pDirectoryEntry->NameInformation.FileName,
7035 ASSERT( lCount >= 0);
7040 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
7042 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7043 AFS_TRACE_LEVEL_VERBOSE,
7044 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7045 &pParentDirEntry->NameInformation.FileName,
7050 ASSERT( lCount >= 0);
7056 try_return( ntStatus);
7060 // Pass back the target dir entry for this request
7061 // The caller must release the DirOpenReferenceCount
7064 *TargetDirEntry = pDirectoryEntry;
7068 if( pDirEntry != NULL)
7071 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
7074 if( pVolumeCB != NULL)
7077 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7079 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7080 AFS_TRACE_LEVEL_VERBOSE,
7081 "AFSEvaluateRootEntry Decrement2 count on volume %p Cnt %d\n",
7086 if( pNameArray != NULL)
7089 AFSFreeNameArray( pNameArray);
7092 if( pwchBuffer != NULL)
7096 // Always free the buffer that we allocated as AFSLocateNameEntry
7097 // will not free it. If uniFullPathName.Buffer was allocated by
7098 // AFSLocateNameEntry, then we must free that as well.
7099 // Check that the uniFullPathName.Buffer in the string is not the same
7100 // offset by the length of the server name
7103 if( uniFullPathName.Length > 0 &&
7104 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
7107 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
7110 AFSExFreePoolWithTag( pwchBuffer, 0);
7118 AFSCleanupFcb( IN AFSFcb *Fcb,
7119 IN BOOLEAN ForceFlush)
7122 NTSTATUS ntStatus = STATUS_SUCCESS;
7123 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
7124 LARGE_INTEGER liTime;
7125 IO_STATUS_BLOCK stIoStatus;
7130 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7132 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7134 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
7137 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
7138 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7141 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7142 AFS_TRACE_LEVEL_VERBOSE,
7143 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
7144 &Fcb->NPFcb->Resource,
7145 PsGetCurrentThread());
7147 AFSAcquireShared( &Fcb->NPFcb->Resource,
7150 if( Fcb->OpenReferenceCount > 0)
7153 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7154 AFS_TRACE_LEVEL_VERBOSE,
7155 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7156 &Fcb->NPFcb->SectionObjectResource,
7157 PsGetCurrentThread());
7159 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
7165 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7170 if( !NT_SUCCESS( stIoStatus.Status))
7173 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7174 AFS_TRACE_LEVEL_ERROR,
7175 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7176 Fcb->ObjectInformation->FileId.Cell,
7177 Fcb->ObjectInformation->FileId.Volume,
7178 Fcb->ObjectInformation->FileId.Vnode,
7179 Fcb->ObjectInformation->FileId.Unique,
7181 stIoStatus.Information);
7183 ntStatus = stIoStatus.Status;
7186 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7189 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7195 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7196 AFS_TRACE_LEVEL_WARNING,
7197 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
7198 Fcb->ObjectInformation->FileId.Cell,
7199 Fcb->ObjectInformation->FileId.Volume,
7200 Fcb->ObjectInformation->FileId.Vnode,
7201 Fcb->ObjectInformation->FileId.Unique);
7203 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7207 __except( EXCEPTION_EXECUTE_HANDLER)
7210 ntStatus = GetExceptionCode();
7214 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7215 Fcb->ObjectInformation->FileId.Cell,
7216 Fcb->ObjectInformation->FileId.Volume,
7217 Fcb->ObjectInformation->FileId.Vnode,
7218 Fcb->ObjectInformation->FileId.Unique,
7221 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7224 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7225 AFS_TRACE_LEVEL_VERBOSE,
7226 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7227 &Fcb->NPFcb->SectionObjectResource,
7228 PsGetCurrentThread());
7230 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7233 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7234 AFS_TRACE_LEVEL_VERBOSE,
7235 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
7236 &Fcb->NPFcb->Resource,
7237 PsGetCurrentThread());
7239 AFSReleaseResource( &Fcb->NPFcb->Resource);
7242 // Wait for any currently running flush or release requests to complete
7245 AFSWaitOnQueuedFlushes( Fcb);
7248 // Now perform another flush on the file
7251 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7255 AFSReleaseExtentsWithFlush( Fcb,
7261 if( Fcb->OpenReferenceCount == 0 ||
7262 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7263 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7266 AFSTearDownFcbExtents( Fcb,
7270 try_return( ntStatus);
7273 KeQueryTickCount( &liTime);
7276 // First up are there dirty extents in the cache to flush?
7279 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7280 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7284 // The file has been marked as invalid. Dump it
7287 AFSTearDownFcbExtents( Fcb,
7290 else if( ForceFlush ||
7291 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7292 Fcb->Specific.File.ExtentCount) &&
7293 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7294 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7296 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7298 Fcb->OpenReferenceCount == 0)
7301 AFSReleaseExtentsWithFlush( Fcb,
7308 // If there are extents and they haven't been used recently *and*
7309 // are not being used
7313 ( 0 != Fcb->Specific.File.ExtentCount &&
7314 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7315 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7316 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7319 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7320 AFS_TRACE_LEVEL_VERBOSE,
7321 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7322 &Fcb->NPFcb->SectionObjectResource,
7323 PsGetCurrentThread());
7325 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7331 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7336 if( !NT_SUCCESS( stIoStatus.Status))
7339 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7340 AFS_TRACE_LEVEL_ERROR,
7341 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7342 Fcb->ObjectInformation->FileId.Cell,
7343 Fcb->ObjectInformation->FileId.Volume,
7344 Fcb->ObjectInformation->FileId.Vnode,
7345 Fcb->ObjectInformation->FileId.Unique,
7347 stIoStatus.Information);
7349 ntStatus = stIoStatus.Status;
7353 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7356 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7362 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7363 AFS_TRACE_LEVEL_WARNING,
7364 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7365 Fcb->ObjectInformation->FileId.Cell,
7366 Fcb->ObjectInformation->FileId.Volume,
7367 Fcb->ObjectInformation->FileId.Vnode,
7368 Fcb->ObjectInformation->FileId.Unique);
7370 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7374 __except( EXCEPTION_EXECUTE_HANDLER)
7377 ntStatus = GetExceptionCode();
7381 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7382 Fcb->ObjectInformation->FileId.Cell,
7383 Fcb->ObjectInformation->FileId.Volume,
7384 Fcb->ObjectInformation->FileId.Vnode,
7385 Fcb->ObjectInformation->FileId.Unique,
7389 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7390 AFS_TRACE_LEVEL_VERBOSE,
7391 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7392 &Fcb->NPFcb->SectionObjectResource,
7393 PsGetCurrentThread());
7395 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7397 if( Fcb->OpenReferenceCount <= 0)
7401 // Tear em down we'll not be needing them again
7404 AFSTearDownFcbExtents( Fcb,
7411 ntStatus = STATUS_RETRY;
7424 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7425 IN UNICODE_STRING *NewFileName)
7428 NTSTATUS ntStatus = STATUS_SUCCESS;
7429 WCHAR *pTmpBuffer = NULL;
7434 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7437 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7440 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7442 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7444 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7448 // OK, we need to allocate a new name buffer
7451 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7452 NewFileName->Length,
7453 AFS_NAME_BUFFER_NINE_TAG);
7455 if( pTmpBuffer == NULL)
7458 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7461 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7463 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7465 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7468 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7470 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7471 NewFileName->Buffer,
7472 NewFileName->Length);
7483 AFSReadCacheFile( IN void *ReadBuffer,
7484 IN LARGE_INTEGER *ReadOffset,
7485 IN ULONG RequestedDataLength,
7486 IN OUT PULONG BytesRead)
7489 NTSTATUS ntStatus = STATUS_SUCCESS;
7492 PIO_STACK_LOCATION pIoStackLocation = NULL;
7493 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7494 FILE_OBJECT *pCacheFileObject = NULL;
7499 pCacheFileObject = AFSReferenceCacheFileObject();
7501 if( pCacheFileObject == NULL)
7503 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7506 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7509 // Initialize the event
7512 KeInitializeEvent( &kEvent,
7513 SynchronizationEvent,
7517 // Allocate an irp for this request. This could also come from a
7518 // private pool, for instance.
7521 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7527 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7531 // Build the IRP's main body
7534 pIrp->UserBuffer = ReadBuffer;
7536 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7537 pIrp->RequestorMode = KernelMode;
7538 pIrp->Flags |= IRP_READ_OPERATION;
7541 // Set up the I/O stack location.
7544 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7545 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7546 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7547 pIoStackLocation->FileObject = pCacheFileObject;
7548 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7550 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7553 // Set the completion routine.
7556 IoSetCompletionRoutine( pIrp,
7564 // Send it to the FSD
7567 ntStatus = IoCallDriver( pTargetDeviceObject,
7570 if( NT_SUCCESS( ntStatus))
7577 ntStatus = KeWaitForSingleObject( &kEvent,
7583 if( NT_SUCCESS( ntStatus))
7586 ntStatus = pIrp->IoStatus.Status;
7588 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7594 if( pCacheFileObject != NULL)
7596 AFSReleaseCacheFileObject( pCacheFileObject);
7602 if( pIrp->MdlAddress != NULL)
7605 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7608 MmUnlockPages( pIrp->MdlAddress);
7611 IoFreeMdl( pIrp->MdlAddress);
7614 pIrp->MdlAddress = NULL;
7628 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7633 UNREFERENCED_PARAMETER(Irp);
7634 UNREFERENCED_PARAMETER(DeviceObject);
7635 KEVENT *pEvent = (KEVENT *)Context;
7641 return STATUS_MORE_PROCESSING_REQUIRED;
7645 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7648 BOOLEAN bIsEmpty = FALSE;
7649 AFSDirectoryCB *pDirEntry = NULL;
7654 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7659 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7662 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7664 while( pDirEntry != NULL)
7667 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7668 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7676 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7681 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7688 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7689 IN AFSDirectoryCB *DirEntry)
7692 NTSTATUS ntStatus = STATUS_SUCCESS;
7697 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7700 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7701 AFS_TRACE_LEVEL_VERBOSE,
7702 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7704 &DirEntry->NameInformation.FileName);
7706 try_return( ntStatus);
7709 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7712 // Remove the entry from the parent tree
7715 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7716 AFS_TRACE_LEVEL_VERBOSE,
7717 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7719 &DirEntry->NameInformation.FileName);
7721 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7724 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7725 AFS_TRACE_LEVEL_VERBOSE,
7726 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7728 &DirEntry->NameInformation.FileName);
7730 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7733 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7737 // From the short name tree
7740 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7741 AFS_TRACE_LEVEL_VERBOSE,
7742 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7744 &DirEntry->NameInformation.FileName);
7746 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7749 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7752 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7753 AFS_TRACE_LEVEL_VERBOSE,
7754 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7756 &DirEntry->NameInformation.FileName);
7758 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7760 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7771 AFSGetAuthenticationId()
7774 LARGE_INTEGER liAuthId = {0,0};
7775 NTSTATUS ntStatus = STATUS_SUCCESS;
7776 PACCESS_TOKEN hToken = NULL;
7777 PTOKEN_STATISTICS pTokenInfo = NULL;
7778 BOOLEAN bCopyOnOpen = FALSE;
7779 BOOLEAN bEffectiveOnly = FALSE;
7780 BOOLEAN bPrimaryToken = FALSE;
7781 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7786 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7789 &stImpersonationLevel);
7794 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7799 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7800 AFS_TRACE_LEVEL_ERROR,
7801 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7803 try_return( ntStatus);
7806 bPrimaryToken = TRUE;
7809 ntStatus = SeQueryInformationToken( hToken,
7811 (PVOID *)&pTokenInfo);
7813 if( !NT_SUCCESS( ntStatus))
7816 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7817 AFS_TRACE_LEVEL_ERROR,
7818 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7820 try_return( ntStatus);
7823 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7824 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7826 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7827 AFS_TRACE_LEVEL_VERBOSE,
7828 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7839 PsDereferenceImpersonationToken( hToken);
7844 PsDereferencePrimaryToken( hToken);
7848 if( pTokenInfo != NULL)
7851 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7859 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7863 UNREFERENCED_PARAMETER(Fcb);
7864 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7866 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7869 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7871 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7874 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7876 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7879 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7881 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7884 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7886 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7893 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7896 BOOLEAN bIsValid = TRUE;
7898 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7900 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7902 while( pCurrentDirEntry != NULL)
7905 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7909 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7914 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7915 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7918 if( pDirEntry == NULL)
7925 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7928 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
7931 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7933 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7935 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7944 AFSReferenceCacheFileObject()
7947 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7948 FILE_OBJECT *pCacheFileObject = NULL;
7950 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7953 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7955 if( pCacheFileObject != NULL)
7957 ObReferenceObject( pCacheFileObject);
7960 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7962 return pCacheFileObject;
7966 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7969 ASSERT( CacheFileObject != NULL);
7971 ObDereferenceObject( CacheFileObject);
7977 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7980 NTSTATUS ntStatus = STATUS_SUCCESS;
7981 AFSDeviceExt *pControlDevExt = NULL;
7982 ULONG ulTimeIncrement = 0;
7988 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7990 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7992 AFSServerName = LibraryInit->AFSServerName;
7994 AFSMountRootName = LibraryInit->AFSMountRootName;
7996 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7999 // Callbacks in the framework
8002 AFSProcessRequest = LibraryInit->AFSProcessRequest;
8004 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
8006 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
8008 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
8010 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
8012 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
8014 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
8016 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
8018 if( LibraryInit->AFSCacheBaseAddress != NULL)
8021 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
8023 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
8025 AFSLibCacheLength = LibraryInit->AFSCacheLength;
8029 // Initialize some flush parameters
8032 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
8034 ulTimeIncrement = KeQueryTimeIncrement();
8036 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
8037 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
8038 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
8039 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
8040 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
8043 // Initialize the global root entry
8046 ntStatus = AFSInitVolume( NULL,
8047 &LibraryInit->GlobalRootFid,
8050 if( !NT_SUCCESS( ntStatus))
8053 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8054 AFS_TRACE_LEVEL_ERROR,
8055 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
8058 try_return( ntStatus);
8061 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
8064 if( !NT_SUCCESS( ntStatus))
8067 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8068 AFS_TRACE_LEVEL_ERROR,
8069 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
8072 lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
8074 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8075 AFS_TRACE_LEVEL_VERBOSE,
8076 "AFSInitializeLibrary Increment count on volume %p Cnt %d\n",
8080 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8082 try_return( ntStatus);
8086 // Update the node type code to AFS_ROOT_ALL
8089 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
8091 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
8094 // Invalidate all known volumes since contact with the service and therefore
8095 // the file server was lost.
8098 AFSInvalidateAllVolumes();
8101 // Drop the locks acquired above
8104 AFSInitVolumeWorker( AFSGlobalRoot);
8106 lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
8108 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8109 AFS_TRACE_LEVEL_VERBOSE,
8110 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8114 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8116 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
8130 NTSTATUS ntStatus = STATUS_SUCCESS;
8131 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
8137 if( AFSGlobalDotDirEntry != NULL)
8140 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
8141 AFS_OBJECT_REFERENCE_GLOBAL);
8143 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
8145 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
8147 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
8149 ExFreePool( AFSGlobalDotDirEntry);
8151 AFSGlobalDotDirEntry = NULL;
8154 if( AFSGlobalDotDotDirEntry != NULL)
8157 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
8158 AFS_OBJECT_REFERENCE_GLOBAL);
8160 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
8162 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
8164 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
8166 ExFreePool( AFSGlobalDotDotDirEntry);
8168 AFSGlobalDotDotDirEntry = NULL;
8171 if( AFSSpecialShareNames != NULL)
8174 pDirNode = AFSSpecialShareNames;
8176 while( pDirNode != NULL)
8179 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
8181 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
8182 AFS_OBJECT_REFERENCE_GLOBAL);
8184 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
8186 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
8188 ExFreePool( pDirNode->NonPaged);
8190 ExFreePool( pDirNode);
8192 pDirNode = pLastDirNode;
8195 AFSSpecialShareNames = NULL;
8203 AFSDefaultLogMsg( IN ULONG Subsystem,
8209 UNREFERENCED_PARAMETER(Subsystem);
8210 UNREFERENCED_PARAMETER(Level);
8211 NTSTATUS ntStatus = STATUS_SUCCESS;
8213 char chDebugBuffer[ 256];
8218 va_start( va_args, Format);
8220 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8225 if( NT_SUCCESS( ntStatus))
8227 DbgPrint( chDebugBuffer);
8237 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8238 IN ULONG InputBufferLength,
8239 IN AFSStatusInfoCB *StatusInfo,
8240 OUT ULONG *ReturnLength)
8243 NTSTATUS ntStatus = STATUS_SUCCESS;
8244 AFSVolumeCB *pVolumeCB = NULL;
8245 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8246 AFSObjectInfoCB *pObjectInfo = NULL;
8247 ULONGLONG ullIndex = 0;
8248 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8249 AFSNameArrayHdr *pNameArray = NULL;
8250 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8257 // If we are given a FID then look up the entry by that, otherwise
8261 if( GetStatusInfo->FileID.Cell != 0 &&
8262 GetStatusInfo->FileID.Volume != 0 &&
8263 GetStatusInfo->FileID.Vnode != 0 &&
8264 GetStatusInfo->FileID.Unique != 0)
8267 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8270 // Locate the volume node
8273 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8275 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8277 (AFSBTreeEntry **)&pVolumeCB);
8279 if( pVolumeCB != NULL)
8282 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8284 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8285 AFS_TRACE_LEVEL_VERBOSE,
8286 "AFSGetObjectStatus Increment count on volume %p Cnt %d\n",
8291 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8293 if( !NT_SUCCESS( ntStatus) ||
8296 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8299 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8302 pObjectInfo = &pVolumeCB->ObjectInformation;
8304 lCount = AFSObjectInfoIncrement( pObjectInfo,
8305 AFS_OBJECT_REFERENCE_STATUS);
8307 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8308 AFS_TRACE_LEVEL_VERBOSE,
8309 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8313 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8315 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8316 AFS_TRACE_LEVEL_VERBOSE,
8317 "AFSGetObjectStatus Decrement count on volume %p Cnt %d\n",
8324 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8327 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8329 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8330 AFS_TRACE_LEVEL_VERBOSE,
8331 "AFSGetObjectStatus Decrement2 count on volume %p Cnt %d\n",
8335 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8337 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8339 (AFSBTreeEntry **)&pObjectInfo);
8341 if( pObjectInfo != NULL)
8345 // Reference the node so it won't be torn down
8348 lCount = AFSObjectInfoIncrement( pObjectInfo,
8349 AFS_OBJECT_REFERENCE_STATUS);
8351 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8352 AFS_TRACE_LEVEL_VERBOSE,
8353 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8358 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8360 if( !NT_SUCCESS( ntStatus) ||
8361 pObjectInfo == NULL)
8363 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8370 if( GetStatusInfo->FileNameLength == 0 ||
8371 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8373 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8376 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8377 uniFullPathName.MaximumLength = uniFullPathName.Length;
8379 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8382 // This name should begin with the \afs server so parse it off and check it
8385 FsRtlDissectName( uniFullPathName,
8389 if( RtlCompareUnicodeString( &uniComponentName,
8393 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8394 AFS_TRACE_LEVEL_ERROR,
8395 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8398 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8401 uniFullPathName = uniRemainingPath;
8403 uniParsedName = uniFullPathName;
8409 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8412 if( pNameArray == NULL)
8414 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8417 pVolumeCB = AFSGlobalRoot;
8419 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8422 // Increment the ref count on the volume and dir entry for correct processing below
8425 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8427 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8428 AFS_TRACE_LEVEL_VERBOSE,
8429 "AFSGetObjectStatus Increment2 count on volume %p Cnt %d\n",
8433 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8435 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8436 AFS_TRACE_LEVEL_VERBOSE,
8437 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8438 &pParentDirEntry->NameInformation.FileName,
8443 ntStatus = AFSLocateNameEntry( NULL,
8448 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8449 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8455 if( !NT_SUCCESS( ntStatus) ||
8456 ntStatus == STATUS_REPARSE)
8460 // The volume lock was released on failure or reparse above
8461 // Except for STATUS_OBJECT_NAME_NOT_FOUND
8464 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
8467 if( pVolumeCB != NULL)
8470 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8472 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8473 AFS_TRACE_LEVEL_VERBOSE,
8474 "AFSGetObjectStatus Decrement3 count on volume %p Cnt %d\n",
8479 if( pDirectoryEntry != NULL)
8482 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8484 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8485 AFS_TRACE_LEVEL_VERBOSE,
8486 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8487 &pDirectoryEntry->NameInformation.FileName,
8492 ASSERT( lCount >= 0);
8497 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8499 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8500 AFS_TRACE_LEVEL_VERBOSE,
8501 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8502 &pParentDirEntry->NameInformation.FileName,
8507 ASSERT( lCount >= 0);
8513 try_return( ntStatus);
8517 // Remove the reference obtained from AFSLocateNameEntry
8520 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8522 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8523 AFS_TRACE_LEVEL_VERBOSE,
8524 "AFSGetObjectStatus Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
8525 &pDirectoryEntry->NameInformation.FileName,
8530 ASSERT( lCount >= 0);
8532 pObjectInfo = pDirectoryEntry->ObjectInformation;
8534 lCount = AFSObjectInfoIncrement( pObjectInfo,
8535 AFS_OBJECT_REFERENCE_STATUS);
8537 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8538 AFS_TRACE_LEVEL_VERBOSE,
8539 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8543 if( pVolumeCB != NULL)
8546 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8548 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8549 AFS_TRACE_LEVEL_VERBOSE,
8550 "AFSGetObjectStatus Decrement4 count on volume %p Cnt %d\n",
8557 // At this point we have an object info block, return the information
8560 StatusInfo->FileId = pObjectInfo->FileId;
8562 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8564 StatusInfo->Expiration = pObjectInfo->Expiration;
8566 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8568 StatusInfo->FileType = pObjectInfo->FileType;
8570 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8572 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8574 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8576 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8578 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8580 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8582 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8584 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8586 StatusInfo->EaSize = pObjectInfo->EaSize;
8588 StatusInfo->Links = pObjectInfo->Links;
8591 // Return the information length
8594 *ReturnLength = sizeof( AFSStatusInfoCB);
8598 if( pObjectInfo != NULL)
8601 lCount = AFSObjectInfoDecrement( pObjectInfo,
8602 AFS_OBJECT_REFERENCE_STATUS);
8604 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8605 AFS_TRACE_LEVEL_VERBOSE,
8606 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8611 if( pNameArray != NULL)
8614 AFSFreeNameArray( pNameArray);
8622 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8623 IN UNICODE_STRING *ComponentName)
8626 NTSTATUS ntStatus = STATUS_SUCCESS;
8627 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8628 AFSDirectoryCB *pDirEntry = NULL;
8636 // Search for the entry in the parent
8639 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8640 AFS_TRACE_LEVEL_VERBOSE_2,
8641 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8644 ulCRC = AFSGenerateCRC( ComponentName,
8647 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8650 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8654 if( pDirEntry == NULL)
8658 // Missed so perform a case insensitive lookup
8661 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8662 AFS_TRACE_LEVEL_VERBOSE_2,
8663 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8666 ulCRC = AFSGenerateCRC( ComponentName,
8669 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8673 if( pDirEntry == NULL)
8677 // OK, if this component is a valid short name then try
8678 // a lookup in the short name tree
8681 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8682 RtlIsNameLegalDOS8Dot3( ComponentName,
8687 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8688 AFS_TRACE_LEVEL_VERBOSE_2,
8689 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8692 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8699 if( pDirEntry != NULL)
8701 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8703 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8704 AFS_TRACE_LEVEL_VERBOSE,
8705 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8706 &pDirEntry->NameInformation.FileName,
8711 ASSERT( lCount >= 0);
8714 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8716 if( pDirEntry == NULL)
8719 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8720 AFS_TRACE_LEVEL_VERBOSE_2,
8721 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8723 STATUS_OBJECT_NAME_NOT_FOUND);
8725 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8729 // We have the symlink object but previously failed to process it so return access
8733 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8734 AFS_TRACE_LEVEL_VERBOSE_2,
8735 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8738 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8740 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8742 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8743 AFS_TRACE_LEVEL_VERBOSE,
8744 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8745 &pDirEntry->NameInformation.FileName,
8750 ASSERT( lCount >= 0);
8761 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8762 OUT UNICODE_STRING *ComponentName)
8765 NTSTATUS ntStatus = STATUS_SUCCESS;
8766 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8768 uniFullPathName = *FullPathName;
8773 FsRtlDissectName( uniFullPathName,
8777 if( uniRemainingPath.Length == 0)
8782 uniFullPathName = uniRemainingPath;
8785 if( uniComponentName.Length > 0)
8787 *ComponentName = uniComponentName;
8794 AFSDumpTraceFiles_Default()
8800 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8803 BOOLEAN bIsValidName = TRUE;
8809 while( usIndex < FileName->Length/sizeof( WCHAR))
8812 if( FileName->Buffer[ usIndex] == L':' ||
8813 FileName->Buffer[ usIndex] == L'*' ||
8814 FileName->Buffer[ usIndex] == L'?' ||
8815 FileName->Buffer[ usIndex] == L'"' ||
8816 FileName->Buffer[ usIndex] == L'<' ||
8817 FileName->Buffer[ usIndex] == L'>')
8819 bIsValidName = FALSE;
8827 return bIsValidName;
8831 AFSCreateDefaultSecurityDescriptor()
8834 NTSTATUS ntStatus = STATUS_SUCCESS;
8836 ULONG ulSACLSize = 0;
8837 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8838 ULONG ulACESize = 0;
8839 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8840 ULONG ulSDLength = 0;
8841 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8842 PSID pWorldSID = NULL;
8843 ULONG *pulSubAuthority = NULL;
8844 ULONG ulWorldSIDLEngth = 0;
8849 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8851 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8853 AFS_GENERIC_MEMORY_29_TAG);
8855 if( pWorldSID == NULL)
8857 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8858 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8861 RtlZeroMemory( pWorldSID,
8864 RtlInitializeSid( pWorldSID,
8865 &SeWorldSidAuthority,
8868 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8869 *pulSubAuthority = SECURITY_WORLD_RID;
8871 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8874 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8879 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8881 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8883 AFS_GENERIC_MEMORY_29_TAG);
8888 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8890 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8893 RtlZeroMemory( pACE,
8896 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8897 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8898 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8899 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8901 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8903 SeExports->SeLowMandatorySid);
8905 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8906 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8908 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8910 AFS_GENERIC_MEMORY_29_TAG);
8915 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8917 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8920 ntStatus = RtlCreateAcl( pSACL,
8924 if( !NT_SUCCESS( ntStatus))
8927 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8930 try_return( ntStatus);
8933 ntStatus = RtlAddAce( pSACL,
8937 pACE->Header.AceSize);
8939 if( !NT_SUCCESS( ntStatus))
8942 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8945 try_return( ntStatus);
8949 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8950 sizeof( SECURITY_DESCRIPTOR),
8951 AFS_GENERIC_MEMORY_27_TAG);
8953 if( pSecurityDescr == NULL)
8956 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8958 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8961 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8962 SECURITY_DESCRIPTOR_REVISION);
8964 if( !NT_SUCCESS( ntStatus))
8967 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8970 try_return( ntStatus);
8973 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8975 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8980 if( !NT_SUCCESS( ntStatus))
8983 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8986 try_return( ntStatus);
8991 // Add in the group and owner to the SD
8994 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8996 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
9000 if( !NT_SUCCESS( ntStatus))
9003 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
9006 try_return( ntStatus);
9010 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
9014 if( !NT_SUCCESS( ntStatus))
9017 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
9020 try_return( ntStatus);
9023 if( !RtlValidSecurityDescriptor( pSecurityDescr))
9026 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
9028 try_return( ntStatus = STATUS_INVALID_PARAMETER);
9031 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
9033 AFS_GENERIC_MEMORY_27_TAG);
9035 if( pRelativeSecurityDescr == NULL)
9038 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9040 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9043 ulSDLength = PAGE_SIZE;
9045 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
9046 pRelativeSecurityDescr,
9049 if( !NT_SUCCESS( ntStatus))
9052 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
9055 try_return( ntStatus);
9058 AFSDefaultSD = pRelativeSecurityDescr;
9062 if( !NT_SUCCESS( ntStatus))
9065 if( pRelativeSecurityDescr != NULL)
9067 ExFreePool( pRelativeSecurityDescr);
9071 if( pSecurityDescr != NULL)
9073 ExFreePool( pSecurityDescr);
9086 if( pWorldSID != NULL)
9088 ExFreePool( pWorldSID);
9096 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
9097 OUT UNICODE_STRING *ParentPath)
9100 *ParentPath = *FullFileName;
9103 // If the final character is a \, jump over it
9106 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
9108 ParentPath->Length -= sizeof( WCHAR);
9111 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
9113 ParentPath->Length -= sizeof( WCHAR);
9117 // And the separator
9120 ParentPath->Length -= sizeof( WCHAR);
9126 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
9127 IN AFSObjectInfoCB *ObjectInfo,
9128 IN BOOLEAN WriteAccess,
9129 OUT GUID *AuthGroup)
9132 NTSTATUS ntStatus = STATUS_SUCCESS;
9133 GUID stAuthGroup, stZeroAuthGroup;
9134 BOOLEAN bFoundAuthGroup = FALSE;
9135 AFSCcb *pCcb = NULL;
9141 RtlZeroMemory( &stAuthGroup,
9144 RtlZeroMemory( &stZeroAuthGroup,
9150 if( ObjectInfo != NULL &&
9151 ObjectInfo->Fcb != NULL)
9153 pFcb = ObjectInfo->Fcb;
9160 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
9163 pCcb = Fcb->CcbListHead;
9165 while( pCcb != NULL)
9169 pCcb->GrantedAccess & FILE_WRITE_DATA)
9171 RtlCopyMemory( &stAuthGroup,
9175 bFoundAuthGroup = TRUE;
9179 else if( pCcb->GrantedAccess & FILE_READ_DATA)
9182 // At least get the read-only access
9185 RtlCopyMemory( &stAuthGroup,
9189 bFoundAuthGroup = TRUE;
9192 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9195 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9198 if( !bFoundAuthGroup)
9201 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9202 (ULONGLONG)PsGetCurrentThreadId(),
9205 if( RtlCompareMemory( &stZeroAuthGroup,
9207 sizeof( GUID)) == sizeof( GUID))
9210 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9212 try_return( ntStatus = STATUS_ACCESS_DENIED);
9216 RtlCopyMemory( AuthGroup,
9229 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9230 IN ULONG InvalidateReason)
9233 NTSTATUS ntStatus = STATUS_SUCCESS;
9236 ULONG ulProcessCount = 0;
9243 switch( InvalidateReason)
9246 case AFS_INVALIDATE_DELETED:
9249 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9250 ObjectInfo->Fcb != NULL)
9253 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9256 ObjectInfo->Links = 0;
9258 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9260 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9265 // Clear out the extents
9266 // And get rid of them (note this involves waiting
9267 // for any writes or reads to the cache to complete)
9270 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9273 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9279 case AFS_INVALIDATE_DATA_VERSION:
9282 LARGE_INTEGER liCurrentOffset = {0,0};
9283 LARGE_INTEGER liFlushLength = {0,0};
9284 ULONG ulFlushLength = 0;
9285 BOOLEAN bLocked = FALSE;
9286 BOOLEAN bExtentsLocked = FALSE;
9287 BOOLEAN bCleanExtents = FALSE;
9289 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9290 ObjectInfo->Fcb != NULL)
9293 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9298 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9299 AFS_TRACE_LEVEL_VERBOSE,
9300 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9301 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9302 PsGetCurrentThread());
9304 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9307 bExtentsLocked = TRUE;
9310 // There are several possibilities here:
9312 // 0. If there are no extents or all of the extents are dirty, do nothing.
9314 // 1. There could be nothing dirty and an open reference count of zero
9315 // in which case we can just tear down all of the extents without
9316 // holding any resources.
9318 // 2. There could be nothing dirty and a non-zero open reference count
9319 // in which case we can issue a CcPurge against the entire file
9320 // while holding just the Fcb Resource.
9322 // 3. There can be dirty extents in which case we need to identify
9323 // the non-dirty ranges and then perform a CcPurge on just the
9324 // non-dirty ranges while holding just the Fcb Resource.
9327 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9330 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9333 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9335 bExtentsLocked = FALSE;
9337 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9340 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9344 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9350 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9351 AFS_TRACE_LEVEL_VERBOSE,
9352 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9353 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9354 PsGetCurrentThread());
9356 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9359 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9366 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9367 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9373 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9374 AFS_TRACE_LEVEL_WARNING,
9375 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9376 ObjectInfo->FileId.Cell,
9377 ObjectInfo->FileId.Volume,
9378 ObjectInfo->FileId.Vnode,
9379 ObjectInfo->FileId.Unique);
9381 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9386 bCleanExtents = TRUE;
9389 __except( EXCEPTION_EXECUTE_HANDLER)
9392 ntStatus = GetExceptionCode();
9396 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9397 ObjectInfo->FileId.Cell,
9398 ObjectInfo->FileId.Volume,
9399 ObjectInfo->FileId.Vnode,
9400 ObjectInfo->FileId.Unique,
9403 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9406 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9407 AFS_TRACE_LEVEL_VERBOSE,
9408 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9409 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9410 PsGetCurrentThread());
9412 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9418 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9420 bExtentsLocked = FALSE;
9422 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9423 AFS_TRACE_LEVEL_VERBOSE,
9424 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9425 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9426 PsGetCurrentThread());
9428 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9431 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9436 // Must build a list of non-dirty ranges from the beginning of the file
9437 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9438 // ranges. In all but the most extreme random data write scenario there will
9439 // be significantly fewer.
9441 // For each range we need offset and size.
9444 AFSByteRange * ByteRangeList = NULL;
9445 ULONG ulByteRangeCount = 0;
9447 BOOLEAN bPurgeOnClose = FALSE;
9452 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9455 if ( ByteRangeList != NULL ||
9456 ulByteRangeCount == 0)
9459 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9466 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9468 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9469 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9470 &ByteRangeList[ulIndex].FileOffset,
9475 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9476 AFS_TRACE_LEVEL_WARNING,
9477 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9478 ObjectInfo->FileId.Cell,
9479 ObjectInfo->FileId.Volume,
9480 ObjectInfo->FileId.Vnode,
9481 ObjectInfo->FileId.Unique);
9483 bPurgeOnClose = TRUE;
9488 bCleanExtents = TRUE;
9491 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9493 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9495 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9502 // We couldn't allocate the memory to build the purge list
9503 // so just walk the extent list while holding the ExtentsList Resource.
9504 // This could deadlock but we do not have much choice.
9507 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9509 bExtentsLocked = TRUE;
9511 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9515 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9519 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9521 while( ulProcessCount < ulCount)
9523 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9525 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9527 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9528 &pEntry->FileOffset,
9533 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9534 AFS_TRACE_LEVEL_WARNING,
9535 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9536 ObjectInfo->FileId.Cell,
9537 ObjectInfo->FileId.Volume,
9538 ObjectInfo->FileId.Vnode,
9539 ObjectInfo->FileId.Unique);
9541 bPurgeOnClose = TRUE;
9546 bCleanExtents = TRUE;
9550 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9553 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9555 while( liFlushLength.QuadPart > 0)
9558 if( liFlushLength.QuadPart > 512 * 1024000)
9560 ulFlushLength = 512 * 1024000;
9564 ulFlushLength = liFlushLength.LowPart;
9567 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9573 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9574 AFS_TRACE_LEVEL_WARNING,
9575 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9576 ObjectInfo->FileId.Cell,
9577 ObjectInfo->FileId.Volume,
9578 ObjectInfo->FileId.Vnode,
9579 ObjectInfo->FileId.Unique);
9581 bPurgeOnClose = TRUE;
9586 bCleanExtents = TRUE;
9589 liFlushLength.QuadPart -= ulFlushLength;
9593 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9601 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9607 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9608 AFS_TRACE_LEVEL_WARNING,
9609 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9610 ObjectInfo->FileId.Cell,
9611 ObjectInfo->FileId.Volume,
9612 ObjectInfo->FileId.Vnode,
9613 ObjectInfo->FileId.Unique);
9615 bPurgeOnClose = TRUE;
9620 bCleanExtents = TRUE;
9627 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9631 __except( EXCEPTION_EXECUTE_HANDLER)
9634 ntStatus = GetExceptionCode();
9638 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9639 ObjectInfo->FileId.Cell,
9640 ObjectInfo->FileId.Volume,
9641 ObjectInfo->FileId.Vnode,
9642 ObjectInfo->FileId.Unique,
9646 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9647 AFS_TRACE_LEVEL_VERBOSE,
9648 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9649 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9650 PsGetCurrentThread());
9652 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9656 if ( bExtentsLocked)
9659 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9665 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9671 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9681 // Destroy the reference passed in by the caller to AFSInvalidateObject
9682 // or AFSQueueInvalidateObject
9685 lCount = AFSObjectInfoDecrement( ObjectInfo,
9686 AFS_OBJECT_REFERENCE_INVALIDATION);
9688 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9689 AFS_TRACE_LEVEL_VERBOSE,
9690 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",