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 PEXCEPTION_RECORD ExceptRec;
65 ExceptRec = ExceptPtrs->ExceptionRecord;
67 Context = ExceptPtrs->ContextRecord;
71 "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
75 ExceptRec->ExceptionCode,
76 ExceptRec->ExceptionAddress,
77 (void *)AFSExceptionFilter);
79 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
81 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
82 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
84 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
86 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
89 KeBugCheck( (ULONG)-2);
97 __except( EXCEPTION_EXECUTE_HANDLER)
103 return EXCEPTION_EXECUTE_HANDLER;
107 // Function: AFSLibExAllocatePoolWithTag()
109 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
110 // is configured on, then bugcheck the system if
111 // a memory allocation fails. The routine should be
112 // used for all memory allocations that are to be freed
113 // when the library is unloaded. Memory allocations that
114 // are to survive library unload and reload should be
115 // performed using AFSExAllocatePoolWithTag() which is
116 // provided by the AFS Framework.
119 // POOL_TYPE PoolType - Paged or NonPaged
120 // SIZE_T NumberOfBytes - requested allocation size
121 // ULONG Tag - Pool Allocation Tag to be applied for tracking
124 // void * - the memory allocation
128 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
129 IN SIZE_T NumberOfBytes,
133 void *pBuffer = NULL;
135 pBuffer = ExAllocatePoolWithTag( PoolType,
142 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
145 KeBugCheck( (ULONG)-2);
152 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
156 PsGetCurrentThread());
166 // Function: AFSAcquireExcl()
168 // Purpose: Called to acquire a resource exclusive with optional wait
171 // PERESOURCE Resource - Resource to acquire
172 // BOOLEAN Wait - Whether to block
175 // BOOLEAN - Whether the mask was acquired
179 AFSAcquireExcl( IN PERESOURCE Resource,
183 BOOLEAN bStatus = FALSE;
186 // Normal kernel APCs must be disabled before calling
187 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
190 KeEnterCriticalRegion();
192 bStatus = ExAcquireResourceExclusiveLite( Resource,
198 KeLeaveCriticalRegion();
205 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
209 BOOLEAN bStatus = FALSE;
211 KeEnterCriticalRegion();
213 bStatus = ExAcquireSharedStarveExclusive( Resource,
219 KeLeaveCriticalRegion();
226 // Function: AFSAcquireShared()
228 // Purpose: Called to acquire a resource shared with optional wait
231 // PERESOURCE Resource - Resource to acquire
232 // BOOLEAN Wait - Whether to block
235 // BOOLEAN - Whether the mask was acquired
239 AFSAcquireShared( IN PERESOURCE Resource,
243 BOOLEAN bStatus = FALSE;
245 KeEnterCriticalRegion();
247 bStatus = ExAcquireResourceSharedLite( Resource,
253 KeLeaveCriticalRegion();
260 // Function: AFSReleaseResource()
262 // Purpose: Called to release a resource
265 // PERESOURCE Resource - Resource to release
272 AFSReleaseResource( IN PERESOURCE Resource)
275 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
276 AFS_TRACE_LEVEL_VERBOSE,
277 "AFSReleaseResource Releasing lock %08lX Thread %08lX\n",
279 PsGetCurrentThread());
281 ExReleaseResourceLite( Resource);
283 KeLeaveCriticalRegion();
289 AFSConvertToShared( IN PERESOURCE Resource)
292 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
293 AFS_TRACE_LEVEL_VERBOSE,
294 "AFSConvertToShared Converting lock %08lX Thread %08lX\n",
296 PsGetCurrentThread());
298 ExConvertExclusiveToSharedLite( Resource);
304 // Function: AFSCompleteRequest
308 // This function completes irps
312 // A status is returned for the function
316 AFSCompleteRequest( IN PIRP Irp,
320 Irp->IoStatus.Status = Status;
322 IoCompleteRequest( Irp,
329 // Function: AFSGenerateCRC
333 // Given a device and filename this function generates a CRC
337 // A status is returned for the function
341 AFSGenerateCRC( IN PUNICODE_STRING FileName,
342 IN BOOLEAN UpperCaseName)
346 NTSTATUS ntStatus = STATUS_SUCCESS;
348 ntStatus = RtlHashUnicodeString( FileName,
350 HASH_STRING_ALGORITHM_DEFAULT,
353 if( !NT_SUCCESS( ntStatus))
362 AFSLockSystemBuffer( IN PIRP Irp,
366 NTSTATUS Status = STATUS_SUCCESS;
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 void *pMappedBuffer = NULL;
547 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
553 if( pDevExt->Specific.Control.ServiceProcess == NULL)
556 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
563 // Attach to the service process for mapping
566 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
567 (PRKAPC_STATE)&stApcState);
569 MmUnmapLockedPages( MappedBuffer,
572 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
584 AFSInitializeLibraryDevice()
587 NTSTATUS ntStatus = STATUS_SUCCESS;
588 AFSDeviceExt *pDeviceExt = NULL;
593 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
596 // The PIOCtl file name
599 RtlInitUnicodeString( &AFSPIOCtlName,
600 AFS_PIOCTL_FILE_INTERFACE_NAME);
603 // And the global root share name
606 RtlInitUnicodeString( &AFSGlobalRootName,
607 AFS_GLOBAL_ROOT_SHARE_NAME);
615 AFSRemoveLibraryDevice()
618 NTSTATUS ntStatus = STATUS_SUCCESS;
629 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
633 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
634 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
636 AFSCompleteRequest( Irp,
643 AFSInitializeGlobalDirectoryEntries()
646 NTSTATUS ntStatus = STATUS_SUCCESS;
647 AFSDirectoryCB *pDirNode = NULL;
648 ULONG ulEntryLength = 0;
649 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
650 AFSObjectInfoCB *pObjectInfoCB = NULL;
651 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
658 // Initialize the global . entry
661 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
664 if( pObjectInfoCB == NULL)
667 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
668 AFS_TRACE_LEVEL_ERROR,
669 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
672 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
675 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
677 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
678 AFS_TRACE_LEVEL_VERBOSE,
679 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
683 ntStatus = STATUS_SUCCESS;
685 ulEntryLength = sizeof( AFSDirectoryCB) +
688 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
692 if( pDirNode == NULL)
695 AFSDeleteObjectInfo( pObjectInfoCB);
697 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
698 AFS_TRACE_LEVEL_ERROR,
699 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
701 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
704 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
705 sizeof( AFSNonPagedDirectoryCB),
706 AFS_DIR_ENTRY_NP_TAG);
708 if( pNonPagedDirEntry == NULL)
711 ExFreePool( pDirNode);
713 AFSDeleteObjectInfo( pObjectInfoCB);
715 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
716 AFS_TRACE_LEVEL_ERROR,
717 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
719 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
722 RtlZeroMemory( pDirNode,
725 RtlZeroMemory( pNonPagedDirEntry,
726 sizeof( AFSNonPagedDirectoryCB));
728 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
730 pDirNode->NonPaged = pNonPagedDirEntry;
732 pDirNode->ObjectInformation = pObjectInfoCB;
738 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
740 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
743 // Setup the names in the entry
746 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
748 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
750 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
752 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
755 // Populate the rest of the data
758 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
760 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
762 AFSGlobalDotDirEntry = pDirNode;
768 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
771 if( pObjectInfoCB == NULL)
774 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
775 AFS_TRACE_LEVEL_ERROR,
776 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
779 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
782 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
784 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
785 AFS_TRACE_LEVEL_VERBOSE,
786 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
790 ntStatus = STATUS_SUCCESS;
792 ulEntryLength = sizeof( AFSDirectoryCB) +
793 ( 2 * sizeof( WCHAR));
795 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
799 if( pDirNode == NULL)
802 AFSDeleteObjectInfo( pObjectInfoCB);
804 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
807 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
808 sizeof( AFSNonPagedDirectoryCB),
809 AFS_DIR_ENTRY_NP_TAG);
811 if( pNonPagedDirEntry == NULL)
814 ExFreePool( pDirNode);
816 AFSDeleteObjectInfo( pObjectInfoCB);
818 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
821 RtlZeroMemory( pDirNode,
824 RtlZeroMemory( pNonPagedDirEntry,
825 sizeof( AFSNonPagedDirectoryCB));
827 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
829 pDirNode->NonPaged = pNonPagedDirEntry;
831 pDirNode->ObjectInformation = pObjectInfoCB;
837 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
839 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
842 // Setup the names in the entry
845 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
847 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
849 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
851 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
853 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
856 // Populate the rest of the data
859 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
861 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
863 AFSGlobalDotDotDirEntry = pDirNode;
867 if( !NT_SUCCESS( ntStatus))
870 if( AFSGlobalDotDirEntry != NULL)
873 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
875 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
877 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
879 ExFreePool( AFSGlobalDotDirEntry);
881 AFSGlobalDotDirEntry = NULL;
884 if( AFSGlobalDotDotDirEntry != NULL)
887 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
889 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
891 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
893 ExFreePool( AFSGlobalDotDotDirEntry);
895 AFSGlobalDotDotDirEntry = NULL;
904 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
905 IN PUNICODE_STRING FileName,
906 IN PUNICODE_STRING TargetName,
907 IN AFSDirEnumEntry *DirEnumEntry,
911 AFSDirectoryCB *pDirNode = NULL;
912 NTSTATUS ntStatus = STATUS_SUCCESS;
913 ULONG ulEntryLength = 0;
914 AFSDirEnumEntry *pDirEnumCB = NULL;
915 AFSFileID stTargetFileID;
917 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
918 AFSObjectInfoCB *pObjectInfoCB = NULL;
919 BOOLEAN bAllocatedObjectCB = FALSE;
920 ULONGLONG ullIndex = 0;
921 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
927 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
928 AFS_TRACE_LEVEL_VERBOSE,
929 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
931 ParentObjectInfo->FileId.Cell,
932 ParentObjectInfo->FileId.Volume,
933 ParentObjectInfo->FileId.Vnode,
934 ParentObjectInfo->FileId.Unique);
937 // First thing is to locate/create our object information block
941 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
944 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
946 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
948 (AFSBTreeEntry **)&pObjectInfoCB);
950 if( !NT_SUCCESS( ntStatus) ||
951 pObjectInfoCB == NULL)
955 // Allocate our object info cb
958 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
961 if( pObjectInfoCB == NULL)
964 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
966 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
969 bAllocatedObjectCB = TRUE;
971 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
972 AFS_TRACE_LEVEL_VERBOSE,
973 "AFSInitDirEntry initialized object %08lX Parent Object %08lX for %wZ\n",
979 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
981 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
982 AFS_TRACE_LEVEL_VERBOSE,
983 "AFSInitDirEntry Increment count on object %08lX Cnt %d\n",
987 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
989 ntStatus = STATUS_SUCCESS;
991 ulEntryLength = sizeof( AFSDirectoryCB) +
994 if( TargetName != NULL)
997 ulEntryLength += TargetName->Length;
1000 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1004 if( pDirNode == NULL)
1007 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1010 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1011 sizeof( AFSNonPagedDirectoryCB),
1012 AFS_DIR_ENTRY_NP_TAG);
1014 if( pNonPagedDirEntry == NULL)
1017 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1020 RtlZeroMemory( pDirNode,
1023 RtlZeroMemory( pNonPagedDirEntry,
1024 sizeof( AFSNonPagedDirectoryCB));
1026 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1028 pDirNode->NonPaged = pNonPagedDirEntry;
1030 pDirNode->ObjectInformation = pObjectInfoCB;
1033 // Set valid entry and NOT_IN_PARENT flag
1036 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1038 pDirNode->FileIndex = FileIndex;
1041 // Setup the names in the entry
1044 if( FileName->Length > 0)
1047 pDirNode->NameInformation.FileName.Length = FileName->Length;
1049 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1051 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1053 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1055 pDirNode->NameInformation.FileName.Length);
1058 // Create a CRC for the file
1061 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1064 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1068 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1069 AFS_TRACE_LEVEL_VERBOSE,
1070 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1073 ParentObjectInfo->FileId.Cell,
1074 ParentObjectInfo->FileId.Volume,
1075 ParentObjectInfo->FileId.Vnode,
1076 ParentObjectInfo->FileId.Unique);
1078 if( TargetName != NULL &&
1079 TargetName->Length > 0)
1082 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1084 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1086 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1087 sizeof( AFSDirectoryCB) +
1088 pDirNode->NameInformation.FileName.Length);
1090 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1092 pDirNode->NameInformation.TargetName.Length);
1096 // If we allocated the object information cb then update the information
1099 if( bAllocatedObjectCB)
1103 // Populate the rest of the data
1106 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1108 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1110 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1112 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1114 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1116 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1118 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1120 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1122 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1124 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1126 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1129 pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1132 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1133 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1136 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1139 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1142 // Object specific information
1145 pObjectInfoCB->Links = DirEnumEntry->Links;
1147 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1149 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1152 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1153 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1157 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1158 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1159 pObjectInfoCB->TargetFileId.Unique == 0 &&
1160 pDirNode->NameInformation.TargetName.Length == 0)
1164 // This will ensure we perform a validation on the node
1167 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1170 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1173 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1179 if( !NT_SUCCESS( ntStatus))
1182 if( pNonPagedDirEntry != NULL)
1185 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1187 AFSExFreePool( pNonPagedDirEntry);
1190 if( pDirNode != NULL)
1193 AFSExFreePool( pDirNode);
1199 // Dereference our object info block if we have one
1202 if( pObjectInfoCB != NULL)
1205 lCount = InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
1207 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1208 AFS_TRACE_LEVEL_VERBOSE,
1209 "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
1213 if( bAllocatedObjectCB)
1216 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1218 AFSDeleteObjectInfo( pObjectInfoCB);
1228 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1229 IN BOOLEAN DirectoryEntry)
1232 BOOLEAN bReturn = TRUE;
1233 ACCESS_MASK stAccessMask = 0;
1236 // Get rid of anything we don't know about
1239 DesiredAccess = (DesiredAccess &
1245 ACCESS_SYSTEM_SECURITY |
1249 FILE_READ_ATTRIBUTES |
1250 FILE_WRITE_ATTRIBUTES |
1251 FILE_LIST_DIRECTORY |
1257 // Our 'read only' access mask. These are the accesses we will
1258 // allow for a read only file
1261 stAccessMask = DELETE |
1266 ACCESS_SYSTEM_SECURITY |
1270 FILE_READ_ATTRIBUTES |
1271 FILE_WRITE_ATTRIBUTES |
1273 FILE_LIST_DIRECTORY |
1277 // For a directory, add in the directory specific accesses
1283 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1288 if( FlagOn( DesiredAccess, ~stAccessMask))
1292 // A write access is set ...
1302 AFSEvaluateNode( IN GUID *AuthGroup,
1303 IN AFSDirectoryCB *DirEntry)
1306 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1307 NTSTATUS ntStatus = STATUS_SUCCESS;
1308 AFSDirEnumEntry *pDirEntry = NULL;
1309 UNICODE_STRING uniTargetName;
1314 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1319 if( !NT_SUCCESS( ntStatus))
1322 try_return( ntStatus);
1325 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1327 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1329 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1331 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1333 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1335 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1337 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1339 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1341 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1343 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1345 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1347 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1350 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1353 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1354 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1357 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1360 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1362 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1365 // If we have a target name then see if it needs updating ...
1368 if( pDirEntry->TargetNameLength > 0)
1372 // Update the target name information if needed
1375 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1377 uniTargetName.MaximumLength = uniTargetName.Length;
1379 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1381 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1384 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1385 RtlCompareUnicodeString( &uniTargetName,
1386 &DirEntry->NameInformation.TargetName,
1391 // Update the target name
1394 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1396 uniTargetName.Buffer,
1397 uniTargetName.Length);
1399 if( !NT_SUCCESS( ntStatus))
1402 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1404 try_return( ntStatus);
1408 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1413 if( pDirEntry != NULL)
1416 AFSExFreePool( pDirEntry);
1424 AFSValidateSymLink( IN GUID *AuthGroup,
1425 IN AFSDirectoryCB *DirEntry)
1428 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1429 NTSTATUS ntStatus = STATUS_SUCCESS;
1430 AFSDirEnumEntry *pDirEntry = NULL;
1431 UNICODE_STRING uniTargetName;
1436 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1441 if( !NT_SUCCESS( ntStatus))
1444 try_return( ntStatus);
1447 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1448 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1451 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1454 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1456 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1458 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1461 // Update the target name information if needed
1464 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1466 uniTargetName.MaximumLength = uniTargetName.Length;
1468 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1470 if( uniTargetName.Length > 0)
1473 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1476 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1477 RtlCompareUnicodeString( &uniTargetName,
1478 &DirEntry->NameInformation.TargetName,
1483 // Update the target name
1486 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1488 uniTargetName.Buffer,
1489 uniTargetName.Length);
1491 if( !NT_SUCCESS( ntStatus))
1494 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1496 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1500 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1504 // If the FileType is the same then nothing to do since it IS
1508 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1511 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1513 try_return( ntStatus = STATUS_SUCCESS);
1516 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1518 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1520 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1522 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1524 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1526 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1528 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1530 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1532 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1535 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1538 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1539 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1542 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1545 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1547 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1551 if( pDirEntry != NULL)
1554 AFSExFreePool( pDirEntry);
1562 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1566 NTSTATUS ntStatus = STATUS_SUCCESS;
1567 IO_STATUS_BLOCK stIoStatus;
1570 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1571 AFS_TRACE_LEVEL_VERBOSE,
1572 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1573 (*ppObjectInfo)->FileType,
1574 (*ppObjectInfo)->FileId.Cell,
1575 (*ppObjectInfo)->FileId.Volume,
1576 (*ppObjectInfo)->FileId.Vnode,
1577 (*ppObjectInfo)->FileId.Unique,
1580 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1581 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1582 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1585 // We only act on the mount point itself, not the target. If the
1586 // node has been deleted then mark it as such otherwise indicate
1587 // it requires verification
1590 if( Reason == AFS_INVALIDATE_DELETED)
1592 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1597 if( Reason == AFS_INVALIDATE_FLUSHED)
1600 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1602 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1605 (*ppObjectInfo)->Expiration.QuadPart = 0;
1607 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1609 (*ppObjectInfo)->TargetFileId.Unique = 0;
1611 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1612 AFS_TRACE_LEVEL_VERBOSE,
1613 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1614 (*ppObjectInfo)->FileId.Cell,
1615 (*ppObjectInfo)->FileId.Volume,
1616 (*ppObjectInfo)->FileId.Vnode,
1617 (*ppObjectInfo)->FileId.Unique);
1619 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1622 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1624 if( Reason == AFS_INVALIDATE_CREDS)
1626 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1629 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1630 Reason == AFS_INVALIDATE_FLUSHED)
1632 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1636 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1639 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1642 FILE_ACTION_MODIFIED);
1644 try_return( ntStatus);
1648 // Depending on the reason for invalidation then perform work on the node
1654 case AFS_INVALIDATE_DELETED:
1658 // Mark this node as invalid
1661 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1663 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1664 AFS_TRACE_LEVEL_VERBOSE,
1665 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1666 (*ppObjectInfo)->FileId.Cell,
1667 (*ppObjectInfo)->FileId.Volume,
1668 (*ppObjectInfo)->FileId.Vnode,
1669 (*ppObjectInfo)->FileId.Unique);
1671 if( (*ppObjectInfo)->ParentObjectInformation != NULL)
1674 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1675 AFS_TRACE_LEVEL_VERBOSE,
1676 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1677 (*ppObjectInfo)->ParentObjectInformation->FileId.Cell,
1678 (*ppObjectInfo)->ParentObjectInformation->FileId.Volume,
1679 (*ppObjectInfo)->ParentObjectInformation->FileId.Vnode,
1680 (*ppObjectInfo)->ParentObjectInformation->FileId.Unique);
1682 SetFlag( (*ppObjectInfo)->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1684 (*ppObjectInfo)->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1686 (*ppObjectInfo)->ParentObjectInformation->Expiration.QuadPart = 0;
1689 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1691 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1695 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1698 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1701 FILE_ACTION_REMOVED);
1703 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1706 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1712 case AFS_INVALIDATE_FLUSHED:
1715 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1716 (*ppObjectInfo)->Fcb != NULL)
1719 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1720 AFS_TRACE_LEVEL_VERBOSE,
1721 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1722 (*ppObjectInfo)->FileId.Cell,
1723 (*ppObjectInfo)->FileId.Volume,
1724 (*ppObjectInfo)->FileId.Vnode,
1725 (*ppObjectInfo)->FileId.Unique);
1727 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1733 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1738 if( !NT_SUCCESS( stIoStatus.Status))
1741 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1742 AFS_TRACE_LEVEL_ERROR,
1743 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1744 (*ppObjectInfo)->FileId.Cell,
1745 (*ppObjectInfo)->FileId.Volume,
1746 (*ppObjectInfo)->FileId.Vnode,
1747 (*ppObjectInfo)->FileId.Unique,
1749 stIoStatus.Information);
1751 ntStatus = stIoStatus.Status;
1754 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1760 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1761 AFS_TRACE_LEVEL_WARNING,
1762 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1763 (*ppObjectInfo)->FileId.Cell,
1764 (*ppObjectInfo)->FileId.Volume,
1765 (*ppObjectInfo)->FileId.Vnode,
1766 (*ppObjectInfo)->FileId.Unique);
1768 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1771 __except( EXCEPTION_EXECUTE_HANDLER)
1774 ntStatus = GetExceptionCode();
1778 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1779 (*ppObjectInfo)->FileId.Cell,
1780 (*ppObjectInfo)->FileId.Volume,
1781 (*ppObjectInfo)->FileId.Vnode,
1782 (*ppObjectInfo)->FileId.Unique,
1785 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1788 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->Resource);
1791 // Clear out the extents
1792 // Get rid of them (note this involves waiting
1793 // for any writes or reads to the cache to complete)
1796 (VOID) AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1800 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1803 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1806 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1807 AFS_TRACE_LEVEL_VERBOSE,
1808 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1809 (*ppObjectInfo)->FileId.Cell,
1810 (*ppObjectInfo)->FileId.Volume,
1811 (*ppObjectInfo)->FileId.Vnode,
1812 (*ppObjectInfo)->FileId.Unique);
1814 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1817 // Fall through to the default processing
1823 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1825 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1829 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1832 if( Reason == AFS_INVALIDATE_CREDS)
1834 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1837 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1839 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1843 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1846 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1849 FILE_ACTION_MODIFIED);
1852 // Indicate this node requires re-evaluation for the remaining reasons
1855 (*ppObjectInfo)->Expiration.QuadPart = 0;
1857 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1858 AFS_TRACE_LEVEL_VERBOSE,
1859 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1860 (*ppObjectInfo)->FileId.Cell,
1861 (*ppObjectInfo)->FileId.Volume,
1862 (*ppObjectInfo)->FileId.Vnode,
1863 (*ppObjectInfo)->FileId.Unique);
1865 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1867 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1868 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1869 ( Reason == AFS_INVALIDATE_CALLBACK ||
1870 Reason == AFS_INVALIDATE_EXPIRED))
1872 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1873 AFS_INVALIDATE_DATA_VERSION)))
1876 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1890 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1893 NTSTATUS ntStatus = STATUS_SUCCESS;
1894 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1895 AFSVolumeCB *pVolumeCB = NULL;
1896 AFSFcb *pTargetDcb = NULL;
1897 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1898 AFSDirectoryCB *pCurrentDirEntry = NULL;
1899 BOOLEAN bIsChild = FALSE;
1900 ULONGLONG ullIndex = 0;
1901 AFSObjectInfoCB *pObjectInfo = NULL;
1907 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1908 AFS_TRACE_LEVEL_VERBOSE,
1909 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1910 InvalidateCB->FileID.Cell,
1911 InvalidateCB->FileID.Volume,
1912 InvalidateCB->FileID.Vnode,
1913 InvalidateCB->FileID.Unique,
1914 InvalidateCB->FileType,
1915 InvalidateCB->WholeVolume,
1916 InvalidateCB->Reason);
1919 // Need to locate the Fcb for the directory to purge
1922 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1923 AFS_TRACE_LEVEL_VERBOSE,
1924 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1925 &pDevExt->Specific.RDR.VolumeTreeLock,
1926 PsGetCurrentThread());
1929 // Starve any exclusive waiters on this paticular call
1932 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1935 // Locate the volume node
1938 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1940 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1942 (AFSBTreeEntry **)&pVolumeCB);
1944 if( pVolumeCB != NULL)
1947 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1949 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1950 AFS_TRACE_LEVEL_VERBOSE,
1951 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1956 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1958 if( !NT_SUCCESS( ntStatus) ||
1962 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1963 AFS_TRACE_LEVEL_WARNING,
1964 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1965 InvalidateCB->FileID.Cell,
1966 InvalidateCB->FileID.Volume,
1967 InvalidateCB->FileID.Vnode,
1968 InvalidateCB->FileID.Unique,
1971 try_return( ntStatus = STATUS_SUCCESS);
1975 // If this is a whole volume invalidation then go do it now
1978 if( InvalidateCB->WholeVolume)
1981 ntStatus = AFSInvalidateVolume( pVolumeCB,
1982 InvalidateCB->Reason);
1984 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1986 try_return( ntStatus);
1989 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1992 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
1995 pObjectInfo = &pVolumeCB->ObjectInformation;
2000 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2002 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2003 AFS_TRACE_LEVEL_VERBOSE,
2004 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
2006 pVolumeCB->VolumeReferenceCount);
2008 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2010 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2012 (AFSBTreeEntry **)&pObjectInfo);
2015 if( pObjectInfo != NULL)
2019 // Reference the node so it won't be torn down
2022 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
2024 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2025 AFS_TRACE_LEVEL_VERBOSE,
2026 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
2031 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2033 if( !NT_SUCCESS( ntStatus) ||
2034 pObjectInfo == NULL)
2037 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2038 AFS_TRACE_LEVEL_VERBOSE,
2039 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2040 InvalidateCB->FileID.Cell,
2041 InvalidateCB->FileID.Volume,
2042 InvalidateCB->FileID.Vnode,
2043 InvalidateCB->FileID.Unique,
2046 try_return( ntStatus = STATUS_SUCCESS);
2049 AFSInvalidateObject( &pObjectInfo,
2050 InvalidateCB->Reason);
2054 if( pObjectInfo != NULL)
2057 lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
2059 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2060 AFS_TRACE_LEVEL_VERBOSE,
2061 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
2071 AFSIsChildOfParent( IN AFSFcb *Dcb,
2075 BOOLEAN bIsChild = FALSE;
2076 AFSFcb *pCurrentFcb = Fcb;
2078 while( pCurrentFcb != NULL)
2081 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2089 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2097 AFSCreateHighIndex( IN AFSFileID *FileID)
2100 ULONGLONG ullIndex = 0;
2102 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2109 AFSCreateLowIndex( IN AFSFileID *FileID)
2112 ULONGLONG ullIndex = 0;
2114 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2120 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2121 IN ACCESS_MASK GrantedAccess,
2122 IN BOOLEAN DirectoryEntry)
2125 BOOLEAN bAccessGranted = TRUE;
2128 // Check if we are asking for read/write and granted only read only
2129 // NOTE: There will be more checks here
2132 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2134 AFSCheckForReadOnlyAccess( GrantedAccess,
2138 bAccessGranted = FALSE;
2141 return bAccessGranted;
2145 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2148 NTSTATUS ntStatus = STATUS_SUCCESS;
2149 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2155 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2157 if( AFSGlobalRoot == NULL)
2164 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2167 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2174 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2181 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2182 IN UNICODE_STRING *SubstituteName,
2183 IN ULONG StringIndex)
2186 NTSTATUS ntStatus = STATUS_SUCCESS;
2187 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2188 AFSSysNameCB *pSysName = NULL;
2189 ERESOURCE *pSysNameLock = NULL;
2192 UNICODE_STRING uniSysName;
2199 if( IoIs32bitProcess( NULL))
2202 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2204 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2209 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2211 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2215 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2217 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2221 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2222 AFS_TRACE_LEVEL_VERBOSE,
2223 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2225 PsGetCurrentThread());
2227 AFSAcquireShared( pSysNameLock,
2231 // Find where we are in the list
2234 while( pSysName != NULL &&
2235 ulIndex < StringIndex)
2238 pSysName = pSysName->fLink;
2243 if( pSysName == NULL)
2246 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2249 RtlInitUnicodeString( &uniSysName,
2252 // If it is a full component of @SYS then just substitue the
2256 if( RtlCompareUnicodeString( &uniSysName,
2261 SubstituteName->Length = pSysName->SysName.Length;
2262 SubstituteName->MaximumLength = SubstituteName->Length;
2264 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2265 SubstituteName->Length,
2266 AFS_SUBST_BUFFER_TAG);
2268 if( SubstituteName->Buffer == NULL)
2271 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2274 RtlCopyMemory( SubstituteName->Buffer,
2275 pSysName->SysName.Buffer,
2276 pSysName->SysName.Length);
2283 while( ComponentName->Buffer[ usIndex] != L'@')
2289 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2290 SubstituteName->MaximumLength = SubstituteName->Length;
2292 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2293 SubstituteName->Length,
2294 AFS_SUBST_BUFFER_TAG);
2296 if( SubstituteName->Buffer == NULL)
2299 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2302 RtlCopyMemory( SubstituteName->Buffer,
2303 ComponentName->Buffer,
2304 usIndex * sizeof( WCHAR));
2306 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2307 pSysName->SysName.Buffer,
2308 pSysName->SysName.Length);
2313 AFSReleaseResource( pSysNameLock);
2320 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2321 IN OUT UNICODE_STRING *ComponentName,
2322 IN UNICODE_STRING *SubstituteName,
2323 IN OUT UNICODE_STRING *RemainingPath,
2324 IN BOOLEAN FreePathName)
2327 NTSTATUS ntStatus = STATUS_SUCCESS;
2328 UNICODE_STRING uniPathName;
2329 USHORT usPrefixNameLen = 0;
2330 SHORT sNameLenDelta = 0;
2336 // If the passed in name can handle the additional length
2337 // then just moves things around
2340 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2342 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2344 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2347 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2350 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2351 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2352 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2355 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2356 SubstituteName->Buffer,
2357 SubstituteName->Length);
2359 FullPathName->Length += sNameLenDelta;
2361 ComponentName->Length += sNameLenDelta;
2363 ComponentName->MaximumLength = ComponentName->Length;
2365 if ( RemainingPath->Buffer)
2368 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2371 try_return( ntStatus);
2375 // Need to re-allocate the buffer
2378 uniPathName.Length = FullPathName->Length -
2379 ComponentName->Length +
2380 SubstituteName->Length;
2382 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2384 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2385 uniPathName.MaximumLength,
2386 AFS_NAME_BUFFER_FOUR_TAG);
2388 if( uniPathName.Buffer == NULL)
2391 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2394 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2396 usPrefixNameLen *= sizeof( WCHAR);
2398 RtlZeroMemory( uniPathName.Buffer,
2399 uniPathName.MaximumLength);
2401 RtlCopyMemory( uniPathName.Buffer,
2402 FullPathName->Buffer,
2405 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2406 SubstituteName->Buffer,
2407 SubstituteName->Length);
2409 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2412 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2413 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2414 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2417 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2419 ComponentName->Length += sNameLenDelta;
2421 ComponentName->MaximumLength = ComponentName->Length;
2423 if ( RemainingPath->Buffer)
2426 RemainingPath->Buffer = uniPathName.Buffer
2427 + (RemainingPath->Buffer - FullPathName->Buffer)
2428 + sNameLenDelta/sizeof( WCHAR);
2433 AFSExFreePool( FullPathName->Buffer);
2436 *FullPathName = uniPathName;
2447 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2451 NTSTATUS ntStatus = STATUS_SUCCESS;
2452 AFSObjectInfoCB *pCurrentObject = NULL;
2453 AFSObjectInfoCB *pNextObject = NULL;
2455 AFSFcb *pFcb = NULL;
2461 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2462 AFS_TRACE_LEVEL_VERBOSE,
2463 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2464 VolumeCB->ObjectInformation.FileId.Cell,
2465 VolumeCB->ObjectInformation.FileId.Volume,
2466 VolumeCB->ObjectInformation.FileId.Vnode,
2467 VolumeCB->ObjectInformation.FileId.Unique,
2471 // Depending on the reason for invalidation then perform work on the node
2477 case AFS_INVALIDATE_DELETED:
2481 // Mark this volume as invalid
2484 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2486 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2493 // Invalidate the volume root directory
2496 pCurrentObject = &VolumeCB->ObjectInformation;
2498 if ( pCurrentObject )
2501 lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
2503 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2504 AFS_TRACE_LEVEL_VERBOSE,
2505 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2509 AFSInvalidateObject( &pCurrentObject,
2512 if ( pCurrentObject)
2515 lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
2517 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2518 AFS_TRACE_LEVEL_VERBOSE,
2519 "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
2526 // Apply invalidation to all other volume objects
2529 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2532 pCurrentObject = VolumeCB->ObjectInfoListHead;
2534 if ( pCurrentObject)
2538 // Reference the node so it won't be torn down
2541 lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
2543 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2544 AFS_TRACE_LEVEL_VERBOSE,
2545 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2550 while( pCurrentObject != NULL)
2553 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2559 // Reference the node so it won't be torn down
2562 lCount = InterlockedIncrement( &pNextObject->ObjectReferenceCount);
2564 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2565 AFS_TRACE_LEVEL_VERBOSE,
2566 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2571 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2573 AFSInvalidateObject( &pCurrentObject,
2576 if ( pCurrentObject )
2579 lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
2581 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2582 AFS_TRACE_LEVEL_VERBOSE,
2583 "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
2588 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2591 pCurrentObject = pNextObject;
2594 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2601 AFSInvalidateAllVolumes( VOID)
2603 AFSVolumeCB *pVolumeCB = NULL;
2604 AFSVolumeCB *pNextVolumeCB = NULL;
2605 AFSDeviceExt *pRDRDeviceExt = NULL;
2608 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2610 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2611 AFS_TRACE_LEVEL_VERBOSE,
2612 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %08lX SHARED %08lX\n",
2613 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2614 PsGetCurrentThread());
2616 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2619 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2624 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2625 AFS_TRACE_LEVEL_VERBOSE,
2626 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %08lX SHARED %08lX\n",
2627 pVolumeCB->ObjectInfoTree.TreeLock,
2628 PsGetCurrentThread());
2630 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
2633 while( pVolumeCB != NULL)
2636 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2641 lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
2644 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2646 // do I need to hold the volume lock here?
2648 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2650 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2653 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2655 pVolumeCB = pNextVolumeCB;
2658 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2662 AFSVerifyEntry( IN GUID *AuthGroup,
2663 IN AFSDirectoryCB *DirEntry)
2666 NTSTATUS ntStatus = STATUS_SUCCESS;
2667 AFSDirEnumEntry *pDirEnumEntry = NULL;
2668 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2669 IO_STATUS_BLOCK stIoStatus;
2674 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2675 AFS_TRACE_LEVEL_VERBOSE_2,
2676 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2677 &DirEntry->NameInformation.FileName,
2678 pObjectInfo->FileId.Cell,
2679 pObjectInfo->FileId.Volume,
2680 pObjectInfo->FileId.Vnode,
2681 pObjectInfo->FileId.Unique);
2683 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2688 if( !NT_SUCCESS( ntStatus))
2691 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2692 AFS_TRACE_LEVEL_ERROR,
2693 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2694 &DirEntry->NameInformation.FileName,
2695 pObjectInfo->FileId.Cell,
2696 pObjectInfo->FileId.Volume,
2697 pObjectInfo->FileId.Vnode,
2698 pObjectInfo->FileId.Unique,
2701 try_return( ntStatus);
2705 // Check the data version of the file
2708 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2710 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2713 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2714 AFS_TRACE_LEVEL_VERBOSE,
2715 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2716 pObjectInfo->DataVersion.QuadPart,
2717 &DirEntry->NameInformation.FileName,
2718 pObjectInfo->FileId.Cell,
2719 pObjectInfo->FileId.Volume,
2720 pObjectInfo->FileId.Vnode,
2721 pObjectInfo->FileId.Unique);
2724 // We are ok, just get out
2727 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2729 try_return( ntStatus = STATUS_SUCCESS);
2734 // New data version so we will need to process the node based on the type
2737 switch( pDirEnumEntry->FileType)
2740 case AFS_FILE_TYPE_MOUNTPOINT:
2744 // For a mount point we need to ensure the target is the same
2747 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2748 &pDirEnumEntry->TargetFileId))
2754 // Update the metadata for the entry
2757 ntStatus = AFSUpdateMetaData( DirEntry,
2760 if( NT_SUCCESS( ntStatus))
2763 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2769 case AFS_FILE_TYPE_SYMLINK:
2772 ASSERT( pDirEnumEntry->TargetNameLength > 0);
2775 // Update the metadata for the entry
2778 ntStatus = AFSUpdateMetaData( DirEntry,
2781 if( NT_SUCCESS( ntStatus))
2784 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2790 case AFS_FILE_TYPE_FILE:
2792 FILE_OBJECT * pCCFileObject = NULL;
2793 BOOLEAN bPurgeExtents = FALSE;
2795 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
2798 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2799 AFS_TRACE_LEVEL_VERBOSE,
2800 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
2801 &DirEntry->NameInformation.FileName,
2802 pObjectInfo->FileId.Cell,
2803 pObjectInfo->FileId.Volume,
2804 pObjectInfo->FileId.Vnode,
2805 pObjectInfo->FileId.Unique,
2806 pObjectInfo->DataVersion.LowPart,
2807 pDirEnumEntry->DataVersion.LowPart
2810 bPurgeExtents = TRUE;
2813 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2816 bPurgeExtents = TRUE;
2818 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2819 AFS_TRACE_LEVEL_VERBOSE,
2820 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2821 &DirEntry->NameInformation.FileName,
2822 pObjectInfo->FileId.Cell,
2823 pObjectInfo->FileId.Volume,
2824 pObjectInfo->FileId.Vnode,
2825 pObjectInfo->FileId.Unique);
2827 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2830 if( pObjectInfo->Fcb != NULL)
2833 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2834 AFS_TRACE_LEVEL_VERBOSE,
2835 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2836 &DirEntry->NameInformation.FileName,
2837 pObjectInfo->FileId.Cell,
2838 pObjectInfo->FileId.Volume,
2839 pObjectInfo->FileId.Vnode,
2840 pObjectInfo->FileId.Unique);
2842 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2848 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2853 if( !NT_SUCCESS( stIoStatus.Status))
2856 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2857 AFS_TRACE_LEVEL_ERROR,
2858 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2859 &DirEntry->NameInformation.FileName,
2860 pObjectInfo->FileId.Cell,
2861 pObjectInfo->FileId.Volume,
2862 pObjectInfo->FileId.Vnode,
2863 pObjectInfo->FileId.Unique,
2865 stIoStatus.Information);
2867 ntStatus = stIoStatus.Status;
2873 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2879 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2880 AFS_TRACE_LEVEL_WARNING,
2881 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2882 &DirEntry->NameInformation.FileName,
2883 pObjectInfo->FileId.Cell,
2884 pObjectInfo->FileId.Volume,
2885 pObjectInfo->FileId.Vnode,
2886 pObjectInfo->FileId.Unique);
2888 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2892 __except( EXCEPTION_EXECUTE_HANDLER)
2894 ntStatus = GetExceptionCode();
2898 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2899 &DirEntry->NameInformation.FileName,
2900 pObjectInfo->FileId.Cell,
2901 pObjectInfo->FileId.Volume,
2902 pObjectInfo->FileId.Vnode,
2903 pObjectInfo->FileId.Unique,
2906 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2909 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2913 AFSFlushExtents( pObjectInfo->Fcb,
2918 // Reacquire the Fcb to purge the cache
2921 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2922 AFS_TRACE_LEVEL_VERBOSE,
2923 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2924 &pObjectInfo->Fcb->NPFcb->Resource,
2925 PsGetCurrentThread());
2927 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2931 // Update the metadata for the entry
2934 ntStatus = AFSUpdateMetaData( DirEntry,
2937 if( !NT_SUCCESS( ntStatus))
2940 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2941 AFS_TRACE_LEVEL_ERROR,
2942 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2943 &DirEntry->NameInformation.FileName,
2944 pObjectInfo->FileId.Cell,
2945 pObjectInfo->FileId.Volume,
2946 pObjectInfo->FileId.Vnode,
2947 pObjectInfo->FileId.Unique,
2954 // Update file sizes
2957 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2958 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2959 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2961 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2963 if ( pCCFileObject != NULL)
2965 CcSetFileSizes( pCCFileObject,
2966 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
2969 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2975 // Update the metadata for the entry
2978 ntStatus = AFSUpdateMetaData( DirEntry,
2981 if( !NT_SUCCESS( ntStatus))
2984 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2985 AFS_TRACE_LEVEL_ERROR,
2986 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2987 &DirEntry->NameInformation.FileName,
2988 pObjectInfo->FileId.Cell,
2989 pObjectInfo->FileId.Volume,
2990 pObjectInfo->FileId.Vnode,
2991 pObjectInfo->FileId.Unique,
2997 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2998 AFS_TRACE_LEVEL_WARNING,
2999 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3000 &DirEntry->NameInformation.FileName,
3001 pObjectInfo->FileId.Cell,
3002 pObjectInfo->FileId.Volume,
3003 pObjectInfo->FileId.Vnode,
3004 pObjectInfo->FileId.Unique);
3007 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3012 case AFS_FILE_TYPE_DIRECTORY:
3015 AFSFcb *pCurrentFcb = NULL;
3016 AFSDirectoryCB *pCurrentDirEntry = NULL;
3019 // For a directory or root entry flush the content of
3020 // the directory enumeration.
3023 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3026 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3027 AFS_TRACE_LEVEL_VERBOSE_2,
3028 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3029 &DirEntry->NameInformation.FileName,
3030 pObjectInfo->FileId.Cell,
3031 pObjectInfo->FileId.Volume,
3032 pObjectInfo->FileId.Vnode,
3033 pObjectInfo->FileId.Unique);
3035 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3038 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3041 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3043 if ( !NT_SUCCESS( ntStatus))
3046 try_return( ntStatus);
3051 // Update the metadata for the entry
3054 ntStatus = AFSUpdateMetaData( DirEntry,
3057 if( NT_SUCCESS( ntStatus))
3060 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3066 case AFS_FILE_TYPE_DFSLINK:
3069 UNICODE_STRING uniTargetName;
3072 // For a DFS link need to check the target name has not changed
3075 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3077 uniTargetName.MaximumLength = uniTargetName.Length;
3079 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3081 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3084 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3085 RtlCompareUnicodeString( &uniTargetName,
3086 &DirEntry->NameInformation.TargetName,
3091 // Update the target name
3094 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3096 uniTargetName.Buffer,
3097 uniTargetName.Length);
3099 if( !NT_SUCCESS( ntStatus))
3102 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3108 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3111 // Update the metadata for the entry
3114 ntStatus = AFSUpdateMetaData( DirEntry,
3117 if( NT_SUCCESS( ntStatus))
3120 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3128 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3129 AFS_TRACE_LEVEL_WARNING,
3130 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3131 pObjectInfo->FileType,
3132 &DirEntry->NameInformation.FileName,
3133 pObjectInfo->FileId.Cell,
3134 pObjectInfo->FileId.Volume,
3135 pObjectInfo->FileId.Vnode,
3136 pObjectInfo->FileId.Unique);
3143 if( pDirEnumEntry != NULL)
3146 AFSExFreePool( pDirEnumEntry);
3154 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3157 NTSTATUS ntStatus = STATUS_SUCCESS;
3158 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3159 ULONGLONG ullIndex = 0;
3160 AFSVolumeCB *pVolumeCB = NULL;
3161 AFSFcb *pFcb = NULL;
3162 AFSObjectInfoCB *pCurrentObject = NULL;
3168 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3169 AFS_TRACE_LEVEL_VERBOSE,
3170 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3171 VolumeStatus->Online,
3172 VolumeStatus->FileID.Cell,
3173 VolumeStatus->FileID.Volume);
3176 // Need to locate the Fcb for the directory to purge
3179 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3180 AFS_TRACE_LEVEL_VERBOSE,
3181 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3182 &pDevExt->Specific.RDR.VolumeTreeLock,
3183 PsGetCurrentThread());
3185 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3188 // Locate the volume node
3191 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3193 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3195 (AFSBTreeEntry **)&pVolumeCB);
3197 if( pVolumeCB != NULL)
3200 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3202 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3205 // Set the volume state accordingly
3208 if( VolumeStatus->Online)
3211 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3216 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3219 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3222 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3224 while( pCurrentObject != NULL)
3227 if( VolumeStatus->Online)
3230 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3232 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3234 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3239 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3242 pFcb = pCurrentObject->Fcb;
3245 !(VolumeStatus->Online) &&
3246 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3249 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3250 AFS_TRACE_LEVEL_ERROR,
3251 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3252 VolumeStatus->FileID.Cell,
3253 VolumeStatus->FileID.Volume);
3256 // Clear out the extents
3259 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3260 AFS_TRACE_LEVEL_VERBOSE,
3261 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3262 &pFcb->NPFcb->Specific.File.ExtentsResource,
3263 PsGetCurrentThread());
3265 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3268 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3270 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3274 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3275 AFS_TRACE_LEVEL_VERBOSE,
3276 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3277 &pFcb->NPFcb->Specific.File.ExtentsResource,
3278 PsGetCurrentThread());
3280 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3283 // And get rid of them (note this involves waiting
3284 // for any writes or reads to the cache to complete)
3287 (VOID) AFSTearDownFcbExtents( pFcb,
3291 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3294 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3296 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3301 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3309 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3312 NTSTATUS ntStatus = STATUS_SUCCESS;
3317 if( AFSGlobalRoot == NULL)
3320 try_return( ntStatus);
3323 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3327 // Set the network state according to the information
3330 if( NetworkStatus->Online)
3333 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3338 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3341 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3352 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3356 NTSTATUS ntStatus = STATUS_SUCCESS;
3357 BOOLEAN bAcquiredLock = FALSE;
3358 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3359 AFSFcb *pFcb = NULL;
3364 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3365 AFS_TRACE_LEVEL_VERBOSE,
3366 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3367 ObjectInfo->FileId.Cell,
3368 ObjectInfo->FileId.Volume,
3369 ObjectInfo->FileId.Vnode,
3370 ObjectInfo->FileId.Unique);
3372 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3375 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3376 AFS_TRACE_LEVEL_VERBOSE,
3377 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3378 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3379 PsGetCurrentThread());
3381 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3384 bAcquiredLock = TRUE;
3388 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3391 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3392 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3395 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3396 AFS_TRACE_LEVEL_ERROR,
3397 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
3398 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3399 ObjectInfo->FileId.Cell,
3400 ObjectInfo->FileId.Volume,
3401 ObjectInfo->FileId.Vnode,
3402 ObjectInfo->FileId.Unique);
3406 // Reset the directory list information by clearing all valid entries
3409 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3411 while( pCurrentDirEntry != NULL)
3414 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3416 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3420 // If this entry has been deleted then process it here
3423 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3424 pCurrentDirEntry->OpenReferenceCount == 0)
3427 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3428 AFS_TRACE_LEVEL_VERBOSE,
3429 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3431 &pCurrentDirEntry->NameInformation.FileName);
3433 AFSDeleteDirEntry( ObjectInfo,
3439 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3441 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3442 AFS_TRACE_LEVEL_VERBOSE,
3443 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3445 pCurrentDirEntry->OpenReferenceCount);
3448 // We pull the short name from the parent tree since it could change below
3451 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3454 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3455 AFS_TRACE_LEVEL_VERBOSE,
3456 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3458 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3459 &pCurrentDirEntry->NameInformation.FileName);
3461 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3464 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3469 pCurrentDirEntry = pNextDirEntry;
3473 // Reget the directory contents
3476 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3479 if ( !NT_SUCCESS( ntStatus))
3481 try_return( ntStatus);
3485 // Now start again and tear down any entries not valid
3488 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3490 while( pCurrentDirEntry != NULL)
3493 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3495 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3498 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3499 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3502 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3505 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3507 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3508 AFS_TRACE_LEVEL_VERBOSE,
3509 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3511 &pCurrentDirEntry->NameInformation.FileName);
3513 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3518 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3521 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3522 AFS_TRACE_LEVEL_VERBOSE,
3523 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3525 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3526 &pCurrentDirEntry->NameInformation.FileName);
3530 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3532 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3533 AFS_TRACE_LEVEL_VERBOSE,
3534 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3536 &pCurrentDirEntry->NameInformation.FileName);
3541 pCurrentDirEntry = pNextDirEntry;
3546 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3547 AFS_TRACE_LEVEL_VERBOSE,
3548 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3550 pCurrentDirEntry->OpenReferenceCount);
3552 if( pCurrentDirEntry->OpenReferenceCount == 0)
3555 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3556 AFS_TRACE_LEVEL_VERBOSE,
3557 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3558 &pCurrentDirEntry->NameInformation.FileName,
3559 ObjectInfo->FileId.Cell,
3560 ObjectInfo->FileId.Volume,
3561 ObjectInfo->FileId.Vnode,
3562 ObjectInfo->FileId.Unique);
3564 AFSDeleteDirEntry( ObjectInfo,
3570 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3571 AFS_TRACE_LEVEL_VERBOSE,
3572 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3574 &pCurrentDirEntry->NameInformation.FileName,
3575 ObjectInfo->FileId.Cell,
3576 ObjectInfo->FileId.Volume,
3577 ObjectInfo->FileId.Vnode,
3578 ObjectInfo->FileId.Unique);
3580 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3582 AFSRemoveNameEntry( ObjectInfo,
3586 pCurrentDirEntry = pNextDirEntry;
3590 if( !AFSValidateDirList( ObjectInfo))
3593 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3602 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3610 AFSIsVolumeFID( IN AFSFileID *FileID)
3613 BOOLEAN bIsVolume = FALSE;
3615 if( FileID->Vnode == 1 &&
3616 FileID->Unique == 1)
3626 AFSIsFinalNode( IN AFSFcb *Fcb)
3629 BOOLEAN bIsFinalNode = FALSE;
3631 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3632 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3633 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3634 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3635 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3638 bIsFinalNode = TRUE;
3643 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3644 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3647 return bIsFinalNode;
3651 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3652 IN AFSDirEnumEntry *DirEnumEntry)
3655 NTSTATUS ntStatus = STATUS_SUCCESS;
3656 UNICODE_STRING uniTargetName;
3657 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3662 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3664 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3666 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3668 pObjectInfo->FileType = DirEnumEntry->FileType;
3670 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3672 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3674 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3676 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3678 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3680 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3682 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3684 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3687 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3690 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3691 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3694 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3697 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3699 pObjectInfo->Links = DirEnumEntry->Links;
3701 if( DirEnumEntry->TargetNameLength > 0)
3705 // Update the target name information if needed
3708 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3710 uniTargetName.MaximumLength = uniTargetName.Length;
3712 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3714 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3717 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3718 RtlCompareUnicodeString( &uniTargetName,
3719 &DirEntry->NameInformation.TargetName,
3724 // Update the target name
3727 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3729 uniTargetName.Buffer,
3730 uniTargetName.Length);
3732 if( !NT_SUCCESS( ntStatus))
3735 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3737 try_return( ntStatus);
3741 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3743 else if( DirEntry->NameInformation.TargetName.Length > 0)
3746 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3749 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3750 DirEntry->NameInformation.TargetName.Buffer != NULL)
3752 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
3755 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3757 DirEntry->NameInformation.TargetName.Length = 0;
3758 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3759 DirEntry->NameInformation.TargetName.Buffer = NULL;
3761 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3773 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3775 IN BOOLEAN FastCall)
3778 NTSTATUS ntStatus = STATUS_SUCCESS;
3779 LARGE_INTEGER liSystemTime;
3780 AFSDirEnumEntry *pDirEnumEntry = NULL;
3781 AFSFcb *pCurrentFcb = NULL;
3782 BOOLEAN bReleaseFcb = FALSE;
3783 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3789 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3793 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3794 AFS_TRACE_LEVEL_VERBOSE_2,
3795 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3796 &DirEntry->NameInformation.FileName,
3797 pObjectInfo->FileId.Cell,
3798 pObjectInfo->FileId.Volume,
3799 pObjectInfo->FileId.Vnode,
3800 pObjectInfo->FileId.Unique,
3804 // If this is a fake node then bail since the service knows nothing about it
3807 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3810 try_return( ntStatus);
3814 // This routine ensures that the current entry is valid by:
3816 // 1) Checking that the expiration time is non-zero and after where we
3820 KeQuerySystemTime( &liSystemTime);
3822 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3823 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3824 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3825 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3828 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3829 AFS_TRACE_LEVEL_VERBOSE_2,
3830 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3831 &DirEntry->NameInformation.FileName,
3832 pObjectInfo->FileId.Cell,
3833 pObjectInfo->FileId.Volume,
3834 pObjectInfo->FileId.Vnode,
3835 pObjectInfo->FileId.Unique);
3837 try_return( ntStatus);
3841 // This node requires updating
3844 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3849 if( !NT_SUCCESS( ntStatus))
3852 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3853 AFS_TRACE_LEVEL_ERROR,
3854 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3856 &DirEntry->NameInformation.FileName,
3857 pObjectInfo->FileId.Cell,
3858 pObjectInfo->FileId.Volume,
3859 pObjectInfo->FileId.Vnode,
3860 pObjectInfo->FileId.Unique,
3864 // Failed validation of node so return access-denied
3867 try_return( ntStatus);
3870 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3871 AFS_TRACE_LEVEL_VERBOSE,
3872 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3874 &DirEntry->NameInformation.FileName,
3875 pObjectInfo->FileId.Cell,
3876 pObjectInfo->FileId.Volume,
3877 pObjectInfo->FileId.Vnode,
3878 pObjectInfo->FileId.Unique,
3879 pObjectInfo->DataVersion.QuadPart,
3880 pDirEnumEntry->DataVersion.QuadPart,
3881 pDirEnumEntry->FileType);
3885 // Based on the file type, process the node
3888 switch( pDirEnumEntry->FileType)
3891 case AFS_FILE_TYPE_MOUNTPOINT:
3895 // Update the metadata for the entry
3898 ntStatus = AFSUpdateMetaData( DirEntry,
3901 if( NT_SUCCESS( ntStatus))
3904 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3910 case AFS_FILE_TYPE_SYMLINK:
3911 case AFS_FILE_TYPE_DFSLINK:
3915 // Update the metadata for the entry
3918 ntStatus = AFSUpdateMetaData( DirEntry,
3921 if( NT_SUCCESS( ntStatus))
3924 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3930 case AFS_FILE_TYPE_FILE:
3934 // For a file where the data version has become invalid we need to
3935 // fail any current extent requests and purge the cache for the file
3936 // Can't hold the Fcb resource while doing this
3939 if( pObjectInfo->Fcb != NULL &&
3940 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3941 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3944 pCurrentFcb = pObjectInfo->Fcb;
3946 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3949 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3950 AFS_TRACE_LEVEL_VERBOSE,
3951 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3952 &pCurrentFcb->NPFcb->Resource,
3953 PsGetCurrentThread());
3955 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3961 if( pCurrentFcb != NULL)
3964 IO_STATUS_BLOCK stIoStatus;
3965 BOOLEAN bPurgeExtents = FALSE;
3967 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3968 AFS_TRACE_LEVEL_VERBOSE_2,
3969 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3970 &DirEntry->NameInformation.FileName,
3971 pObjectInfo->FileId.Cell,
3972 pObjectInfo->FileId.Volume,
3973 pObjectInfo->FileId.Vnode,
3974 pObjectInfo->FileId.Unique);
3976 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3979 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3980 AFS_TRACE_LEVEL_VERBOSE,
3981 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
3982 &DirEntry->NameInformation.FileName,
3983 pObjectInfo->FileId.Cell,
3984 pObjectInfo->FileId.Volume,
3985 pObjectInfo->FileId.Vnode,
3986 pObjectInfo->FileId.Unique,
3987 pObjectInfo->DataVersion.LowPart,
3988 pDirEnumEntry->DataVersion.LowPart
3991 bPurgeExtents = TRUE;
3994 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3996 bPurgeExtents = TRUE;
3998 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3999 AFS_TRACE_LEVEL_VERBOSE,
4000 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4001 &DirEntry->NameInformation.FileName,
4002 pObjectInfo->FileId.Cell,
4003 pObjectInfo->FileId.Volume,
4004 pObjectInfo->FileId.Vnode,
4005 pObjectInfo->FileId.Unique);
4007 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4013 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4018 if( !NT_SUCCESS( stIoStatus.Status))
4021 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4022 AFS_TRACE_LEVEL_ERROR,
4023 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4024 &DirEntry->NameInformation.FileName,
4025 pObjectInfo->FileId.Cell,
4026 pObjectInfo->FileId.Volume,
4027 pObjectInfo->FileId.Vnode,
4028 pObjectInfo->FileId.Unique,
4030 stIoStatus.Information);
4032 ntStatus = stIoStatus.Status;
4038 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4044 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4045 AFS_TRACE_LEVEL_WARNING,
4046 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4047 &DirEntry->NameInformation.FileName,
4048 pObjectInfo->FileId.Cell,
4049 pObjectInfo->FileId.Volume,
4050 pObjectInfo->FileId.Vnode,
4051 pObjectInfo->FileId.Unique);
4053 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4057 __except( EXCEPTION_EXECUTE_HANDLER)
4059 ntStatus = GetExceptionCode();
4063 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4064 &DirEntry->NameInformation.FileName,
4065 pObjectInfo->FileId.Cell,
4066 pObjectInfo->FileId.Volume,
4067 pObjectInfo->FileId.Vnode,
4068 pObjectInfo->FileId.Unique,
4071 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4074 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4076 bReleaseFcb = FALSE;
4080 AFSFlushExtents( pCurrentFcb,
4087 // Update the metadata for the entry
4090 ntStatus = AFSUpdateMetaData( DirEntry,
4093 if( !NT_SUCCESS( ntStatus))
4096 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4097 AFS_TRACE_LEVEL_ERROR,
4098 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4099 &DirEntry->NameInformation.FileName,
4100 pObjectInfo->FileId.Cell,
4101 pObjectInfo->FileId.Volume,
4102 pObjectInfo->FileId.Vnode,
4103 pObjectInfo->FileId.Unique,
4109 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4112 // Update file sizes
4115 if( pObjectInfo->Fcb != NULL)
4117 FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4119 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4120 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4121 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4123 if ( pCCFileObject != NULL)
4125 CcSetFileSizes( pCCFileObject,
4126 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4132 case AFS_FILE_TYPE_DIRECTORY:
4135 AFSDirectoryCB *pCurrentDirEntry = NULL;
4137 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4141 // For a directory or root entry flush the content of
4142 // the directory enumeration.
4145 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4146 AFS_TRACE_LEVEL_VERBOSE,
4147 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4148 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4149 PsGetCurrentThread());
4151 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4154 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4155 AFS_TRACE_LEVEL_VERBOSE_2,
4156 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4157 &DirEntry->NameInformation.FileName,
4158 pObjectInfo->FileId.Cell,
4159 pObjectInfo->FileId.Volume,
4160 pObjectInfo->FileId.Vnode,
4161 pObjectInfo->FileId.Unique);
4163 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4166 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4169 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4172 if( !NT_SUCCESS( ntStatus))
4175 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4176 AFS_TRACE_LEVEL_ERROR,
4177 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4178 &DirEntry->NameInformation.FileName,
4179 pObjectInfo->FileId.Cell,
4180 pObjectInfo->FileId.Volume,
4181 pObjectInfo->FileId.Vnode,
4182 pObjectInfo->FileId.Unique,
4190 // Update the metadata for the entry
4193 ntStatus = AFSUpdateMetaData( DirEntry,
4196 if( NT_SUCCESS( ntStatus))
4199 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4207 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4208 AFS_TRACE_LEVEL_WARNING,
4209 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4210 pObjectInfo->FileType,
4212 &DirEntry->NameInformation.FileName,
4213 pObjectInfo->FileId.Cell,
4214 pObjectInfo->FileId.Volume,
4215 pObjectInfo->FileId.Vnode,
4216 pObjectInfo->FileId.Unique);
4226 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4229 if( pDirEnumEntry != NULL)
4232 AFSExFreePool( pDirEnumEntry);
4240 AFSInitializeSpecialShareNameList()
4243 NTSTATUS ntStatus = STATUS_SUCCESS;
4244 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4245 AFSObjectInfoCB *pObjectInfoCB = NULL;
4246 UNICODE_STRING uniShareName;
4247 ULONG ulEntryLength = 0;
4248 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4253 RtlInitUnicodeString( &uniShareName,
4256 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4259 if( pObjectInfoCB == NULL)
4262 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4265 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4266 AFS_TRACE_LEVEL_VERBOSE,
4267 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
4270 pObjectInfoCB->ObjectReferenceCount = 1;
4272 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4274 ulEntryLength = sizeof( AFSDirectoryCB) +
4275 uniShareName.Length;
4277 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4281 if( pDirNode == NULL)
4284 AFSDeleteObjectInfo( pObjectInfoCB);
4286 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4289 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4290 sizeof( AFSNonPagedDirectoryCB),
4291 AFS_DIR_ENTRY_NP_TAG);
4293 if( pNonPagedDirEntry == NULL)
4296 ExFreePool( pDirNode);
4298 AFSDeleteObjectInfo( pObjectInfoCB);
4300 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4303 RtlZeroMemory( pDirNode,
4306 RtlZeroMemory( pNonPagedDirEntry,
4307 sizeof( AFSNonPagedDirectoryCB));
4309 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4311 pDirNode->NonPaged = pNonPagedDirEntry;
4313 pDirNode->ObjectInformation = pObjectInfoCB;
4319 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
4321 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4323 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4325 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4327 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4328 uniShareName.Buffer,
4329 pDirNode->NameInformation.FileName.Length);
4331 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4334 AFSSpecialShareNames = pDirNode;
4336 pLastDirNode = pDirNode;
4338 RtlInitUnicodeString( &uniShareName,
4341 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4344 if( pObjectInfoCB == NULL)
4347 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4350 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4351 AFS_TRACE_LEVEL_VERBOSE,
4352 "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
4355 pObjectInfoCB->ObjectReferenceCount = 1;
4357 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4359 ulEntryLength = sizeof( AFSDirectoryCB) +
4360 uniShareName.Length;
4362 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4366 if( pDirNode == NULL)
4369 AFSDeleteObjectInfo( pObjectInfoCB);
4371 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4374 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4375 sizeof( AFSNonPagedDirectoryCB),
4376 AFS_DIR_ENTRY_NP_TAG);
4378 if( pNonPagedDirEntry == NULL)
4381 ExFreePool( pDirNode);
4383 AFSDeleteObjectInfo( pObjectInfoCB);
4385 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4388 RtlZeroMemory( pDirNode,
4391 RtlZeroMemory( pNonPagedDirEntry,
4392 sizeof( AFSNonPagedDirectoryCB));
4394 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4396 pDirNode->NonPaged = pNonPagedDirEntry;
4398 pDirNode->ObjectInformation = pObjectInfoCB;
4404 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
4406 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4408 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4410 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4412 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4413 uniShareName.Buffer,
4414 pDirNode->NameInformation.FileName.Length);
4416 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4419 pLastDirNode->ListEntry.fLink = pDirNode;
4421 pDirNode->ListEntry.bLink = pLastDirNode;
4423 pLastDirNode = pDirNode;
4425 RtlInitUnicodeString( &uniShareName,
4428 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4431 if( pObjectInfoCB == NULL)
4434 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4437 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4438 AFS_TRACE_LEVEL_VERBOSE,
4439 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4442 pObjectInfoCB->ObjectReferenceCount = 1;
4444 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4446 ulEntryLength = sizeof( AFSDirectoryCB) +
4447 uniShareName.Length;
4449 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4453 if( pDirNode == NULL)
4456 AFSDeleteObjectInfo( pObjectInfoCB);
4458 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4461 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4462 sizeof( AFSNonPagedDirectoryCB),
4463 AFS_DIR_ENTRY_NP_TAG);
4465 if( pNonPagedDirEntry == NULL)
4468 ExFreePool( pDirNode);
4470 AFSDeleteObjectInfo( pObjectInfoCB);
4472 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4475 RtlZeroMemory( pDirNode,
4478 RtlZeroMemory( pNonPagedDirEntry,
4479 sizeof( AFSNonPagedDirectoryCB));
4481 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4483 pDirNode->NonPaged = pNonPagedDirEntry;
4485 pDirNode->ObjectInformation = pObjectInfoCB;
4491 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4493 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4495 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4497 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4499 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4500 uniShareName.Buffer,
4501 pDirNode->NameInformation.FileName.Length);
4503 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4506 pLastDirNode->ListEntry.fLink = pDirNode;
4508 pDirNode->ListEntry.bLink = pLastDirNode;
4512 if( !NT_SUCCESS( ntStatus))
4515 if( AFSSpecialShareNames != NULL)
4518 pDirNode = AFSSpecialShareNames;
4520 while( pDirNode != NULL)
4523 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4525 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4527 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4529 ExFreePool( pDirNode->NonPaged);
4531 ExFreePool( pDirNode);
4533 pDirNode = pLastDirNode;
4536 AFSSpecialShareNames = NULL;
4545 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4546 IN UNICODE_STRING *SecondaryName)
4549 AFSDirectoryCB *pDirectoryCB = NULL;
4550 ULONGLONG ullHash = 0;
4551 UNICODE_STRING uniFullShareName;
4557 // Build up the entire name here. We are guaranteed that if there is a
4558 // secondary name, it is pointing to a portion of the share name buffer
4561 if( SecondaryName->Length > 0 &&
4562 SecondaryName->Buffer != NULL)
4565 uniFullShareName = *SecondaryName;
4568 // The calling routine strips off the leading slash so add it back in
4571 uniFullShareName.Buffer--;
4572 uniFullShareName.Length += sizeof( WCHAR);
4573 uniFullShareName.MaximumLength += sizeof( WCHAR);
4576 // And the share name
4579 uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
4580 uniFullShareName.Length += ShareName->Length;
4581 uniFullShareName.MaximumLength += ShareName->Length;
4586 uniFullShareName = *ShareName;
4590 // Generate our hash value
4593 ullHash = AFSGenerateCRC( &uniFullShareName,
4597 // Loop through our special share names to see if this is one of them
4600 pDirectoryCB = AFSSpecialShareNames;
4602 while( pDirectoryCB != NULL)
4605 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4611 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4615 return pDirectoryCB;
4619 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4623 // Block on the queue flush event
4626 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4636 AFSWaitOnQueuedReleases()
4639 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4642 // Block on the queue flush event
4645 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4655 AFSIsEqualFID( IN AFSFileID *FileId1,
4656 IN AFSFileID *FileId2)
4659 BOOLEAN bIsEqual = FALSE;
4661 if( FileId1->Hash == FileId2->Hash &&
4662 FileId1->Unique == FileId2->Unique &&
4663 FileId1->Vnode == FileId2->Vnode &&
4664 FileId1->Volume == FileId2->Volume &&
4665 FileId1->Cell == FileId2->Cell)
4675 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4678 NTSTATUS ntStatus = STATUS_SUCCESS;
4679 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4684 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4687 // Reset the directory list information
4690 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4692 while( pCurrentDirEntry != NULL)
4695 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4697 if( pCurrentDirEntry->OpenReferenceCount == 0)
4700 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4701 AFS_TRACE_LEVEL_VERBOSE,
4702 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4704 &pCurrentDirEntry->NameInformation.FileName);
4706 AFSDeleteDirEntry( ObjectInfoCB,
4712 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4713 AFS_TRACE_LEVEL_VERBOSE,
4714 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4716 &pCurrentDirEntry->NameInformation.FileName);
4718 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4720 AFSRemoveNameEntry( ObjectInfoCB,
4724 pCurrentDirEntry = pNextDirEntry;
4727 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4729 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4731 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4733 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4735 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4737 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4739 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4740 AFS_TRACE_LEVEL_VERBOSE,
4741 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4742 ObjectInfoCB->FileId.Cell,
4743 ObjectInfoCB->FileId.Volume,
4744 ObjectInfoCB->FileId.Vnode,
4745 ObjectInfoCB->FileId.Unique);
4752 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4755 NTSTATUS ntStatus = STATUS_SUCCESS;
4756 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4757 UNICODE_STRING uniFullName;
4762 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4763 AFS_TRACE_LEVEL_VERBOSE,
4764 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4765 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4766 PsGetCurrentThread());
4768 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4771 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4774 try_return( ntStatus);
4778 // Initialize the root information
4781 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4784 // Enumerate the shares in the volume
4787 ntStatus = AFSEnumerateDirectory( AuthGroup,
4788 &AFSGlobalRoot->ObjectInformation,
4791 if( !NT_SUCCESS( ntStatus))
4794 try_return( ntStatus);
4797 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4800 // Indicate the node is initialized
4803 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4805 uniFullName.MaximumLength = PAGE_SIZE;
4806 uniFullName.Length = 0;
4808 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4809 uniFullName.MaximumLength,
4810 AFS_GENERIC_MEMORY_12_TAG);
4812 if( uniFullName.Buffer == NULL)
4816 // Reset the directory content
4819 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4821 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4823 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4827 // Populate our list of entries in the NP enumeration list
4830 while( pDirGlobalDirNode != NULL)
4833 uniFullName.Buffer[ 0] = L'\\';
4834 uniFullName.Buffer[ 1] = L'\\';
4836 uniFullName.Length = 2 * sizeof( WCHAR);
4838 RtlCopyMemory( &uniFullName.Buffer[ 2],
4839 AFSServerName.Buffer,
4840 AFSServerName.Length);
4842 uniFullName.Length += AFSServerName.Length;
4844 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4846 uniFullName.Length += sizeof( WCHAR);
4848 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4849 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4850 pDirGlobalDirNode->NameInformation.FileName.Length);
4852 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4854 AFSAddConnectionEx( &uniFullName,
4855 RESOURCEDISPLAYTYPE_SHARE,
4858 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4861 AFSExFreePool( uniFullName.Buffer);
4865 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4872 AFSIsRelativeName( IN UNICODE_STRING *Name)
4875 BOOLEAN bIsRelative = FALSE;
4877 if( Name->Buffer[ 0] != L'\\')
4887 AFSUpdateName( IN UNICODE_STRING *Name)
4892 while( usIndex < Name->Length/sizeof( WCHAR))
4895 if( Name->Buffer[ usIndex] == L'/')
4898 Name->Buffer[ usIndex] = L'\\';
4908 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4909 IN OUT ULONG *Flags,
4910 IN WCHAR *NameBuffer,
4911 IN USHORT NameLength)
4914 NTSTATUS ntStatus = STATUS_SUCCESS;
4915 WCHAR *pTmpBuffer = NULL;
4921 // If we have enough space then just move in the name otherwise
4922 // allocate a new buffer
4925 if( TargetName->Length < NameLength)
4928 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4930 AFS_NAME_BUFFER_FIVE_TAG);
4932 if( pTmpBuffer == NULL)
4935 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4938 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4941 AFSExFreePool( TargetName->Buffer);
4944 TargetName->MaximumLength = NameLength;
4946 TargetName->Buffer = pTmpBuffer;
4948 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4951 TargetName->Length = NameLength;
4953 RtlCopyMemory( TargetName->Buffer,
4955 TargetName->Length);
4958 // Update the name in the buffer
4961 AFSUpdateName( TargetName);
4972 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4973 IN ULONG InitialElementCount)
4976 AFSNameArrayHdr *pNameArray = NULL;
4977 AFSNameArrayCB *pCurrentElement = NULL;
4978 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4984 if( InitialElementCount == 0)
4987 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
4990 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
4991 sizeof( AFSNameArrayHdr) +
4992 (InitialElementCount * sizeof( AFSNameArrayCB)),
4993 AFS_NAME_ARRAY_TAG);
4995 if( pNameArray == NULL)
4998 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
4999 AFS_TRACE_LEVEL_ERROR,
5000 "AFSInitNameArray Failed to allocate name array\n");
5002 try_return( pNameArray);
5005 RtlZeroMemory( pNameArray,
5006 sizeof( AFSNameArrayHdr) +
5007 (InitialElementCount * sizeof( AFSNameArrayCB)));
5009 pNameArray->MaxElementCount = InitialElementCount;
5011 if( DirectoryCB != NULL)
5014 pCurrentElement = &pNameArray->ElementArray[ 0];
5016 pNameArray->CurrentEntry = pCurrentElement;
5018 pNameArray->Count = 1;
5020 pNameArray->LinkCount = 0;
5022 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5024 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5025 AFS_TRACE_LEVEL_VERBOSE,
5026 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
5027 &DirectoryCB->NameInformation.FileName,
5031 pCurrentElement->DirectoryCB = DirectoryCB;
5033 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5035 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5037 if( pCurrentElement->FileId.Vnode == 1)
5040 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5043 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5044 AFS_TRACE_LEVEL_VERBOSE,
5045 "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5047 pCurrentElement->DirectoryCB,
5048 pCurrentElement->FileId.Cell,
5049 pCurrentElement->FileId.Volume,
5050 pCurrentElement->FileId.Vnode,
5051 pCurrentElement->FileId.Unique,
5052 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5053 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5065 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
5066 IN UNICODE_STRING *Path,
5067 IN AFSDirectoryCB *DirectoryCB)
5070 NTSTATUS ntStatus = STATUS_SUCCESS;
5071 AFSNameArrayCB *pCurrentElement = NULL;
5072 UNICODE_STRING uniComponentName, uniRemainingPath;
5073 AFSObjectInfoCB *pCurrentObject = NULL;
5074 ULONG ulTotalCount = 0;
5076 USHORT usLength = 0;
5082 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5083 AFS_TRACE_LEVEL_VERBOSE,
5084 "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5088 DirectoryCB->ObjectInformation->FileId.Cell,
5089 DirectoryCB->ObjectInformation->FileId.Volume,
5090 DirectoryCB->ObjectInformation->FileId.Vnode,
5091 DirectoryCB->ObjectInformation->FileId.Unique,
5092 &DirectoryCB->NameInformation.FileName,
5093 DirectoryCB->ObjectInformation->FileType);
5096 // Init some info in the header
5099 pCurrentElement = &NameArray->ElementArray[ 0];
5101 NameArray->CurrentEntry = pCurrentElement;
5104 // The first entry points at the root
5107 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
5109 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5111 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5112 AFS_TRACE_LEVEL_VERBOSE,
5113 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
5114 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5115 pCurrentElement->DirectoryCB,
5118 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
5120 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
5122 pCurrentElement->Flags = 0;
5124 if( pCurrentElement->FileId.Vnode == 1)
5127 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5130 NameArray->Count = 1;
5132 NameArray->LinkCount = 0;
5134 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5135 AFS_TRACE_LEVEL_VERBOSE,
5136 "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5138 pCurrentElement->DirectoryCB,
5139 pCurrentElement->FileId.Cell,
5140 pCurrentElement->FileId.Volume,
5141 pCurrentElement->FileId.Vnode,
5142 pCurrentElement->FileId.Unique,
5143 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5144 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5147 // If the root is the parent then we are done ...
5150 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
5152 try_return( ntStatus);
5164 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
5165 IN AFSNameArrayHdr *RelatedNameArray,
5166 IN AFSDirectoryCB *DirectoryCB)
5169 NTSTATUS ntStatus = STATUS_SUCCESS;
5170 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
5171 UNICODE_STRING uniComponentName, uniRemainingPath;
5172 AFSObjectInfoCB *pObjectInfo = NULL;
5173 ULONG ulTotalCount = 0;
5175 USHORT usLength = 0;
5181 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5182 AFS_TRACE_LEVEL_VERBOSE,
5183 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5187 DirectoryCB->ObjectInformation->FileId.Cell,
5188 DirectoryCB->ObjectInformation->FileId.Volume,
5189 DirectoryCB->ObjectInformation->FileId.Vnode,
5190 DirectoryCB->ObjectInformation->FileId.Unique,
5191 &DirectoryCB->NameInformation.FileName,
5192 DirectoryCB->ObjectInformation->FileType);
5195 // Init some info in the header
5198 pCurrentElement = &NameArray->ElementArray[ 0];
5200 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5202 NameArray->Count = 0;
5204 NameArray->LinkCount = RelatedNameArray->LinkCount;
5207 // Populate the name array with the data from the related array
5213 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5215 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5217 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5219 pCurrentElement->Flags = 0;
5221 if( pCurrentElement->FileId.Vnode == 1)
5224 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5227 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5229 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5230 AFS_TRACE_LEVEL_VERBOSE,
5231 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
5232 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5233 pCurrentElement->DirectoryCB,
5236 lCount = InterlockedIncrement( &NameArray->Count);
5238 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5239 AFS_TRACE_LEVEL_VERBOSE,
5240 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5243 pCurrentElement->DirectoryCB,
5244 pCurrentElement->FileId.Cell,
5245 pCurrentElement->FileId.Volume,
5246 pCurrentElement->FileId.Vnode,
5247 pCurrentElement->FileId.Unique,
5248 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5249 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5251 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5252 NameArray->Count == RelatedNameArray->Count)
5264 pCurrentRelatedElement++;
5267 NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
5274 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5277 NTSTATUS ntStatus = STATUS_SUCCESS;
5278 AFSNameArrayCB *pCurrentElement = NULL;
5279 LONG lCount, lElement;
5284 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5285 AFS_TRACE_LEVEL_VERBOSE,
5286 "AFSFreeNameArray [NA:%p]\n",
5289 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5292 pCurrentElement = &NameArray->ElementArray[ lElement];
5294 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5296 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5297 AFS_TRACE_LEVEL_VERBOSE,
5298 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
5299 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5300 pCurrentElement->DirectoryCB,
5304 AFSExFreePool( NameArray);
5311 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5312 IN AFSDirectoryCB *DirectoryCB)
5315 NTSTATUS ntStatus = STATUS_SUCCESS;
5316 AFSNameArrayCB *pCurrentElement = NULL;
5322 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5323 AFS_TRACE_LEVEL_VERBOSE,
5324 "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5327 DirectoryCB->ObjectInformation->FileId.Cell,
5328 DirectoryCB->ObjectInformation->FileId.Volume,
5329 DirectoryCB->ObjectInformation->FileId.Vnode,
5330 DirectoryCB->ObjectInformation->FileId.Unique,
5331 &DirectoryCB->NameInformation.FileName,
5332 DirectoryCB->ObjectInformation->FileType);
5334 if( NameArray->Count == NameArray->MaxElementCount)
5337 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5338 AFS_TRACE_LEVEL_ERROR,
5339 "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
5342 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5345 for ( lCount = 0; lCount < NameArray->Count; lCount++)
5348 if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
5349 &DirectoryCB->ObjectInformation->FileId) )
5352 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5353 AFS_TRACE_LEVEL_WARNING,
5354 "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
5357 STATUS_ACCESS_DENIED);
5359 try_return( ntStatus = STATUS_ACCESS_DENIED);
5363 if( NameArray->Count > 0)
5366 NameArray->CurrentEntry++;
5370 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5373 pCurrentElement = NameArray->CurrentEntry;
5375 lCount = InterlockedIncrement( &NameArray->Count);
5377 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5379 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5380 AFS_TRACE_LEVEL_VERBOSE,
5381 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
5382 &DirectoryCB->NameInformation.FileName,
5386 pCurrentElement->DirectoryCB = DirectoryCB;
5388 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5390 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5392 pCurrentElement->Flags = 0;
5394 if( pCurrentElement->FileId.Vnode == 1)
5397 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5400 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5401 AFS_TRACE_LEVEL_VERBOSE,
5402 "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5404 NameArray->Count - 1,
5405 pCurrentElement->DirectoryCB,
5406 pCurrentElement->FileId.Cell,
5407 pCurrentElement->FileId.Volume,
5408 pCurrentElement->FileId.Vnode,
5409 pCurrentElement->FileId.Unique,
5410 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5411 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5422 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5425 AFSDirectoryCB *pDirectoryCB = NULL;
5426 AFSNameArrayCB *pCurrentElement = NULL;
5427 BOOLEAN bVolumeRoot = FALSE;
5433 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5434 AFS_TRACE_LEVEL_VERBOSE,
5435 "AFSBackupEntry [NA:%p]\n",
5438 if( NameArray->Count == 0)
5441 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5442 AFS_TRACE_LEVEL_ERROR,
5443 "AFSBackupEntry [NA:%p] No more entries\n",
5446 try_return( pCurrentElement);
5449 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5451 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5452 AFS_TRACE_LEVEL_VERBOSE,
5453 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5454 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5455 NameArray->CurrentEntry->DirectoryCB,
5458 NameArray->CurrentEntry->DirectoryCB = NULL;
5460 lCount = InterlockedDecrement( &NameArray->Count);
5464 NameArray->CurrentEntry = NULL;
5466 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5467 AFS_TRACE_LEVEL_ERROR,
5468 "AFSBackupEntry [NA:%p] No more entries\n",
5474 bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5476 NameArray->CurrentEntry--;
5478 pCurrentElement = NameArray->CurrentEntry;
5480 pDirectoryCB = pCurrentElement->DirectoryCB;
5482 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5483 AFS_TRACE_LEVEL_VERBOSE,
5484 "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5486 NameArray->Count - 1,
5487 pCurrentElement->DirectoryCB,
5488 pCurrentElement->FileId.Cell,
5489 pCurrentElement->FileId.Volume,
5490 pCurrentElement->FileId.Vnode,
5491 pCurrentElement->FileId.Unique,
5492 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5493 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5496 // If the entry we are removing is a volume root,
5497 // we must remove the mount point entry as well.
5498 // If the NameArray was constructed by checking the
5499 // share name via the service, the name array can
5500 // contain two volume roots in sequence without a
5501 // mount point separating them.
5505 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
5508 pDirectoryCB = AFSBackupEntry( NameArray);
5518 return pDirectoryCB;
5522 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5525 AFSDirectoryCB *pDirEntry = NULL;
5526 AFSNameArrayCB *pElement = NULL;
5531 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5532 AFS_TRACE_LEVEL_VERBOSE,
5533 "AFSGetParentEntry [NA:%p]\n",
5536 if( NameArray->Count == 0 ||
5537 NameArray->Count == 1)
5540 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5541 AFS_TRACE_LEVEL_ERROR,
5542 "AFSGetParentEntry [NA:%p] No more entries\n",
5545 try_return( pDirEntry = NULL);
5548 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5550 pDirEntry = pElement->DirectoryCB;
5552 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5553 AFS_TRACE_LEVEL_VERBOSE,
5554 "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5556 NameArray->Count - 2,
5557 pElement->DirectoryCB,
5558 pElement->FileId.Cell,
5559 pElement->FileId.Volume,
5560 pElement->FileId.Vnode,
5561 pElement->FileId.Unique,
5562 &pElement->DirectoryCB->NameInformation.FileName,
5563 pElement->DirectoryCB->ObjectInformation->FileType);
5574 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5575 IN AFSDirectoryCB *DirectoryCB)
5578 AFSNameArrayCB *pCurrentElement = NULL;
5579 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5580 LONG lCount, lElement;
5585 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5586 AFS_TRACE_LEVEL_VERBOSE,
5587 "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5590 DirectoryCB->ObjectInformation->FileId.Cell,
5591 DirectoryCB->ObjectInformation->FileId.Volume,
5592 DirectoryCB->ObjectInformation->FileId.Vnode,
5593 DirectoryCB->ObjectInformation->FileId.Unique,
5594 &DirectoryCB->NameInformation.FileName,
5595 DirectoryCB->ObjectInformation->FileType);
5597 // Dereference previous name array contents
5600 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5603 pCurrentElement = &NameArray->ElementArray[ lElement];
5605 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5607 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5608 AFS_TRACE_LEVEL_VERBOSE,
5609 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5610 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5611 pCurrentElement->DirectoryCB,
5615 RtlZeroMemory( NameArray,
5616 sizeof( AFSNameArrayHdr) +
5617 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5619 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5621 if( DirectoryCB != NULL)
5624 pCurrentElement = &NameArray->ElementArray[ 0];
5626 NameArray->CurrentEntry = pCurrentElement;
5628 NameArray->Count = 1;
5630 NameArray->LinkCount = 0;
5632 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5634 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5635 AFS_TRACE_LEVEL_VERBOSE,
5636 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5637 &DirectoryCB->NameInformation.FileName,
5641 pCurrentElement->DirectoryCB = DirectoryCB;
5643 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5645 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5647 pCurrentElement->Flags = 0;
5649 if( pCurrentElement->FileId.Vnode == 1)
5652 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5655 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5656 AFS_TRACE_LEVEL_VERBOSE,
5657 "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5659 pCurrentElement->DirectoryCB,
5660 pCurrentElement->FileId.Cell,
5661 pCurrentElement->FileId.Volume,
5662 pCurrentElement->FileId.Vnode,
5663 pCurrentElement->FileId.Unique,
5664 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5665 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5673 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5676 AFSNameArrayCB *pCurrentElement = NULL;
5678 pCurrentElement = &NameArray->ElementArray[ 0];
5680 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5682 while( pCurrentElement->DirectoryCB != NULL)
5685 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5686 pCurrentElement->FileId.Cell,
5687 pCurrentElement->FileId.Volume,
5688 pCurrentElement->FileId.Vnode,
5689 pCurrentElement->FileId.Unique,
5690 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5695 AFSPrint("AFSDumpNameArray End\n\n");
5701 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5706 // Depending on the type of node, set the event
5709 switch( Fcb->Header.NodeTypeCode)
5712 case AFS_DIRECTORY_FCB:
5717 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5727 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5733 // Depending on the type of node, set the event
5736 switch( Fcb->Header.NodeTypeCode)
5739 case AFS_DIRECTORY_FCB:
5744 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5746 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5756 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5759 BOOLEAN bIsInProcess = FALSE;
5764 if( ObjectInfo->Fcb == NULL)
5767 try_return( bIsInProcess);
5770 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5773 case AFS_DIRECTORY_FCB:
5778 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5781 bIsInProcess = TRUE;
5793 return bIsInProcess;
5797 AFSVerifyVolume( IN ULONGLONG ProcessId,
5798 IN AFSVolumeCB *VolumeCB)
5801 NTSTATUS ntStatus = STATUS_SUCCESS;
5808 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5811 NTSTATUS ntStatus = STATUS_SUCCESS;
5812 AFSObjectInfoCB *pObjectInfoCB = NULL;
5813 AFSDirectoryCB *pDirNode = NULL;
5814 ULONG ulEntryLength = 0;
5815 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5821 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5824 if( pObjectInfoCB == NULL)
5827 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5830 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5831 AFS_TRACE_LEVEL_VERBOSE,
5832 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5835 pObjectInfoCB->ObjectReferenceCount = 1;
5837 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5839 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5841 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5843 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5847 if( pDirNode == NULL)
5850 AFSDeleteObjectInfo( pObjectInfoCB);
5852 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5855 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5856 sizeof( AFSNonPagedDirectoryCB),
5857 AFS_DIR_ENTRY_NP_TAG);
5859 if( pNonPagedDirEntry == NULL)
5862 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5865 RtlZeroMemory( pDirNode,
5868 RtlZeroMemory( pNonPagedDirEntry,
5869 sizeof( AFSNonPagedDirectoryCB));
5871 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5873 pDirNode->NonPaged = pNonPagedDirEntry;
5875 pDirNode->ObjectInformation = pObjectInfoCB;
5877 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5883 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5885 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5887 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5889 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5891 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5892 AFSPIOCtlName.Buffer,
5893 pDirNode->NameInformation.FileName.Length);
5895 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5898 if ( InterlockedCompareExchangePointer( (PVOID *)&ObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5901 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5902 AFS_TRACE_LEVEL_WARNING,
5903 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %08lX pFcb %08lX\n",
5904 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5908 // Increment the open reference and handle on the node
5911 lCount = InterlockedIncrement( &pDirNode->ObjectInformation->ObjectReferenceCount);
5913 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
5914 AFS_TRACE_LEVEL_VERBOSE,
5915 "AFSInitPIOCtlDirectoryCB Increment count on Object %08lX Cnt %d\n",
5916 pDirNode->ObjectInformation,
5919 try_return( ntStatus = STATUS_REPARSE);
5924 if ( ntStatus != STATUS_SUCCESS)
5927 if ( pDirNode != NULL)
5930 AFSExFreePool( pDirNode);
5933 if ( pObjectInfoCB != NULL)
5936 AFSDeleteObjectInfo( pObjectInfoCB);
5945 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5946 IN AFSDirectoryCB *DirectoryCB,
5947 IN UNICODE_STRING *ParentPathName,
5948 IN AFSNameArrayHdr *RelatedNameArray,
5950 OUT AFSFileInfoCB *FileInfo)
5953 NTSTATUS ntStatus = STATUS_SUCCESS;
5954 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
5955 UNICODE_STRING uniFullPathName;
5956 AFSNameArrayHdr *pNameArray = NULL;
5957 AFSVolumeCB *pVolumeCB = NULL;
5958 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5959 WCHAR *pwchBuffer = NULL;
5960 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5961 ULONG ulNameDifference = 0;
5968 // Retrieve a target name for the entry
5971 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5974 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5977 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5979 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5984 if( !NT_SUCCESS( ntStatus) ||
5985 pDirEntry->TargetNameLength == 0)
5988 if( pDirEntry != NULL)
5991 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5994 try_return( ntStatus);
5997 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6000 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6004 // Update the target name
6007 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6008 &DirectoryCB->Flags,
6009 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6010 (USHORT)pDirEntry->TargetNameLength);
6012 if( !NT_SUCCESS( ntStatus))
6015 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6017 try_return( ntStatus);
6021 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6025 // Need to pass the full path in for parsing.
6028 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
6031 uniFullPathName.Length = 0;
6032 uniFullPathName.MaximumLength = ParentPathName->Length +
6034 DirectoryCB->NameInformation.TargetName.Length;
6036 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6037 uniFullPathName.MaximumLength,
6038 AFS_NAME_BUFFER_SIX_TAG);
6040 if( uniFullPathName.Buffer == NULL)
6043 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6045 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6048 pwchBuffer = uniFullPathName.Buffer;
6050 RtlZeroMemory( uniFullPathName.Buffer,
6051 uniFullPathName.MaximumLength);
6053 RtlCopyMemory( uniFullPathName.Buffer,
6054 ParentPathName->Buffer,
6055 ParentPathName->Length);
6057 uniFullPathName.Length = ParentPathName->Length;
6059 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
6060 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
6063 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
6065 uniFullPathName.Length += sizeof( WCHAR);
6068 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
6069 DirectoryCB->NameInformation.TargetName.Buffer,
6070 DirectoryCB->NameInformation.TargetName.Length);
6072 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
6074 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
6075 uniParsedName.MaximumLength = uniParsedName.Length;
6077 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
6079 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6082 // We populate up to the current parent
6085 if( RelatedNameArray != NULL)
6088 pNameArray = AFSInitNameArray( NULL,
6089 RelatedNameArray->MaxElementCount);
6091 if( pNameArray == NULL)
6094 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6097 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
6104 pNameArray = AFSInitNameArray( NULL,
6107 if( pNameArray == NULL)
6110 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6113 ntStatus = AFSPopulateNameArray( pNameArray,
6118 if( !NT_SUCCESS( ntStatus))
6121 try_return( ntStatus);
6124 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
6126 pParentDirEntry = ParentDirectoryCB;
6131 uniFullPathName.Length = 0;
6132 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6134 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6135 uniFullPathName.MaximumLength,
6136 AFS_NAME_BUFFER_SEVEN_TAG);
6138 if( uniFullPathName.Buffer == NULL)
6141 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6143 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6146 pwchBuffer = uniFullPathName.Buffer;
6148 RtlZeroMemory( uniFullPathName.Buffer,
6149 uniFullPathName.MaximumLength);
6151 RtlCopyMemory( uniFullPathName.Buffer,
6152 DirectoryCB->NameInformation.TargetName.Buffer,
6153 DirectoryCB->NameInformation.TargetName.Length);
6155 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6158 // This name should begin with the \afs server so parse it off and check it
6161 FsRtlDissectName( uniFullPathName,
6165 if( RtlCompareUnicodeString( &uniComponentName,
6170 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6172 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6173 AFS_TRACE_LEVEL_ERROR,
6174 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
6177 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
6180 uniFullPathName = uniRemainingPath;
6182 uniParsedName = uniFullPathName;
6184 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6186 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6192 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6195 if( pNameArray == NULL)
6198 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6201 pVolumeCB = AFSGlobalRoot;
6203 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6207 // Increment the ref count on the volume and dir entry for correct processing below
6210 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6212 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6213 AFS_TRACE_LEVEL_VERBOSE,
6214 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
6218 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6220 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6221 AFS_TRACE_LEVEL_VERBOSE,
6222 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6223 &pParentDirEntry->NameInformation.FileName,
6228 ntStatus = AFSLocateNameEntry( NULL,
6233 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
6239 if( !NT_SUCCESS( ntStatus))
6243 // The volume lock was released on failure above
6244 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6247 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6250 if( pVolumeCB != NULL)
6253 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6255 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6256 AFS_TRACE_LEVEL_VERBOSE,
6257 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
6262 if( pDirectoryEntry != NULL)
6265 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6267 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6268 AFS_TRACE_LEVEL_VERBOSE,
6269 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6270 &pDirectoryEntry->NameInformation.FileName,
6278 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6280 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6281 AFS_TRACE_LEVEL_VERBOSE,
6282 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6283 &pParentDirEntry->NameInformation.FileName,
6292 try_return( ntStatus);
6296 // Store off the information
6299 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6302 // Check for the mount point being returned
6305 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
6308 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6310 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
6311 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6314 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6317 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6322 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6326 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6328 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6330 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6332 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6334 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6336 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6339 // Remove the reference made above
6342 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6344 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6345 AFS_TRACE_LEVEL_VERBOSE,
6346 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
6347 &pDirectoryEntry->NameInformation.FileName,
6354 if( pDirEntry != NULL)
6357 AFSExFreePool( pDirEntry);
6360 if( pVolumeCB != NULL)
6363 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6365 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6366 AFS_TRACE_LEVEL_VERBOSE,
6367 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
6372 if( pNameArray != NULL)
6375 AFSFreeNameArray( pNameArray);
6378 if( pwchBuffer != NULL)
6382 // Always free the buffer that we allocated as AFSLocateNameEntry
6383 // will not free it. If uniFullPathName.Buffer was allocated by
6384 // AFSLocateNameEntry, then we must free that as well.
6385 // Check that the uniFullPathName.Buffer in the string is not the same
6386 // offset by the length of the server name
6389 if( uniFullPathName.Length > 0 &&
6390 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6393 AFSExFreePool( uniFullPathName.Buffer);
6396 AFSExFreePool( pwchBuffer);
6404 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6405 IN ULONGLONG HashIndex)
6408 NTSTATUS ntStatus = STATUS_SUCCESS;
6409 AFSObjectInfoCB *pObjectInfo = NULL;
6415 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6416 sizeof( AFSObjectInfoCB),
6417 AFS_OBJECT_INFO_TAG);
6419 if( pObjectInfo == NULL)
6422 try_return( pObjectInfo);
6425 RtlZeroMemory( pObjectInfo,
6426 sizeof( AFSObjectInfoCB));
6428 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6429 sizeof( AFSNonPagedObjectInfoCB),
6430 AFS_NP_OBJECT_INFO_TAG);
6432 if( pObjectInfo->NonPagedInfo == NULL)
6435 AFSExFreePool( pObjectInfo);
6437 try_return( pObjectInfo = NULL);
6440 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6442 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6444 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6446 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6448 if( ParentObjectInfo != NULL)
6450 lCount = InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
6454 // Initialize the access time
6457 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6463 // Insert the entry into the object tree and list
6466 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6468 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6471 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6476 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6477 &pObjectInfo->TreeEntry);
6479 ASSERT( NT_SUCCESS( ntStatus));
6483 // And the object list in the volume
6486 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6489 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6494 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6496 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6499 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6502 // Indicate the object is in the hash tree and linked list in the volume
6505 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6517 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6520 BOOLEAN bAcquiredTreeLock = FALSE;
6523 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6526 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6528 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6531 bAcquiredTreeLock = TRUE;
6535 // Remove it from the tree and list if it was inserted
6538 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6541 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6542 &ObjectInfo->TreeEntry);
6545 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6548 if( ObjectInfo->ListEntry.fLink == NULL)
6551 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6553 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6556 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6562 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6565 if( ObjectInfo->ListEntry.bLink == NULL)
6568 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6570 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6573 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6579 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6583 if( ObjectInfo->ParentObjectInformation != NULL)
6586 lCount = InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
6589 if( bAcquiredTreeLock)
6592 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6596 // Release the fid in the service
6599 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6602 AFSReleaseFid( &ObjectInfo->FileId);
6605 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6607 AFSExFreePool( ObjectInfo->NonPagedInfo);
6609 AFSExFreePool( ObjectInfo);
6615 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6616 OUT AFSDirectoryCB **TargetDirEntry)
6619 NTSTATUS ntStatus = STATUS_SUCCESS;
6620 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6621 UNICODE_STRING uniFullPathName;
6622 AFSNameArrayHdr *pNameArray = NULL;
6623 AFSVolumeCB *pVolumeCB = NULL;
6624 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6625 WCHAR *pwchBuffer = NULL;
6626 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6627 ULONG ulNameDifference = 0;
6634 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6635 DirectoryCB->ObjectInformation,
6639 if( !NT_SUCCESS( ntStatus))
6641 try_return( ntStatus);
6645 // Retrieve a target name for the entry
6648 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6651 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6654 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6656 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6661 if( !NT_SUCCESS( ntStatus) ||
6662 pDirEntry->TargetNameLength == 0)
6665 if( pDirEntry != NULL)
6668 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6671 try_return( ntStatus);
6674 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6677 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6681 // Update the target name
6684 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6685 &DirectoryCB->Flags,
6686 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6687 (USHORT)pDirEntry->TargetNameLength);
6689 if( !NT_SUCCESS( ntStatus))
6692 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6694 try_return( ntStatus);
6698 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6702 // Need to pass the full path in for parsing.
6705 uniFullPathName.Length = 0;
6706 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6708 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6709 uniFullPathName.MaximumLength,
6710 AFS_NAME_BUFFER_EIGHT_TAG);
6712 if( uniFullPathName.Buffer == NULL)
6715 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6717 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6720 pwchBuffer = uniFullPathName.Buffer;
6722 RtlZeroMemory( uniFullPathName.Buffer,
6723 uniFullPathName.MaximumLength);
6725 RtlCopyMemory( uniFullPathName.Buffer,
6726 DirectoryCB->NameInformation.TargetName.Buffer,
6727 DirectoryCB->NameInformation.TargetName.Length);
6729 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6732 // This name should begin with the \afs server so parse it off and chech it
6735 FsRtlDissectName( uniFullPathName,
6739 if( RtlCompareUnicodeString( &uniComponentName,
6745 // Try evaluating the full path
6748 uniFullPathName.Buffer = pwchBuffer;
6750 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6752 uniFullPathName.MaximumLength = uniFullPathName.Length;
6757 uniFullPathName = uniRemainingPath;
6760 uniParsedName = uniFullPathName;
6762 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6764 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6770 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6773 if( pNameArray == NULL)
6776 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6779 pVolumeCB = AFSGlobalRoot;
6781 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6783 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6785 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6786 AFS_TRACE_LEVEL_VERBOSE,
6787 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6791 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6793 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6794 AFS_TRACE_LEVEL_VERBOSE,
6795 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6796 &pParentDirEntry->NameInformation.FileName,
6801 ntStatus = AFSLocateNameEntry( NULL,
6812 if( !NT_SUCCESS( ntStatus))
6816 // The volume lock was released on failure above
6817 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6820 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6823 if( pVolumeCB != NULL)
6826 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6828 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6829 AFS_TRACE_LEVEL_VERBOSE,
6830 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
6835 if( pDirectoryEntry != NULL)
6838 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6840 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6841 AFS_TRACE_LEVEL_VERBOSE,
6842 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6843 &pDirectoryEntry->NameInformation.FileName,
6851 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6853 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6854 AFS_TRACE_LEVEL_VERBOSE,
6855 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6856 &pParentDirEntry->NameInformation.FileName,
6865 try_return( ntStatus);
6869 // Pass back the target dir entry for this request
6872 *TargetDirEntry = pDirectoryEntry;
6876 if( pDirEntry != NULL)
6879 AFSExFreePool( pDirEntry);
6882 if( pVolumeCB != NULL)
6885 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6887 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6888 AFS_TRACE_LEVEL_VERBOSE,
6889 "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
6894 if( pNameArray != NULL)
6897 AFSFreeNameArray( pNameArray);
6900 if( pwchBuffer != NULL)
6904 // Always free the buffer that we allocated as AFSLocateNameEntry
6905 // will not free it. If uniFullPathName.Buffer was allocated by
6906 // AFSLocateNameEntry, then we must free that as well.
6907 // Check that the uniFullPathName.Buffer in the string is not the same
6908 // offset by the length of the server name
6911 if( uniFullPathName.Length > 0 &&
6912 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6915 AFSExFreePool( uniFullPathName.Buffer);
6918 AFSExFreePool( pwchBuffer);
6926 AFSCleanupFcb( IN AFSFcb *Fcb,
6927 IN BOOLEAN ForceFlush)
6930 NTSTATUS ntStatus = STATUS_SUCCESS;
6931 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6932 LARGE_INTEGER liTime;
6933 IO_STATUS_BLOCK stIoStatus;
6938 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6940 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6942 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6945 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6946 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6949 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6952 if( Fcb->OpenReferenceCount > 0)
6958 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6963 if( !NT_SUCCESS( stIoStatus.Status))
6966 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6967 AFS_TRACE_LEVEL_ERROR,
6968 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6969 Fcb->ObjectInformation->FileId.Cell,
6970 Fcb->ObjectInformation->FileId.Volume,
6971 Fcb->ObjectInformation->FileId.Vnode,
6972 Fcb->ObjectInformation->FileId.Unique,
6974 stIoStatus.Information);
6976 ntStatus = stIoStatus.Status;
6979 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6985 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6986 AFS_TRACE_LEVEL_WARNING,
6987 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
6988 Fcb->ObjectInformation->FileId.Cell,
6989 Fcb->ObjectInformation->FileId.Volume,
6990 Fcb->ObjectInformation->FileId.Vnode,
6991 Fcb->ObjectInformation->FileId.Unique);
6993 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6996 __except( EXCEPTION_EXECUTE_HANDLER)
6999 ntStatus = GetExceptionCode();
7003 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7004 Fcb->ObjectInformation->FileId.Cell,
7005 Fcb->ObjectInformation->FileId.Volume,
7006 Fcb->ObjectInformation->FileId.Vnode,
7007 Fcb->ObjectInformation->FileId.Unique,
7010 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7014 AFSReleaseResource( &Fcb->NPFcb->Resource);
7017 // Wait for any currently running flush or release requests to complete
7020 AFSWaitOnQueuedFlushes( Fcb);
7023 // Now perform another flush on the file
7026 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7030 AFSReleaseExtentsWithFlush( Fcb,
7035 if( Fcb->OpenReferenceCount == 0 ||
7036 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7037 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7040 AFSTearDownFcbExtents( Fcb,
7044 try_return( ntStatus);
7047 KeQueryTickCount( &liTime);
7050 // First up are there dirty extents in the cache to flush?
7053 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7054 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7058 // The file has been marked as invalid. Dump it
7061 AFSTearDownFcbExtents( Fcb,
7064 else if( ForceFlush ||
7065 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7066 Fcb->Specific.File.ExtentCount) &&
7067 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7068 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7070 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7072 Fcb->OpenReferenceCount == 0)
7075 AFSReleaseExtentsWithFlush( Fcb,
7081 // If there are extents and they haven't been used recently *and*
7082 // are not being used
7086 ( 0 != Fcb->Specific.File.ExtentCount &&
7087 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7088 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7089 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
7090 AFSAcquireExcl( &Fcb->NPFcb->Resource,
7097 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7102 if( !NT_SUCCESS( stIoStatus.Status))
7105 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7106 AFS_TRACE_LEVEL_ERROR,
7107 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7108 Fcb->ObjectInformation->FileId.Cell,
7109 Fcb->ObjectInformation->FileId.Volume,
7110 Fcb->ObjectInformation->FileId.Vnode,
7111 Fcb->ObjectInformation->FileId.Unique,
7113 stIoStatus.Information);
7115 ntStatus = stIoStatus.Status;
7121 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7127 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7128 AFS_TRACE_LEVEL_WARNING,
7129 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7130 Fcb->ObjectInformation->FileId.Cell,
7131 Fcb->ObjectInformation->FileId.Volume,
7132 Fcb->ObjectInformation->FileId.Vnode,
7133 Fcb->ObjectInformation->FileId.Unique);
7135 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7139 __except( EXCEPTION_EXECUTE_HANDLER)
7142 ntStatus = GetExceptionCode();
7146 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7147 Fcb->ObjectInformation->FileId.Cell,
7148 Fcb->ObjectInformation->FileId.Volume,
7149 Fcb->ObjectInformation->FileId.Vnode,
7150 Fcb->ObjectInformation->FileId.Unique,
7154 AFSReleaseResource( &Fcb->NPFcb->Resource);
7156 if( Fcb->OpenReferenceCount == 0)
7160 // Tear em down we'll not be needing them again
7163 AFSTearDownFcbExtents( Fcb,
7177 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7178 IN UNICODE_STRING *NewFileName)
7181 NTSTATUS ntStatus = STATUS_SUCCESS;
7182 WCHAR *pTmpBuffer = NULL;
7187 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7190 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7193 AFSExFreePool( DirectoryCB->NameInformation.FileName.Buffer);
7195 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7197 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7201 // OK, we need to allocate a new name buffer
7204 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7205 NewFileName->Length,
7206 AFS_NAME_BUFFER_NINE_TAG);
7208 if( pTmpBuffer == NULL)
7211 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7214 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7216 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7218 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7221 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7223 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7224 NewFileName->Buffer,
7225 NewFileName->Length);
7236 AFSReadCacheFile( IN void *ReadBuffer,
7237 IN LARGE_INTEGER *ReadOffset,
7238 IN ULONG RequestedDataLength,
7239 IN OUT PULONG BytesRead)
7242 NTSTATUS ntStatus = STATUS_SUCCESS;
7245 PIO_STACK_LOCATION pIoStackLocation = NULL;
7246 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7247 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7248 FILE_OBJECT *pCacheFileObject = NULL;
7253 pCacheFileObject = AFSReferenceCacheFileObject();
7255 if( pCacheFileObject == NULL)
7257 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7260 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7263 // Initialize the event
7266 KeInitializeEvent( &kEvent,
7267 SynchronizationEvent,
7271 // Allocate an irp for this request. This could also come from a
7272 // private pool, for instance.
7275 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7281 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7285 // Build the IRP's main body
7288 pIrp->UserBuffer = ReadBuffer;
7290 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7291 pIrp->RequestorMode = KernelMode;
7292 pIrp->Flags |= IRP_READ_OPERATION;
7295 // Set up the I/O stack location.
7298 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7299 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7300 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7301 pIoStackLocation->FileObject = pCacheFileObject;
7302 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7304 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7307 // Set the completion routine.
7310 IoSetCompletionRoutine( pIrp,
7318 // Send it to the FSD
7321 ntStatus = IoCallDriver( pTargetDeviceObject,
7324 if( NT_SUCCESS( ntStatus))
7331 ntStatus = KeWaitForSingleObject( &kEvent,
7337 if( NT_SUCCESS( ntStatus))
7340 ntStatus = pIrp->IoStatus.Status;
7342 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7348 if( pCacheFileObject != NULL)
7350 AFSReleaseCacheFileObject( pCacheFileObject);
7356 if( pIrp->MdlAddress != NULL)
7359 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7362 MmUnlockPages( pIrp->MdlAddress);
7365 IoFreeMdl( pIrp->MdlAddress);
7368 pIrp->MdlAddress = NULL;
7382 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7387 KEVENT *pEvent = (KEVENT *)Context;
7393 return STATUS_MORE_PROCESSING_REQUIRED;
7397 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7400 BOOLEAN bIsEmpty = FALSE;
7401 AFSDirectoryCB *pDirEntry = NULL;
7406 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7411 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7414 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7416 while( pDirEntry != NULL)
7419 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7420 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7428 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7433 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7440 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7441 IN AFSDirectoryCB *DirEntry)
7444 NTSTATUS ntStatus = STATUS_SUCCESS;
7449 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7452 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7453 AFS_TRACE_LEVEL_VERBOSE,
7454 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7456 &DirEntry->NameInformation.FileName);
7458 try_return( ntStatus);
7461 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7464 // Remove the entry from the parent tree
7467 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7468 AFS_TRACE_LEVEL_VERBOSE,
7469 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7471 &DirEntry->NameInformation.FileName);
7473 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7476 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7477 AFS_TRACE_LEVEL_VERBOSE,
7478 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7480 &DirEntry->NameInformation.FileName);
7482 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7485 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7489 // From the short name tree
7492 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7493 AFS_TRACE_LEVEL_VERBOSE,
7494 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7496 &DirEntry->NameInformation.FileName);
7498 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7501 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7504 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7505 AFS_TRACE_LEVEL_VERBOSE,
7506 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7508 &DirEntry->NameInformation.FileName);
7510 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7512 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7523 AFSGetAuthenticationId()
7526 LARGE_INTEGER liAuthId = {0,0};
7527 NTSTATUS ntStatus = STATUS_SUCCESS;
7528 PACCESS_TOKEN hToken = NULL;
7529 PTOKEN_STATISTICS pTokenInfo = NULL;
7530 BOOLEAN bCopyOnOpen = FALSE;
7531 BOOLEAN bEffectiveOnly = FALSE;
7532 BOOLEAN bPrimaryToken = FALSE;
7533 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7538 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7541 &stImpersonationLevel);
7546 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7551 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7552 AFS_TRACE_LEVEL_ERROR,
7553 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7555 try_return( ntStatus);
7558 bPrimaryToken = TRUE;
7561 ntStatus = SeQueryInformationToken( hToken,
7563 (PVOID *)&pTokenInfo);
7565 if( !NT_SUCCESS( ntStatus))
7568 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7569 AFS_TRACE_LEVEL_ERROR,
7570 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7572 try_return( ntStatus);
7575 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7576 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7578 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7579 AFS_TRACE_LEVEL_VERBOSE,
7580 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7591 PsDereferenceImpersonationToken( hToken);
7596 PsDereferencePrimaryToken( hToken);
7600 if( pTokenInfo != NULL)
7603 AFSExFreePool( pTokenInfo);
7611 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7615 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7617 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7620 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7622 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7625 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7627 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7630 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7632 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7635 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7637 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7644 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7647 BOOLEAN bIsValid = TRUE;
7649 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7651 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7653 while( pCurrentDirEntry != NULL)
7656 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7660 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7665 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7666 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7669 if( pDirEntry == NULL)
7676 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7679 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7682 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7684 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7686 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7695 AFSReferenceCacheFileObject()
7698 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7699 FILE_OBJECT *pCacheFileObject = NULL;
7701 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7704 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7706 if( pCacheFileObject != NULL)
7708 ObReferenceObject( pCacheFileObject);
7711 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7713 return pCacheFileObject;
7717 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7720 ASSERT( CacheFileObject != NULL);
7722 ObDereferenceObject( CacheFileObject);
7728 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7731 NTSTATUS ntStatus = STATUS_SUCCESS;
7732 AFSDeviceExt *pControlDevExt = NULL;
7733 ULONG ulTimeIncrement = 0;
7738 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7740 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7742 AFSServerName = LibraryInit->AFSServerName;
7744 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7747 // Callbacks in the framework
7750 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7752 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7754 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7756 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7758 AFSExFreePool = LibraryInit->AFSExFreePool;
7760 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7762 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7764 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7766 if( LibraryInit->AFSCacheBaseAddress != NULL)
7769 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7771 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7773 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7777 // Initialize some flush parameters
7780 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7782 ulTimeIncrement = KeQueryTimeIncrement();
7784 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7785 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7786 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7787 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7788 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7791 // Initialize the global root entry
7794 ntStatus = AFSInitVolume( NULL,
7795 &LibraryInit->GlobalRootFid,
7798 if( !NT_SUCCESS( ntStatus))
7801 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7802 AFS_TRACE_LEVEL_ERROR,
7803 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7806 try_return( ntStatus);
7809 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7812 if( !NT_SUCCESS( ntStatus))
7815 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7816 AFS_TRACE_LEVEL_ERROR,
7817 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7820 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7822 try_return( ntStatus);
7826 // Update the node type code to AFS_ROOT_ALL
7829 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7831 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7834 // Invalidate all known volumes since contact with the service and therefore
7835 // the file server was lost.
7838 AFSInvalidateAllVolumes();
7841 // Drop the locks acquired above
7844 AFSInitVolumeWorker( AFSGlobalRoot);
7846 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7848 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7862 NTSTATUS ntStatus = STATUS_SUCCESS;
7863 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7868 if( AFSGlobalDotDirEntry != NULL)
7871 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
7873 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7875 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7877 ExFreePool( AFSGlobalDotDirEntry);
7879 AFSGlobalDotDirEntry = NULL;
7882 if( AFSGlobalDotDotDirEntry != NULL)
7885 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
7887 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7889 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7891 ExFreePool( AFSGlobalDotDotDirEntry);
7893 AFSGlobalDotDotDirEntry = NULL;
7896 if( AFSSpecialShareNames != NULL)
7899 pDirNode = AFSSpecialShareNames;
7901 while( pDirNode != NULL)
7904 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7906 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
7908 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7910 ExFreePool( pDirNode->NonPaged);
7912 ExFreePool( pDirNode);
7914 pDirNode = pLastDirNode;
7917 AFSSpecialShareNames = NULL;
7925 AFSDefaultLogMsg( IN ULONG Subsystem,
7931 NTSTATUS ntStatus = STATUS_SUCCESS;
7933 char chDebugBuffer[ 256];
7938 va_start( va_args, Format);
7940 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7945 if( NT_SUCCESS( ntStatus))
7947 DbgPrint( chDebugBuffer);
7957 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7958 IN ULONG InputBufferLength,
7959 IN AFSStatusInfoCB *StatusInfo,
7960 OUT ULONG *ReturnLength)
7963 NTSTATUS ntStatus = STATUS_SUCCESS;
7964 AFSFcb *pFcb = NULL;
7965 AFSVolumeCB *pVolumeCB = NULL;
7966 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7967 AFSObjectInfoCB *pObjectInfo = NULL;
7968 ULONGLONG ullIndex = 0;
7969 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7970 AFSNameArrayHdr *pNameArray = NULL;
7971 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7978 // If we are given a FID then look up the entry by that, otherwise
7982 if( GetStatusInfo->FileID.Cell != 0 &&
7983 GetStatusInfo->FileID.Volume != 0 &&
7984 GetStatusInfo->FileID.Vnode != 0 &&
7985 GetStatusInfo->FileID.Unique != 0)
7988 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7991 // Locate the volume node
7994 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7996 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7998 (AFSBTreeEntry **)&pVolumeCB);
8000 if( pVolumeCB != NULL)
8003 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8005 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8006 AFS_TRACE_LEVEL_VERBOSE,
8007 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
8012 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8014 if( !NT_SUCCESS( ntStatus) ||
8017 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8020 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8023 pObjectInfo = &pVolumeCB->ObjectInformation;
8025 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
8027 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8032 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8035 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8037 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8038 AFS_TRACE_LEVEL_VERBOSE,
8039 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
8043 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8045 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8047 (AFSBTreeEntry **)&pObjectInfo);
8049 if( pObjectInfo != NULL)
8053 // Reference the node so it won't be torn down
8056 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
8058 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8059 AFS_TRACE_LEVEL_VERBOSE,
8060 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
8065 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8067 if( !NT_SUCCESS( ntStatus) ||
8068 pObjectInfo == NULL)
8070 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8077 if( GetStatusInfo->FileNameLength == 0 ||
8078 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8080 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8083 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8084 uniFullPathName.MaximumLength = uniFullPathName.Length;
8086 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8089 // This name should begin with the \afs server so parse it off and check it
8092 FsRtlDissectName( uniFullPathName,
8096 if( RtlCompareUnicodeString( &uniComponentName,
8100 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8101 AFS_TRACE_LEVEL_ERROR,
8102 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8105 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8108 uniFullPathName = uniRemainingPath;
8110 uniParsedName = uniFullPathName;
8116 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8119 if( pNameArray == NULL)
8121 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8124 pVolumeCB = AFSGlobalRoot;
8126 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8129 // Increment the ref count on the volume and dir entry for correct processing below
8132 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8134 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8135 AFS_TRACE_LEVEL_VERBOSE,
8136 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
8140 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
8142 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8143 AFS_TRACE_LEVEL_VERBOSE,
8144 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8145 &pParentDirEntry->NameInformation.FileName,
8150 ntStatus = AFSLocateNameEntry( NULL,
8155 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8156 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8162 if( !NT_SUCCESS( ntStatus))
8166 // The volume lock was released on failure above
8167 // Except for STATUS_OBJECT_NAME_NOT_FOUND
8170 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
8173 if( pVolumeCB != NULL)
8176 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8178 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8179 AFS_TRACE_LEVEL_VERBOSE,
8180 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
8185 if( pDirectoryEntry != NULL)
8188 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
8190 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8191 AFS_TRACE_LEVEL_VERBOSE,
8192 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8193 &pDirectoryEntry->NameInformation.FileName,
8201 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
8203 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8204 AFS_TRACE_LEVEL_VERBOSE,
8205 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8206 &pParentDirEntry->NameInformation.FileName,
8215 try_return( ntStatus);
8219 // Remove the reference made above
8222 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
8224 pObjectInfo = pDirectoryEntry->ObjectInformation;
8226 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
8228 if( pVolumeCB != NULL)
8231 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8233 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8234 AFS_TRACE_LEVEL_VERBOSE,
8235 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
8237 pVolumeCB->VolumeReferenceCount);
8242 // At this point we have an object info block, return the information
8245 StatusInfo->FileId = pObjectInfo->FileId;
8247 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8249 StatusInfo->Expiration = pObjectInfo->Expiration;
8251 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8253 StatusInfo->FileType = pObjectInfo->FileType;
8255 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8257 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8259 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8261 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8263 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8265 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8267 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8269 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8271 StatusInfo->EaSize = pObjectInfo->EaSize;
8273 StatusInfo->Links = pObjectInfo->Links;
8276 // Return the information length
8279 *ReturnLength = sizeof( AFSStatusInfoCB);
8283 if( pObjectInfo != NULL)
8286 lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
8289 if( pNameArray != NULL)
8292 AFSFreeNameArray( pNameArray);
8300 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8301 IN UNICODE_STRING *ComponentName)
8304 NTSTATUS ntStatus = STATUS_SUCCESS;
8305 AFSDirectoryCB *pDirEntry = NULL;
8313 // Search for the entry in the parent
8316 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8317 AFS_TRACE_LEVEL_VERBOSE_2,
8318 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8321 ulCRC = AFSGenerateCRC( ComponentName,
8324 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8327 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8331 if( pDirEntry == NULL)
8335 // Missed so perform a case insensitive lookup
8338 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8339 AFS_TRACE_LEVEL_VERBOSE_2,
8340 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8343 ulCRC = AFSGenerateCRC( ComponentName,
8346 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8350 if( pDirEntry == NULL)
8354 // OK, if this component is a valid short name then try
8355 // a lookup in the short name tree
8358 if( RtlIsNameLegalDOS8Dot3( ComponentName,
8363 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8364 AFS_TRACE_LEVEL_VERBOSE_2,
8365 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8368 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8375 if( pDirEntry != NULL)
8377 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
8380 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8382 if( pDirEntry == NULL)
8385 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8386 AFS_TRACE_LEVEL_VERBOSE_2,
8387 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
8390 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8394 // We have the symlink object but previously failed to process it so return access
8398 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8399 AFS_TRACE_LEVEL_VERBOSE_2,
8400 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8403 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8405 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
8416 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8417 OUT UNICODE_STRING *ComponentName)
8420 NTSTATUS ntStatus = STATUS_SUCCESS;
8421 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8423 uniFullPathName = *FullPathName;
8428 FsRtlDissectName( uniFullPathName,
8432 if( uniRemainingPath.Length == 0)
8437 uniFullPathName = uniRemainingPath;
8440 if( uniComponentName.Length > 0)
8442 *ComponentName = uniComponentName;
8449 AFSDumpTraceFiles_Default()
8455 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8458 BOOLEAN bIsValidName = TRUE;
8464 while( usIndex < FileName->Length/sizeof( WCHAR))
8467 if( FileName->Buffer[ usIndex] == L':' ||
8468 FileName->Buffer[ usIndex] == L'*' ||
8469 FileName->Buffer[ usIndex] == L'?' ||
8470 FileName->Buffer[ usIndex] == L'"' ||
8471 FileName->Buffer[ usIndex] == L'<' ||
8472 FileName->Buffer[ usIndex] == L'>')
8474 bIsValidName = FALSE;
8482 return bIsValidName;
8486 AFSCreateDefaultSecurityDescriptor()
8489 NTSTATUS ntStatus = STATUS_SUCCESS;
8491 ULONG ulSACLSize = 0;
8492 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8493 ULONG ulACESize = 0;
8494 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8495 ULONG ulSDLength = 0;
8496 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8497 PSID pWorldSID = NULL;
8498 ULONG *pulSubAuthority = NULL;
8499 ULONG ulWorldSIDLEngth = 0;
8504 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8506 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8508 AFS_GENERIC_MEMORY_29_TAG);
8510 if( pWorldSID == NULL)
8512 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8513 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8516 RtlZeroMemory( pWorldSID,
8519 RtlInitializeSid( pWorldSID,
8520 &SeWorldSidAuthority,
8523 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8524 *pulSubAuthority = SECURITY_WORLD_RID;
8526 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8529 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8534 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8536 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8538 AFS_GENERIC_MEMORY_29_TAG);
8543 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8545 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8548 RtlZeroMemory( pACE,
8551 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8552 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8553 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8554 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8556 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8558 SeExports->SeLowMandatorySid);
8560 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8561 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8563 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8565 AFS_GENERIC_MEMORY_29_TAG);
8570 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8572 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8575 ntStatus = RtlCreateAcl( pSACL,
8579 if( !NT_SUCCESS( ntStatus))
8582 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8585 try_return( ntStatus);
8588 ntStatus = RtlAddAce( pSACL,
8592 pACE->Header.AceSize);
8594 if( !NT_SUCCESS( ntStatus))
8597 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8600 try_return( ntStatus);
8604 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8605 sizeof( SECURITY_DESCRIPTOR),
8606 AFS_GENERIC_MEMORY_27_TAG);
8608 if( pSecurityDescr == NULL)
8611 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8613 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8616 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8617 SECURITY_DESCRIPTOR_REVISION);
8619 if( !NT_SUCCESS( ntStatus))
8622 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8625 try_return( ntStatus);
8628 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8630 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8635 if( !NT_SUCCESS( ntStatus))
8638 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8641 try_return( ntStatus);
8646 // Add in the group and owner to the SD
8649 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8651 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8655 if( !NT_SUCCESS( ntStatus))
8658 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8661 try_return( ntStatus);
8665 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8669 if( !NT_SUCCESS( ntStatus))
8672 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8675 try_return( ntStatus);
8678 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8681 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8683 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8686 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8688 AFS_GENERIC_MEMORY_27_TAG);
8690 if( pRelativeSecurityDescr == NULL)
8693 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8695 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8698 ulSDLength = PAGE_SIZE;
8700 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8701 pRelativeSecurityDescr,
8704 if( !NT_SUCCESS( ntStatus))
8707 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8710 try_return( ntStatus);
8713 AFSDefaultSD = pRelativeSecurityDescr;
8717 if( !NT_SUCCESS( ntStatus))
8720 if( pRelativeSecurityDescr != NULL)
8722 ExFreePool( pRelativeSecurityDescr);
8726 if( pSecurityDescr != NULL)
8728 ExFreePool( pSecurityDescr);
8741 if( pWorldSID != NULL)
8743 ExFreePool( pWorldSID);
8751 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8752 OUT UNICODE_STRING *ParentPath)
8757 *ParentPath = *FullFileName;
8760 // If the final character is a \, jump over it
8763 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8765 ParentPath->Length -= sizeof( WCHAR);
8768 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8770 ParentPath->Length -= sizeof( WCHAR);
8774 // And the separator
8777 ParentPath->Length -= sizeof( WCHAR);
8783 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8784 IN AFSObjectInfoCB *ObjectInfo,
8785 IN BOOLEAN WriteAccess,
8786 OUT GUID *AuthGroup)
8789 NTSTATUS ntStatus = STATUS_SUCCESS;
8790 GUID stAuthGroup, stZeroAuthGroup;
8791 BOOLEAN bFoundAuthGroup = FALSE;
8792 AFSCcb *pCcb = NULL;
8798 RtlZeroMemory( &stAuthGroup,
8801 RtlZeroMemory( &stZeroAuthGroup,
8807 if( ObjectInfo != NULL &&
8808 ObjectInfo->Fcb != NULL)
8810 pFcb = ObjectInfo->Fcb;
8817 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8820 pCcb = Fcb->CcbListHead;
8822 while( pCcb != NULL)
8826 pCcb->GrantedAccess & FILE_WRITE_DATA)
8828 RtlCopyMemory( &stAuthGroup,
8832 bFoundAuthGroup = TRUE;
8836 else if( pCcb->GrantedAccess & FILE_READ_DATA)
8839 // At least get the read-only access
8842 RtlCopyMemory( &stAuthGroup,
8846 bFoundAuthGroup = TRUE;
8849 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
8852 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
8855 if( !bFoundAuthGroup)
8858 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
8859 (ULONGLONG)PsGetCurrentThreadId(),
8862 if( RtlCompareMemory( &stZeroAuthGroup,
8864 sizeof( GUID)) == sizeof( GUID))
8867 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
8869 try_return( ntStatus = STATUS_ACCESS_DENIED);
8873 RtlCopyMemory( AuthGroup,
8886 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
8887 IN ULONG InvalidateReason)
8890 NTSTATUS ntStatus = STATUS_SUCCESS;
8891 IO_STATUS_BLOCK stIoStatus;
8894 ULONG ulProcessCount = 0;
8900 switch( InvalidateReason)
8903 case AFS_INVALIDATE_DELETED:
8906 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8907 ObjectInfo->Fcb != NULL)
8912 // Clear out the extents
8913 // And get rid of them (note this involves waiting
8914 // for any writes or reads to the cache to complete)
8917 (VOID) AFSTearDownFcbExtents( ObjectInfo->Fcb,
8924 case AFS_INVALIDATE_DATA_VERSION:
8927 LARGE_INTEGER liCurrentOffset = {0,0};
8928 LARGE_INTEGER liFlushLength = {0,0};
8929 ULONG ulFlushLength = 0;
8930 BOOLEAN bLocked = FALSE;
8931 BOOLEAN bExtentsLocked = FALSE;
8932 BOOLEAN bCleanExtents = FALSE;
8934 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8935 ObjectInfo->Fcb != NULL)
8938 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
8943 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
8944 AFS_TRACE_LEVEL_VERBOSE,
8945 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %08lX SHARED %08lX\n",
8946 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
8947 PsGetCurrentThread());
8949 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
8952 bExtentsLocked = TRUE;
8955 // There are several possibilities here:
8957 // 0. If there are no extents or all of the extents are dirty, do nothing.
8959 // 1. There could be nothing dirty and an open reference count of zero
8960 // in which case we can just tear down all of the extents without
8961 // holding any resources.
8963 // 2. There could be nothing dirty and a non-zero open reference count
8964 // in which case we can issue a CcPurge against the entire file
8965 // while holding just the Fcb Resource.
8967 // 3. There can be dirty extents in which case we need to identify
8968 // the non-dirty ranges and then perform a CcPurge on just the
8969 // non-dirty ranges while holding just the Fcb Resource.
8972 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
8975 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
8978 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
8981 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
8983 bExtentsLocked = FALSE;
8985 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
8989 (VOID) AFSTearDownFcbExtents( ObjectInfo->Fcb,
8998 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9000 bExtentsLocked = FALSE;
9002 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9008 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9009 AFS_TRACE_LEVEL_WARNING,
9010 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9011 ObjectInfo->FileId.Cell,
9012 ObjectInfo->FileId.Volume,
9013 ObjectInfo->FileId.Vnode,
9014 ObjectInfo->FileId.Unique);
9016 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9021 bCleanExtents = TRUE;
9024 __except( EXCEPTION_EXECUTE_HANDLER)
9027 ntStatus = GetExceptionCode();
9031 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9032 ObjectInfo->FileId.Cell,
9033 ObjectInfo->FileId.Volume,
9034 ObjectInfo->FileId.Vnode,
9035 ObjectInfo->FileId.Unique,
9038 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9046 // Must build a list of non-dirty ranges from the beginning of the file
9047 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9048 // ranges. In all but the most extreme random data write scenario there will
9049 // be significantly fewer.
9051 // For each range we need offset and size.
9054 AFSByteRange * ByteRangeList = NULL;
9055 ULONG ulByteRangeCount = 0;
9057 BOOLEAN bPurgeOnClose = FALSE;
9062 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9065 if ( ByteRangeList != NULL ||
9066 ulByteRangeCount == 0)
9069 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9071 bExtentsLocked = FALSE;
9073 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9080 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9082 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9083 &ByteRangeList[ulIndex].FileOffset,
9088 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9089 AFS_TRACE_LEVEL_WARNING,
9090 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9091 ObjectInfo->FileId.Cell,
9092 ObjectInfo->FileId.Volume,
9093 ObjectInfo->FileId.Vnode,
9094 ObjectInfo->FileId.Unique);
9096 bPurgeOnClose = TRUE;
9101 bCleanExtents = TRUE;
9104 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9106 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9108 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9115 // We couldn't allocate the memory to build the purge list
9116 // so just walk the extent list while holding the ExtentsList Resource.
9117 // This could deadlock but we do not have much choice.
9120 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9124 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9128 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9130 while( ulProcessCount < ulCount)
9132 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9134 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9136 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9137 &pEntry->FileOffset,
9142 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9143 AFS_TRACE_LEVEL_WARNING,
9144 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9145 ObjectInfo->FileId.Cell,
9146 ObjectInfo->FileId.Volume,
9147 ObjectInfo->FileId.Vnode,
9148 ObjectInfo->FileId.Unique);
9150 bPurgeOnClose = TRUE;
9155 bCleanExtents = TRUE;
9159 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9162 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9164 while( liFlushLength.QuadPart > 0)
9167 if( liFlushLength.QuadPart > 512 * 1024000)
9169 ulFlushLength = 512 * 1024000;
9173 ulFlushLength = liFlushLength.LowPart;
9176 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9182 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9183 AFS_TRACE_LEVEL_WARNING,
9184 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9185 ObjectInfo->FileId.Cell,
9186 ObjectInfo->FileId.Volume,
9187 ObjectInfo->FileId.Vnode,
9188 ObjectInfo->FileId.Unique);
9190 bPurgeOnClose = TRUE;
9195 bCleanExtents = TRUE;
9198 liFlushLength.QuadPart -= ulFlushLength;
9202 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9210 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9216 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9217 AFS_TRACE_LEVEL_WARNING,
9218 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9219 ObjectInfo->FileId.Cell,
9220 ObjectInfo->FileId.Volume,
9221 ObjectInfo->FileId.Vnode,
9222 ObjectInfo->FileId.Unique);
9224 bPurgeOnClose = TRUE;
9229 bCleanExtents = TRUE;
9236 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9240 __except( EXCEPTION_EXECUTE_HANDLER)
9243 ntStatus = GetExceptionCode();
9247 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9248 ObjectInfo->FileId.Cell,
9249 ObjectInfo->FileId.Volume,
9250 ObjectInfo->FileId.Vnode,
9251 ObjectInfo->FileId.Unique,
9257 if ( bExtentsLocked)
9260 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9266 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9272 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9281 if( ObjectInfo != NULL)
9283 InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);