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 = AFSObjectInfoIncrement( pObjectInfoCB);
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 = AFSObjectInfoIncrement( pObjectInfoCB);
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 = AFSObjectInfoIncrement( pObjectInfoCB);
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 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1190 if( pDirNode != NULL)
1193 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1199 // Dereference our object info block if we have one
1202 if( pObjectInfoCB != NULL)
1205 lCount = AFSObjectInfoDecrement( pObjectInfoCB);
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 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
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 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
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 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 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1849 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1852 FILE_ACTION_MODIFIED);
1857 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1860 FILE_ACTION_MODIFIED);
1864 // Indicate this node requires re-evaluation for the remaining reasons
1867 (*ppObjectInfo)->Expiration.QuadPart = 0;
1869 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1870 AFS_TRACE_LEVEL_VERBOSE,
1871 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1872 (*ppObjectInfo)->FileId.Cell,
1873 (*ppObjectInfo)->FileId.Volume,
1874 (*ppObjectInfo)->FileId.Vnode,
1875 (*ppObjectInfo)->FileId.Unique);
1877 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1879 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1880 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1881 ( Reason == AFS_INVALIDATE_CALLBACK ||
1882 Reason == AFS_INVALIDATE_EXPIRED))
1884 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1885 AFS_INVALIDATE_DATA_VERSION)))
1888 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1902 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1905 NTSTATUS ntStatus = STATUS_SUCCESS;
1906 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1907 AFSVolumeCB *pVolumeCB = NULL;
1908 AFSFcb *pTargetDcb = NULL;
1909 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1910 AFSDirectoryCB *pCurrentDirEntry = NULL;
1911 BOOLEAN bIsChild = FALSE;
1912 ULONGLONG ullIndex = 0;
1913 AFSObjectInfoCB *pObjectInfo = NULL;
1919 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1920 AFS_TRACE_LEVEL_VERBOSE,
1921 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1922 InvalidateCB->FileID.Cell,
1923 InvalidateCB->FileID.Volume,
1924 InvalidateCB->FileID.Vnode,
1925 InvalidateCB->FileID.Unique,
1926 InvalidateCB->FileType,
1927 InvalidateCB->WholeVolume,
1928 InvalidateCB->Reason);
1931 // Need to locate the Fcb for the directory to purge
1934 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1935 AFS_TRACE_LEVEL_VERBOSE,
1936 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1937 &pDevExt->Specific.RDR.VolumeTreeLock,
1938 PsGetCurrentThread());
1941 // Starve any exclusive waiters on this paticular call
1944 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1947 // Locate the volume node
1950 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1952 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1954 (AFSBTreeEntry **)&pVolumeCB);
1956 if( pVolumeCB != NULL)
1959 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1961 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1962 AFS_TRACE_LEVEL_VERBOSE,
1963 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1968 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1970 if( !NT_SUCCESS( ntStatus) ||
1974 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1975 AFS_TRACE_LEVEL_WARNING,
1976 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1977 InvalidateCB->FileID.Cell,
1978 InvalidateCB->FileID.Volume,
1979 InvalidateCB->FileID.Vnode,
1980 InvalidateCB->FileID.Unique,
1983 try_return( ntStatus = STATUS_SUCCESS);
1987 // If this is a whole volume invalidation then go do it now
1990 if( InvalidateCB->WholeVolume)
1993 ntStatus = AFSInvalidateVolume( pVolumeCB,
1994 InvalidateCB->Reason);
1996 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1998 try_return( ntStatus);
2001 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
2004 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2007 pObjectInfo = &pVolumeCB->ObjectInformation;
2012 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2014 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2015 AFS_TRACE_LEVEL_VERBOSE,
2016 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
2018 pVolumeCB->VolumeReferenceCount);
2020 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2022 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2024 (AFSBTreeEntry **)&pObjectInfo);
2027 if( pObjectInfo != NULL)
2031 // Reference the node so it won't be torn down
2034 lCount = AFSObjectInfoIncrement( pObjectInfo);
2036 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2037 AFS_TRACE_LEVEL_VERBOSE,
2038 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
2043 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2045 if( !NT_SUCCESS( ntStatus) ||
2046 pObjectInfo == NULL)
2049 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2050 AFS_TRACE_LEVEL_VERBOSE,
2051 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2052 InvalidateCB->FileID.Cell,
2053 InvalidateCB->FileID.Volume,
2054 InvalidateCB->FileID.Vnode,
2055 InvalidateCB->FileID.Unique,
2058 try_return( ntStatus = STATUS_SUCCESS);
2061 AFSInvalidateObject( &pObjectInfo,
2062 InvalidateCB->Reason);
2066 if( pObjectInfo != NULL)
2069 lCount = AFSObjectInfoDecrement( pObjectInfo);
2071 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2072 AFS_TRACE_LEVEL_VERBOSE,
2073 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
2083 AFSIsChildOfParent( IN AFSFcb *Dcb,
2087 BOOLEAN bIsChild = FALSE;
2088 AFSFcb *pCurrentFcb = Fcb;
2090 while( pCurrentFcb != NULL)
2093 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2101 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2109 AFSCreateHighIndex( IN AFSFileID *FileID)
2112 ULONGLONG ullIndex = 0;
2114 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2121 AFSCreateLowIndex( IN AFSFileID *FileID)
2124 ULONGLONG ullIndex = 0;
2126 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2132 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2133 IN ACCESS_MASK GrantedAccess,
2134 IN BOOLEAN DirectoryEntry)
2137 BOOLEAN bAccessGranted = TRUE;
2140 // Check if we are asking for read/write and granted only read only
2141 // NOTE: There will be more checks here
2144 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2146 AFSCheckForReadOnlyAccess( GrantedAccess,
2150 bAccessGranted = FALSE;
2153 return bAccessGranted;
2157 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2160 NTSTATUS ntStatus = STATUS_SUCCESS;
2161 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2167 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2169 if( AFSGlobalRoot == NULL)
2176 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2179 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2186 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2193 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2194 IN UNICODE_STRING *SubstituteName,
2195 IN ULONG StringIndex)
2198 NTSTATUS ntStatus = STATUS_SUCCESS;
2199 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2200 AFSSysNameCB *pSysName = NULL;
2201 ERESOURCE *pSysNameLock = NULL;
2204 UNICODE_STRING uniSysName;
2211 if( IoIs32bitProcess( NULL))
2214 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2216 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2221 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2223 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2227 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2229 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2233 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2234 AFS_TRACE_LEVEL_VERBOSE,
2235 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2237 PsGetCurrentThread());
2239 AFSAcquireShared( pSysNameLock,
2243 // Find where we are in the list
2246 while( pSysName != NULL &&
2247 ulIndex < StringIndex)
2250 pSysName = pSysName->fLink;
2255 if( pSysName == NULL)
2258 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2261 RtlInitUnicodeString( &uniSysName,
2264 // If it is a full component of @SYS then just substitue the
2268 if( RtlCompareUnicodeString( &uniSysName,
2273 SubstituteName->Length = pSysName->SysName.Length;
2274 SubstituteName->MaximumLength = SubstituteName->Length;
2276 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2277 SubstituteName->Length,
2278 AFS_SUBST_BUFFER_TAG);
2280 if( SubstituteName->Buffer == NULL)
2283 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2286 RtlCopyMemory( SubstituteName->Buffer,
2287 pSysName->SysName.Buffer,
2288 pSysName->SysName.Length);
2295 while( ComponentName->Buffer[ usIndex] != L'@')
2301 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2302 SubstituteName->MaximumLength = SubstituteName->Length;
2304 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2305 SubstituteName->Length,
2306 AFS_SUBST_BUFFER_TAG);
2308 if( SubstituteName->Buffer == NULL)
2311 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2314 RtlCopyMemory( SubstituteName->Buffer,
2315 ComponentName->Buffer,
2316 usIndex * sizeof( WCHAR));
2318 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2319 pSysName->SysName.Buffer,
2320 pSysName->SysName.Length);
2325 AFSReleaseResource( pSysNameLock);
2332 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2333 IN OUT UNICODE_STRING *ComponentName,
2334 IN UNICODE_STRING *SubstituteName,
2335 IN OUT UNICODE_STRING *RemainingPath,
2336 IN BOOLEAN FreePathName)
2339 NTSTATUS ntStatus = STATUS_SUCCESS;
2340 UNICODE_STRING uniPathName;
2341 USHORT usPrefixNameLen = 0;
2342 SHORT sNameLenDelta = 0;
2348 // If the passed in name can handle the additional length
2349 // then just moves things around
2352 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2354 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2356 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2359 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2362 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2363 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2364 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2367 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2368 SubstituteName->Buffer,
2369 SubstituteName->Length);
2371 FullPathName->Length += sNameLenDelta;
2373 ComponentName->Length += sNameLenDelta;
2375 ComponentName->MaximumLength = ComponentName->Length;
2377 if ( RemainingPath->Buffer)
2380 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2383 try_return( ntStatus);
2387 // Need to re-allocate the buffer
2390 uniPathName.Length = FullPathName->Length -
2391 ComponentName->Length +
2392 SubstituteName->Length;
2394 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2396 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2397 uniPathName.MaximumLength,
2398 AFS_NAME_BUFFER_FOUR_TAG);
2400 if( uniPathName.Buffer == NULL)
2403 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2406 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2408 usPrefixNameLen *= sizeof( WCHAR);
2410 RtlZeroMemory( uniPathName.Buffer,
2411 uniPathName.MaximumLength);
2413 RtlCopyMemory( uniPathName.Buffer,
2414 FullPathName->Buffer,
2417 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2418 SubstituteName->Buffer,
2419 SubstituteName->Length);
2421 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2424 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2425 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2426 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2429 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2431 ComponentName->Length += sNameLenDelta;
2433 ComponentName->MaximumLength = ComponentName->Length;
2435 if ( RemainingPath->Buffer)
2438 RemainingPath->Buffer = uniPathName.Buffer
2439 + (RemainingPath->Buffer - FullPathName->Buffer)
2440 + sNameLenDelta/sizeof( WCHAR);
2445 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2448 *FullPathName = uniPathName;
2459 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2463 NTSTATUS ntStatus = STATUS_SUCCESS;
2464 AFSObjectInfoCB *pCurrentObject = NULL;
2465 AFSObjectInfoCB *pNextObject = NULL;
2467 AFSFcb *pFcb = NULL;
2473 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2474 AFS_TRACE_LEVEL_VERBOSE,
2475 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2476 VolumeCB->ObjectInformation.FileId.Cell,
2477 VolumeCB->ObjectInformation.FileId.Volume,
2478 VolumeCB->ObjectInformation.FileId.Vnode,
2479 VolumeCB->ObjectInformation.FileId.Unique,
2483 // Depending on the reason for invalidation then perform work on the node
2489 case AFS_INVALIDATE_DELETED:
2493 // Mark this volume as invalid
2496 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2498 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2505 // Invalidate the volume root directory
2508 pCurrentObject = &VolumeCB->ObjectInformation;
2510 if ( pCurrentObject )
2513 lCount = AFSObjectInfoIncrement( pCurrentObject);
2515 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2516 AFS_TRACE_LEVEL_VERBOSE,
2517 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2521 AFSInvalidateObject( &pCurrentObject,
2524 if ( pCurrentObject)
2527 lCount = AFSObjectInfoDecrement( pCurrentObject);
2529 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2530 AFS_TRACE_LEVEL_VERBOSE,
2531 "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
2538 // Apply invalidation to all other volume objects
2541 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2544 pCurrentObject = VolumeCB->ObjectInfoListHead;
2546 if ( pCurrentObject)
2550 // Reference the node so it won't be torn down
2553 lCount = AFSObjectInfoIncrement( pCurrentObject);
2555 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2556 AFS_TRACE_LEVEL_VERBOSE,
2557 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2562 while( pCurrentObject != NULL)
2565 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2571 // Reference the node so it won't be torn down
2574 lCount = AFSObjectInfoIncrement( pNextObject);
2576 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2577 AFS_TRACE_LEVEL_VERBOSE,
2578 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2583 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2585 AFSInvalidateObject( &pCurrentObject,
2588 if ( pCurrentObject )
2591 lCount = AFSObjectInfoDecrement( pCurrentObject);
2593 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2594 AFS_TRACE_LEVEL_VERBOSE,
2595 "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
2600 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2603 pCurrentObject = pNextObject;
2606 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2613 AFSInvalidateAllVolumes( VOID)
2615 AFSVolumeCB *pVolumeCB = NULL;
2616 AFSVolumeCB *pNextVolumeCB = NULL;
2617 AFSDeviceExt *pRDRDeviceExt = NULL;
2620 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2622 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2623 AFS_TRACE_LEVEL_VERBOSE,
2624 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %08lX SHARED %08lX\n",
2625 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2626 PsGetCurrentThread());
2628 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2631 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2636 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2637 AFS_TRACE_LEVEL_VERBOSE,
2638 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %08lX SHARED %08lX\n",
2639 pVolumeCB->ObjectInfoTree.TreeLock,
2640 PsGetCurrentThread());
2642 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
2645 while( pVolumeCB != NULL)
2648 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2653 lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
2656 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2658 // do I need to hold the volume lock here?
2660 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2662 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2665 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2667 pVolumeCB = pNextVolumeCB;
2670 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2674 AFSVerifyEntry( IN GUID *AuthGroup,
2675 IN AFSDirectoryCB *DirEntry)
2678 NTSTATUS ntStatus = STATUS_SUCCESS;
2679 AFSDirEnumEntry *pDirEnumEntry = NULL;
2680 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2681 IO_STATUS_BLOCK stIoStatus;
2686 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2687 AFS_TRACE_LEVEL_VERBOSE_2,
2688 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2689 &DirEntry->NameInformation.FileName,
2690 pObjectInfo->FileId.Cell,
2691 pObjectInfo->FileId.Volume,
2692 pObjectInfo->FileId.Vnode,
2693 pObjectInfo->FileId.Unique);
2695 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2700 if( !NT_SUCCESS( ntStatus))
2703 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2704 AFS_TRACE_LEVEL_ERROR,
2705 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2706 &DirEntry->NameInformation.FileName,
2707 pObjectInfo->FileId.Cell,
2708 pObjectInfo->FileId.Volume,
2709 pObjectInfo->FileId.Vnode,
2710 pObjectInfo->FileId.Unique,
2713 try_return( ntStatus);
2717 // Check the data version of the file
2720 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2722 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2725 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2726 AFS_TRACE_LEVEL_VERBOSE,
2727 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2728 pObjectInfo->DataVersion.QuadPart,
2729 &DirEntry->NameInformation.FileName,
2730 pObjectInfo->FileId.Cell,
2731 pObjectInfo->FileId.Volume,
2732 pObjectInfo->FileId.Vnode,
2733 pObjectInfo->FileId.Unique);
2736 // We are ok, just get out
2739 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2741 try_return( ntStatus = STATUS_SUCCESS);
2746 // New data version so we will need to process the node based on the type
2749 switch( pDirEnumEntry->FileType)
2752 case AFS_FILE_TYPE_MOUNTPOINT:
2756 // For a mount point we need to ensure the target is the same
2759 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2760 &pDirEnumEntry->TargetFileId))
2766 // Update the metadata for the entry
2769 ntStatus = AFSUpdateMetaData( DirEntry,
2772 if( NT_SUCCESS( ntStatus))
2775 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2781 case AFS_FILE_TYPE_SYMLINK:
2784 ASSERT( pDirEnumEntry->TargetNameLength > 0);
2787 // Update the metadata for the entry
2790 ntStatus = AFSUpdateMetaData( DirEntry,
2793 if( NT_SUCCESS( ntStatus))
2796 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2802 case AFS_FILE_TYPE_FILE:
2804 FILE_OBJECT * pCCFileObject = NULL;
2805 BOOLEAN bPurgeExtents = FALSE;
2807 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
2810 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2811 AFS_TRACE_LEVEL_VERBOSE,
2812 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
2813 &DirEntry->NameInformation.FileName,
2814 pObjectInfo->FileId.Cell,
2815 pObjectInfo->FileId.Volume,
2816 pObjectInfo->FileId.Vnode,
2817 pObjectInfo->FileId.Unique,
2818 pObjectInfo->DataVersion.LowPart,
2819 pDirEnumEntry->DataVersion.LowPart
2822 bPurgeExtents = TRUE;
2825 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2828 bPurgeExtents = TRUE;
2830 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2831 AFS_TRACE_LEVEL_VERBOSE,
2832 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2833 &DirEntry->NameInformation.FileName,
2834 pObjectInfo->FileId.Cell,
2835 pObjectInfo->FileId.Volume,
2836 pObjectInfo->FileId.Vnode,
2837 pObjectInfo->FileId.Unique);
2839 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2842 if( pObjectInfo->Fcb != NULL)
2845 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2846 AFS_TRACE_LEVEL_VERBOSE,
2847 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2848 &DirEntry->NameInformation.FileName,
2849 pObjectInfo->FileId.Cell,
2850 pObjectInfo->FileId.Volume,
2851 pObjectInfo->FileId.Vnode,
2852 pObjectInfo->FileId.Unique);
2854 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2860 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2865 if( !NT_SUCCESS( stIoStatus.Status))
2868 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2869 AFS_TRACE_LEVEL_ERROR,
2870 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2871 &DirEntry->NameInformation.FileName,
2872 pObjectInfo->FileId.Cell,
2873 pObjectInfo->FileId.Volume,
2874 pObjectInfo->FileId.Vnode,
2875 pObjectInfo->FileId.Unique,
2877 stIoStatus.Information);
2879 ntStatus = stIoStatus.Status;
2885 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2891 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2892 AFS_TRACE_LEVEL_WARNING,
2893 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2894 &DirEntry->NameInformation.FileName,
2895 pObjectInfo->FileId.Cell,
2896 pObjectInfo->FileId.Volume,
2897 pObjectInfo->FileId.Vnode,
2898 pObjectInfo->FileId.Unique);
2900 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2904 __except( EXCEPTION_EXECUTE_HANDLER)
2906 ntStatus = GetExceptionCode();
2910 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2911 &DirEntry->NameInformation.FileName,
2912 pObjectInfo->FileId.Cell,
2913 pObjectInfo->FileId.Volume,
2914 pObjectInfo->FileId.Vnode,
2915 pObjectInfo->FileId.Unique,
2918 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2921 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2925 AFSFlushExtents( pObjectInfo->Fcb,
2930 // Reacquire the Fcb to purge the cache
2933 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2934 AFS_TRACE_LEVEL_VERBOSE,
2935 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2936 &pObjectInfo->Fcb->NPFcb->Resource,
2937 PsGetCurrentThread());
2939 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2943 // Update the metadata for the entry
2946 ntStatus = AFSUpdateMetaData( DirEntry,
2949 if( !NT_SUCCESS( ntStatus))
2952 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2953 AFS_TRACE_LEVEL_ERROR,
2954 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2955 &DirEntry->NameInformation.FileName,
2956 pObjectInfo->FileId.Cell,
2957 pObjectInfo->FileId.Volume,
2958 pObjectInfo->FileId.Vnode,
2959 pObjectInfo->FileId.Unique,
2966 // Update file sizes
2969 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2970 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2971 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2973 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2975 if ( pCCFileObject != NULL)
2977 CcSetFileSizes( pCCFileObject,
2978 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
2981 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2987 // Update the metadata for the entry
2990 ntStatus = AFSUpdateMetaData( DirEntry,
2993 if( !NT_SUCCESS( ntStatus))
2996 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2997 AFS_TRACE_LEVEL_ERROR,
2998 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2999 &DirEntry->NameInformation.FileName,
3000 pObjectInfo->FileId.Cell,
3001 pObjectInfo->FileId.Volume,
3002 pObjectInfo->FileId.Vnode,
3003 pObjectInfo->FileId.Unique,
3009 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3010 AFS_TRACE_LEVEL_WARNING,
3011 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3012 &DirEntry->NameInformation.FileName,
3013 pObjectInfo->FileId.Cell,
3014 pObjectInfo->FileId.Volume,
3015 pObjectInfo->FileId.Vnode,
3016 pObjectInfo->FileId.Unique);
3019 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3024 case AFS_FILE_TYPE_DIRECTORY:
3027 AFSFcb *pCurrentFcb = NULL;
3028 AFSDirectoryCB *pCurrentDirEntry = NULL;
3031 // For a directory or root entry flush the content of
3032 // the directory enumeration.
3035 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3038 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3039 AFS_TRACE_LEVEL_VERBOSE_2,
3040 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3041 &DirEntry->NameInformation.FileName,
3042 pObjectInfo->FileId.Cell,
3043 pObjectInfo->FileId.Volume,
3044 pObjectInfo->FileId.Vnode,
3045 pObjectInfo->FileId.Unique);
3047 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3050 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3053 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3055 if ( !NT_SUCCESS( ntStatus))
3058 try_return( ntStatus);
3063 // Update the metadata for the entry
3066 ntStatus = AFSUpdateMetaData( DirEntry,
3069 if( NT_SUCCESS( ntStatus))
3072 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3078 case AFS_FILE_TYPE_DFSLINK:
3081 UNICODE_STRING uniTargetName;
3084 // For a DFS link need to check the target name has not changed
3087 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3089 uniTargetName.MaximumLength = uniTargetName.Length;
3091 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3093 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3096 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3097 RtlCompareUnicodeString( &uniTargetName,
3098 &DirEntry->NameInformation.TargetName,
3103 // Update the target name
3106 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3108 uniTargetName.Buffer,
3109 uniTargetName.Length);
3111 if( !NT_SUCCESS( ntStatus))
3114 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3120 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3123 // Update the metadata for the entry
3126 ntStatus = AFSUpdateMetaData( DirEntry,
3129 if( NT_SUCCESS( ntStatus))
3132 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3140 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3141 AFS_TRACE_LEVEL_WARNING,
3142 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3143 pObjectInfo->FileType,
3144 &DirEntry->NameInformation.FileName,
3145 pObjectInfo->FileId.Cell,
3146 pObjectInfo->FileId.Volume,
3147 pObjectInfo->FileId.Vnode,
3148 pObjectInfo->FileId.Unique);
3155 if( pDirEnumEntry != NULL)
3158 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3166 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3169 NTSTATUS ntStatus = STATUS_SUCCESS;
3170 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3171 ULONGLONG ullIndex = 0;
3172 AFSVolumeCB *pVolumeCB = NULL;
3173 AFSFcb *pFcb = NULL;
3174 AFSObjectInfoCB *pCurrentObject = NULL;
3180 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3181 AFS_TRACE_LEVEL_VERBOSE,
3182 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3183 VolumeStatus->Online,
3184 VolumeStatus->FileID.Cell,
3185 VolumeStatus->FileID.Volume);
3188 // Need to locate the Fcb for the directory to purge
3191 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3192 AFS_TRACE_LEVEL_VERBOSE,
3193 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3194 &pDevExt->Specific.RDR.VolumeTreeLock,
3195 PsGetCurrentThread());
3197 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3200 // Locate the volume node
3203 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3205 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3207 (AFSBTreeEntry **)&pVolumeCB);
3209 if( pVolumeCB != NULL)
3212 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3214 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3217 // Set the volume state accordingly
3220 if( VolumeStatus->Online)
3223 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3228 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3231 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3234 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3236 while( pCurrentObject != NULL)
3239 if( VolumeStatus->Online)
3242 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3244 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3246 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3251 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3254 pFcb = pCurrentObject->Fcb;
3257 !(VolumeStatus->Online) &&
3258 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3261 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3262 AFS_TRACE_LEVEL_ERROR,
3263 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3264 VolumeStatus->FileID.Cell,
3265 VolumeStatus->FileID.Volume);
3268 // Clear out the extents
3271 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3272 AFS_TRACE_LEVEL_VERBOSE,
3273 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3274 &pFcb->NPFcb->Specific.File.ExtentsResource,
3275 PsGetCurrentThread());
3277 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3280 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3282 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3286 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3287 AFS_TRACE_LEVEL_VERBOSE,
3288 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3289 &pFcb->NPFcb->Specific.File.ExtentsResource,
3290 PsGetCurrentThread());
3292 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3295 // And get rid of them (note this involves waiting
3296 // for any writes or reads to the cache to complete)
3299 AFSTearDownFcbExtents( pFcb,
3303 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3306 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3308 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3313 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3321 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3324 NTSTATUS ntStatus = STATUS_SUCCESS;
3329 if( AFSGlobalRoot == NULL)
3332 try_return( ntStatus);
3335 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3339 // Set the network state according to the information
3342 if( NetworkStatus->Online)
3345 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3350 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3353 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3364 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3368 NTSTATUS ntStatus = STATUS_SUCCESS;
3369 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3370 BOOLEAN bAcquiredLock = FALSE;
3371 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3372 AFSFcb *pFcb = NULL;
3377 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3378 AFS_TRACE_LEVEL_VERBOSE,
3379 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3380 ObjectInfo->FileId.Cell,
3381 ObjectInfo->FileId.Volume,
3382 ObjectInfo->FileId.Vnode,
3383 ObjectInfo->FileId.Unique);
3385 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3388 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3389 AFS_TRACE_LEVEL_VERBOSE,
3390 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3391 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3392 PsGetCurrentThread());
3394 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3397 bAcquiredLock = TRUE;
3401 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3404 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3405 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3408 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3409 AFS_TRACE_LEVEL_ERROR,
3410 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
3411 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3412 ObjectInfo->FileId.Cell,
3413 ObjectInfo->FileId.Volume,
3414 ObjectInfo->FileId.Vnode,
3415 ObjectInfo->FileId.Unique);
3419 // Reset the directory list information by clearing all valid entries
3422 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3424 while( pCurrentDirEntry != NULL)
3427 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3429 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3433 // If this entry has been deleted then process it here
3436 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3437 pCurrentDirEntry->OpenReferenceCount == 0)
3440 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3441 AFS_TRACE_LEVEL_VERBOSE,
3442 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3444 &pCurrentDirEntry->NameInformation.FileName);
3446 AFSDeleteDirEntry( ObjectInfo,
3452 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3454 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3455 AFS_TRACE_LEVEL_VERBOSE,
3456 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3458 pCurrentDirEntry->OpenReferenceCount);
3461 // We pull the short name from the parent tree since it could change below
3464 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3467 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3468 AFS_TRACE_LEVEL_VERBOSE,
3469 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3471 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3472 &pCurrentDirEntry->NameInformation.FileName);
3474 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3477 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3482 pCurrentDirEntry = pNextDirEntry;
3486 // Reget the directory contents
3489 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3492 if ( !NT_SUCCESS( ntStatus))
3494 try_return( ntStatus);
3498 // Now start again and tear down any entries not valid
3501 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3503 while( pCurrentDirEntry != NULL)
3506 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3508 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3511 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3512 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3513 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3516 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3519 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3521 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3522 AFS_TRACE_LEVEL_VERBOSE,
3523 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3525 &pCurrentDirEntry->NameInformation.FileName);
3527 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3532 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3535 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3536 AFS_TRACE_LEVEL_VERBOSE,
3537 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3539 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3540 &pCurrentDirEntry->NameInformation.FileName);
3544 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3546 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3547 AFS_TRACE_LEVEL_VERBOSE,
3548 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3550 &pCurrentDirEntry->NameInformation.FileName);
3555 pCurrentDirEntry = pNextDirEntry;
3560 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3561 AFS_TRACE_LEVEL_VERBOSE,
3562 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3564 pCurrentDirEntry->OpenReferenceCount);
3566 if( pCurrentDirEntry->OpenReferenceCount == 0)
3569 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3570 AFS_TRACE_LEVEL_VERBOSE,
3571 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3572 &pCurrentDirEntry->NameInformation.FileName,
3573 ObjectInfo->FileId.Cell,
3574 ObjectInfo->FileId.Volume,
3575 ObjectInfo->FileId.Vnode,
3576 ObjectInfo->FileId.Unique);
3578 AFSDeleteDirEntry( ObjectInfo,
3584 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3585 AFS_TRACE_LEVEL_VERBOSE,
3586 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3588 &pCurrentDirEntry->NameInformation.FileName,
3589 ObjectInfo->FileId.Cell,
3590 ObjectInfo->FileId.Volume,
3591 ObjectInfo->FileId.Vnode,
3592 ObjectInfo->FileId.Unique);
3594 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3596 AFSRemoveNameEntry( ObjectInfo,
3600 pCurrentDirEntry = pNextDirEntry;
3604 if( !AFSValidateDirList( ObjectInfo))
3607 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3616 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3624 AFSIsVolumeFID( IN AFSFileID *FileID)
3627 BOOLEAN bIsVolume = FALSE;
3629 if( FileID->Vnode == 1 &&
3630 FileID->Unique == 1)
3640 AFSIsFinalNode( IN AFSFcb *Fcb)
3643 BOOLEAN bIsFinalNode = FALSE;
3645 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3646 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3647 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3648 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3649 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3652 bIsFinalNode = TRUE;
3657 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3658 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3661 return bIsFinalNode;
3665 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3666 IN AFSDirEnumEntry *DirEnumEntry)
3669 NTSTATUS ntStatus = STATUS_SUCCESS;
3670 UNICODE_STRING uniTargetName;
3671 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3676 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3678 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3680 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3682 pObjectInfo->FileType = DirEnumEntry->FileType;
3684 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3686 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3688 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3690 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3692 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3694 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3696 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3698 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3701 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3704 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3705 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3708 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3711 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3713 pObjectInfo->Links = DirEnumEntry->Links;
3715 if( DirEnumEntry->TargetNameLength > 0)
3719 // Update the target name information if needed
3722 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3724 uniTargetName.MaximumLength = uniTargetName.Length;
3726 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3728 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3731 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3732 RtlCompareUnicodeString( &uniTargetName,
3733 &DirEntry->NameInformation.TargetName,
3738 // Update the target name
3741 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3743 uniTargetName.Buffer,
3744 uniTargetName.Length);
3746 if( !NT_SUCCESS( ntStatus))
3749 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3751 try_return( ntStatus);
3755 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3757 else if( DirEntry->NameInformation.TargetName.Length > 0)
3760 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3763 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3764 DirEntry->NameInformation.TargetName.Buffer != NULL)
3766 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3769 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3771 DirEntry->NameInformation.TargetName.Length = 0;
3772 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3773 DirEntry->NameInformation.TargetName.Buffer = NULL;
3775 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3787 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3789 IN BOOLEAN FastCall)
3792 NTSTATUS ntStatus = STATUS_SUCCESS;
3793 LARGE_INTEGER liSystemTime;
3794 AFSDirEnumEntry *pDirEnumEntry = NULL;
3795 AFSFcb *pCurrentFcb = NULL;
3796 BOOLEAN bReleaseFcb = FALSE;
3797 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3803 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3807 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3808 AFS_TRACE_LEVEL_VERBOSE_2,
3809 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3810 &DirEntry->NameInformation.FileName,
3811 pObjectInfo->FileId.Cell,
3812 pObjectInfo->FileId.Volume,
3813 pObjectInfo->FileId.Vnode,
3814 pObjectInfo->FileId.Unique,
3818 // If this is a fake node then bail since the service knows nothing about it
3821 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3824 try_return( ntStatus);
3828 // This routine ensures that the current entry is valid by:
3830 // 1) Checking that the expiration time is non-zero and after where we
3834 KeQuerySystemTime( &liSystemTime);
3836 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3837 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3838 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3839 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3842 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3843 AFS_TRACE_LEVEL_VERBOSE_2,
3844 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3845 &DirEntry->NameInformation.FileName,
3846 pObjectInfo->FileId.Cell,
3847 pObjectInfo->FileId.Volume,
3848 pObjectInfo->FileId.Vnode,
3849 pObjectInfo->FileId.Unique);
3851 try_return( ntStatus);
3855 // This node requires updating
3858 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3863 if( !NT_SUCCESS( ntStatus))
3866 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3867 AFS_TRACE_LEVEL_ERROR,
3868 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3870 &DirEntry->NameInformation.FileName,
3871 pObjectInfo->FileId.Cell,
3872 pObjectInfo->FileId.Volume,
3873 pObjectInfo->FileId.Vnode,
3874 pObjectInfo->FileId.Unique,
3878 // Failed validation of node so return access-denied
3881 try_return( ntStatus);
3884 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3885 AFS_TRACE_LEVEL_VERBOSE,
3886 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3888 &DirEntry->NameInformation.FileName,
3889 pObjectInfo->FileId.Cell,
3890 pObjectInfo->FileId.Volume,
3891 pObjectInfo->FileId.Vnode,
3892 pObjectInfo->FileId.Unique,
3893 pObjectInfo->DataVersion.QuadPart,
3894 pDirEnumEntry->DataVersion.QuadPart,
3895 pDirEnumEntry->FileType);
3899 // Based on the file type, process the node
3902 switch( pDirEnumEntry->FileType)
3905 case AFS_FILE_TYPE_MOUNTPOINT:
3909 // Update the metadata for the entry
3912 ntStatus = AFSUpdateMetaData( DirEntry,
3915 if( NT_SUCCESS( ntStatus))
3918 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3924 case AFS_FILE_TYPE_SYMLINK:
3925 case AFS_FILE_TYPE_DFSLINK:
3929 // Update the metadata for the entry
3932 ntStatus = AFSUpdateMetaData( DirEntry,
3935 if( NT_SUCCESS( ntStatus))
3938 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3944 case AFS_FILE_TYPE_FILE:
3948 // For a file where the data version has become invalid we need to
3949 // fail any current extent requests and purge the cache for the file
3950 // Can't hold the Fcb resource while doing this
3953 if( pObjectInfo->Fcb != NULL &&
3954 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3955 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3958 pCurrentFcb = pObjectInfo->Fcb;
3960 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3963 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3964 AFS_TRACE_LEVEL_VERBOSE,
3965 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3966 &pCurrentFcb->NPFcb->Resource,
3967 PsGetCurrentThread());
3969 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3975 if( pCurrentFcb != NULL)
3978 IO_STATUS_BLOCK stIoStatus;
3979 BOOLEAN bPurgeExtents = FALSE;
3981 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3982 AFS_TRACE_LEVEL_VERBOSE_2,
3983 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3984 &DirEntry->NameInformation.FileName,
3985 pObjectInfo->FileId.Cell,
3986 pObjectInfo->FileId.Volume,
3987 pObjectInfo->FileId.Vnode,
3988 pObjectInfo->FileId.Unique);
3990 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3993 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3994 AFS_TRACE_LEVEL_VERBOSE,
3995 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
3996 &DirEntry->NameInformation.FileName,
3997 pObjectInfo->FileId.Cell,
3998 pObjectInfo->FileId.Volume,
3999 pObjectInfo->FileId.Vnode,
4000 pObjectInfo->FileId.Unique,
4001 pObjectInfo->DataVersion.LowPart,
4002 pDirEnumEntry->DataVersion.LowPart
4005 bPurgeExtents = TRUE;
4008 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4010 bPurgeExtents = TRUE;
4012 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4013 AFS_TRACE_LEVEL_VERBOSE,
4014 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4015 &DirEntry->NameInformation.FileName,
4016 pObjectInfo->FileId.Cell,
4017 pObjectInfo->FileId.Volume,
4018 pObjectInfo->FileId.Vnode,
4019 pObjectInfo->FileId.Unique);
4021 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4027 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4032 if( !NT_SUCCESS( stIoStatus.Status))
4035 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4036 AFS_TRACE_LEVEL_ERROR,
4037 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4038 &DirEntry->NameInformation.FileName,
4039 pObjectInfo->FileId.Cell,
4040 pObjectInfo->FileId.Volume,
4041 pObjectInfo->FileId.Vnode,
4042 pObjectInfo->FileId.Unique,
4044 stIoStatus.Information);
4046 ntStatus = stIoStatus.Status;
4052 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4058 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4059 AFS_TRACE_LEVEL_WARNING,
4060 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4061 &DirEntry->NameInformation.FileName,
4062 pObjectInfo->FileId.Cell,
4063 pObjectInfo->FileId.Volume,
4064 pObjectInfo->FileId.Vnode,
4065 pObjectInfo->FileId.Unique);
4067 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4071 __except( EXCEPTION_EXECUTE_HANDLER)
4073 ntStatus = GetExceptionCode();
4077 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4078 &DirEntry->NameInformation.FileName,
4079 pObjectInfo->FileId.Cell,
4080 pObjectInfo->FileId.Volume,
4081 pObjectInfo->FileId.Vnode,
4082 pObjectInfo->FileId.Unique,
4085 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4088 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4090 bReleaseFcb = FALSE;
4094 AFSFlushExtents( pCurrentFcb,
4101 // Update the metadata for the entry
4104 ntStatus = AFSUpdateMetaData( DirEntry,
4107 if( !NT_SUCCESS( ntStatus))
4110 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4111 AFS_TRACE_LEVEL_ERROR,
4112 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4113 &DirEntry->NameInformation.FileName,
4114 pObjectInfo->FileId.Cell,
4115 pObjectInfo->FileId.Volume,
4116 pObjectInfo->FileId.Vnode,
4117 pObjectInfo->FileId.Unique,
4123 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4126 // Update file sizes
4129 if( pObjectInfo->Fcb != NULL)
4131 FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4133 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4134 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4135 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4137 if ( pCCFileObject != NULL)
4139 CcSetFileSizes( pCCFileObject,
4140 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4146 case AFS_FILE_TYPE_DIRECTORY:
4149 AFSDirectoryCB *pCurrentDirEntry = NULL;
4151 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4155 // For a directory or root entry flush the content of
4156 // the directory enumeration.
4159 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4160 AFS_TRACE_LEVEL_VERBOSE,
4161 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4162 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4163 PsGetCurrentThread());
4165 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4168 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4169 AFS_TRACE_LEVEL_VERBOSE_2,
4170 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4171 &DirEntry->NameInformation.FileName,
4172 pObjectInfo->FileId.Cell,
4173 pObjectInfo->FileId.Volume,
4174 pObjectInfo->FileId.Vnode,
4175 pObjectInfo->FileId.Unique);
4177 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4180 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4183 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4186 if( !NT_SUCCESS( ntStatus))
4189 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4190 AFS_TRACE_LEVEL_ERROR,
4191 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4192 &DirEntry->NameInformation.FileName,
4193 pObjectInfo->FileId.Cell,
4194 pObjectInfo->FileId.Volume,
4195 pObjectInfo->FileId.Vnode,
4196 pObjectInfo->FileId.Unique,
4204 // Update the metadata for the entry
4207 ntStatus = AFSUpdateMetaData( DirEntry,
4210 if( NT_SUCCESS( ntStatus))
4213 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4221 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4222 AFS_TRACE_LEVEL_WARNING,
4223 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4224 pObjectInfo->FileType,
4226 &DirEntry->NameInformation.FileName,
4227 pObjectInfo->FileId.Cell,
4228 pObjectInfo->FileId.Volume,
4229 pObjectInfo->FileId.Vnode,
4230 pObjectInfo->FileId.Unique);
4240 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4243 if( pDirEnumEntry != NULL)
4246 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4254 AFSInitializeSpecialShareNameList()
4257 NTSTATUS ntStatus = STATUS_SUCCESS;
4258 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4259 AFSObjectInfoCB *pObjectInfoCB = NULL;
4260 UNICODE_STRING uniShareName;
4261 ULONG ulEntryLength = 0;
4262 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4267 RtlInitUnicodeString( &uniShareName,
4270 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4273 if( pObjectInfoCB == NULL)
4276 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4279 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4280 AFS_TRACE_LEVEL_VERBOSE,
4281 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
4284 pObjectInfoCB->ObjectReferenceCount = 1;
4286 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4288 ulEntryLength = sizeof( AFSDirectoryCB) +
4289 uniShareName.Length;
4291 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4295 if( pDirNode == NULL)
4298 AFSDeleteObjectInfo( pObjectInfoCB);
4300 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4303 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4304 sizeof( AFSNonPagedDirectoryCB),
4305 AFS_DIR_ENTRY_NP_TAG);
4307 if( pNonPagedDirEntry == NULL)
4310 ExFreePool( pDirNode);
4312 AFSDeleteObjectInfo( pObjectInfoCB);
4314 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4317 RtlZeroMemory( pDirNode,
4320 RtlZeroMemory( pNonPagedDirEntry,
4321 sizeof( AFSNonPagedDirectoryCB));
4323 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4325 pDirNode->NonPaged = pNonPagedDirEntry;
4327 pDirNode->ObjectInformation = pObjectInfoCB;
4333 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
4335 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4337 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4339 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4341 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4342 uniShareName.Buffer,
4343 pDirNode->NameInformation.FileName.Length);
4345 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4348 AFSSpecialShareNames = pDirNode;
4350 pLastDirNode = pDirNode;
4352 RtlInitUnicodeString( &uniShareName,
4355 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4358 if( pObjectInfoCB == NULL)
4361 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4364 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4365 AFS_TRACE_LEVEL_VERBOSE,
4366 "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
4369 pObjectInfoCB->ObjectReferenceCount = 1;
4371 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4373 ulEntryLength = sizeof( AFSDirectoryCB) +
4374 uniShareName.Length;
4376 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4380 if( pDirNode == NULL)
4383 AFSDeleteObjectInfo( pObjectInfoCB);
4385 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4388 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4389 sizeof( AFSNonPagedDirectoryCB),
4390 AFS_DIR_ENTRY_NP_TAG);
4392 if( pNonPagedDirEntry == NULL)
4395 ExFreePool( pDirNode);
4397 AFSDeleteObjectInfo( pObjectInfoCB);
4399 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4402 RtlZeroMemory( pDirNode,
4405 RtlZeroMemory( pNonPagedDirEntry,
4406 sizeof( AFSNonPagedDirectoryCB));
4408 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4410 pDirNode->NonPaged = pNonPagedDirEntry;
4412 pDirNode->ObjectInformation = pObjectInfoCB;
4418 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
4420 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4422 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4424 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4426 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4427 uniShareName.Buffer,
4428 pDirNode->NameInformation.FileName.Length);
4430 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4433 pLastDirNode->ListEntry.fLink = pDirNode;
4435 pDirNode->ListEntry.bLink = pLastDirNode;
4437 pLastDirNode = pDirNode;
4439 RtlInitUnicodeString( &uniShareName,
4442 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4445 if( pObjectInfoCB == NULL)
4448 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4451 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4452 AFS_TRACE_LEVEL_VERBOSE,
4453 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4456 pObjectInfoCB->ObjectReferenceCount = 1;
4458 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4460 ulEntryLength = sizeof( AFSDirectoryCB) +
4461 uniShareName.Length;
4463 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4467 if( pDirNode == NULL)
4470 AFSDeleteObjectInfo( pObjectInfoCB);
4472 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4475 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4476 sizeof( AFSNonPagedDirectoryCB),
4477 AFS_DIR_ENTRY_NP_TAG);
4479 if( pNonPagedDirEntry == NULL)
4482 ExFreePool( pDirNode);
4484 AFSDeleteObjectInfo( pObjectInfoCB);
4486 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4489 RtlZeroMemory( pDirNode,
4492 RtlZeroMemory( pNonPagedDirEntry,
4493 sizeof( AFSNonPagedDirectoryCB));
4495 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4497 pDirNode->NonPaged = pNonPagedDirEntry;
4499 pDirNode->ObjectInformation = pObjectInfoCB;
4505 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4507 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4509 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4511 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4513 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4514 uniShareName.Buffer,
4515 pDirNode->NameInformation.FileName.Length);
4517 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4520 pLastDirNode->ListEntry.fLink = pDirNode;
4522 pDirNode->ListEntry.bLink = pLastDirNode;
4526 if( !NT_SUCCESS( ntStatus))
4529 if( AFSSpecialShareNames != NULL)
4532 pDirNode = AFSSpecialShareNames;
4534 while( pDirNode != NULL)
4537 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4539 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4541 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4543 ExFreePool( pDirNode->NonPaged);
4545 ExFreePool( pDirNode);
4547 pDirNode = pLastDirNode;
4550 AFSSpecialShareNames = NULL;
4559 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4560 IN UNICODE_STRING *SecondaryName)
4563 AFSDirectoryCB *pDirectoryCB = NULL;
4564 ULONGLONG ullHash = 0;
4565 UNICODE_STRING uniFullShareName;
4571 // Build up the entire name here. We are guaranteed that if there is a
4572 // secondary name, it is pointing to a portion of the share name buffer
4575 if( SecondaryName->Length > 0 &&
4576 SecondaryName->Buffer != NULL)
4579 uniFullShareName = *SecondaryName;
4582 // The calling routine strips off the leading slash so add it back in
4585 uniFullShareName.Buffer--;
4586 uniFullShareName.Length += sizeof( WCHAR);
4587 uniFullShareName.MaximumLength += sizeof( WCHAR);
4590 // And the share name
4593 uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
4594 uniFullShareName.Length += ShareName->Length;
4595 uniFullShareName.MaximumLength += ShareName->Length;
4600 uniFullShareName = *ShareName;
4604 // Generate our hash value
4607 ullHash = AFSGenerateCRC( &uniFullShareName,
4611 // Loop through our special share names to see if this is one of them
4614 pDirectoryCB = AFSSpecialShareNames;
4616 while( pDirectoryCB != NULL)
4619 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4625 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4629 return pDirectoryCB;
4633 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4637 // Block on the queue flush event
4640 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4650 AFSWaitOnQueuedReleases()
4653 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4656 // Block on the queue flush event
4659 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4669 AFSIsEqualFID( IN AFSFileID *FileId1,
4670 IN AFSFileID *FileId2)
4673 BOOLEAN bIsEqual = FALSE;
4675 if( FileId1->Hash == FileId2->Hash &&
4676 FileId1->Unique == FileId2->Unique &&
4677 FileId1->Vnode == FileId2->Vnode &&
4678 FileId1->Volume == FileId2->Volume &&
4679 FileId1->Cell == FileId2->Cell)
4689 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4692 NTSTATUS ntStatus = STATUS_SUCCESS;
4693 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4698 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4701 // Reset the directory list information
4704 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4706 while( pCurrentDirEntry != NULL)
4709 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4711 if( pCurrentDirEntry->OpenReferenceCount == 0)
4714 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4715 AFS_TRACE_LEVEL_VERBOSE,
4716 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4718 &pCurrentDirEntry->NameInformation.FileName);
4720 AFSDeleteDirEntry( ObjectInfoCB,
4726 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4727 AFS_TRACE_LEVEL_VERBOSE,
4728 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4730 &pCurrentDirEntry->NameInformation.FileName);
4732 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4734 AFSRemoveNameEntry( ObjectInfoCB,
4738 pCurrentDirEntry = pNextDirEntry;
4741 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4743 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4745 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4747 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4749 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4751 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4753 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4754 AFS_TRACE_LEVEL_VERBOSE,
4755 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4756 ObjectInfoCB->FileId.Cell,
4757 ObjectInfoCB->FileId.Volume,
4758 ObjectInfoCB->FileId.Vnode,
4759 ObjectInfoCB->FileId.Unique);
4766 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4769 NTSTATUS ntStatus = STATUS_SUCCESS;
4770 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4771 UNICODE_STRING uniFullName;
4776 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4777 AFS_TRACE_LEVEL_VERBOSE,
4778 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4779 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4780 PsGetCurrentThread());
4782 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4785 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4788 try_return( ntStatus);
4792 // Initialize the root information
4795 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4798 // Enumerate the shares in the volume
4801 ntStatus = AFSEnumerateDirectory( AuthGroup,
4802 &AFSGlobalRoot->ObjectInformation,
4805 if( !NT_SUCCESS( ntStatus))
4808 try_return( ntStatus);
4811 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4814 // Indicate the node is initialized
4817 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4819 uniFullName.MaximumLength = PAGE_SIZE;
4820 uniFullName.Length = 0;
4822 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4823 uniFullName.MaximumLength,
4824 AFS_GENERIC_MEMORY_12_TAG);
4826 if( uniFullName.Buffer == NULL)
4830 // Reset the directory content
4833 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4835 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4837 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4841 // Populate our list of entries in the NP enumeration list
4844 while( pDirGlobalDirNode != NULL)
4847 uniFullName.Buffer[ 0] = L'\\';
4848 uniFullName.Buffer[ 1] = L'\\';
4850 uniFullName.Length = 2 * sizeof( WCHAR);
4852 RtlCopyMemory( &uniFullName.Buffer[ 2],
4853 AFSServerName.Buffer,
4854 AFSServerName.Length);
4856 uniFullName.Length += AFSServerName.Length;
4858 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4860 uniFullName.Length += sizeof( WCHAR);
4862 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4863 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4864 pDirGlobalDirNode->NameInformation.FileName.Length);
4866 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4868 AFSAddConnectionEx( &uniFullName,
4869 RESOURCEDISPLAYTYPE_SHARE,
4872 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4875 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
4879 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4886 AFSIsRelativeName( IN UNICODE_STRING *Name)
4889 BOOLEAN bIsRelative = FALSE;
4891 if( Name->Buffer[ 0] != L'\\')
4901 AFSUpdateName( IN UNICODE_STRING *Name)
4906 while( usIndex < Name->Length/sizeof( WCHAR))
4909 if( Name->Buffer[ usIndex] == L'/')
4912 Name->Buffer[ usIndex] = L'\\';
4922 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4923 IN OUT ULONG *Flags,
4924 IN WCHAR *NameBuffer,
4925 IN USHORT NameLength)
4928 NTSTATUS ntStatus = STATUS_SUCCESS;
4929 WCHAR *pTmpBuffer = NULL;
4935 // If we have enough space then just move in the name otherwise
4936 // allocate a new buffer
4939 if( TargetName->Length < NameLength)
4942 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4944 AFS_NAME_BUFFER_FIVE_TAG);
4946 if( pTmpBuffer == NULL)
4949 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4952 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4955 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
4958 TargetName->MaximumLength = NameLength;
4960 TargetName->Buffer = pTmpBuffer;
4962 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4965 TargetName->Length = NameLength;
4967 RtlCopyMemory( TargetName->Buffer,
4969 TargetName->Length);
4972 // Update the name in the buffer
4975 AFSUpdateName( TargetName);
4986 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4987 IN ULONG InitialElementCount)
4990 AFSNameArrayHdr *pNameArray = NULL;
4991 AFSNameArrayCB *pCurrentElement = NULL;
4992 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4998 if( InitialElementCount == 0)
5001 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
5004 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
5005 sizeof( AFSNameArrayHdr) +
5006 (InitialElementCount * sizeof( AFSNameArrayCB)),
5007 AFS_NAME_ARRAY_TAG);
5009 if( pNameArray == NULL)
5012 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5013 AFS_TRACE_LEVEL_ERROR,
5014 "AFSInitNameArray Failed to allocate name array\n");
5016 try_return( pNameArray);
5019 RtlZeroMemory( pNameArray,
5020 sizeof( AFSNameArrayHdr) +
5021 (InitialElementCount * sizeof( AFSNameArrayCB)));
5023 pNameArray->MaxElementCount = InitialElementCount;
5025 if( DirectoryCB != NULL)
5028 pCurrentElement = &pNameArray->ElementArray[ 0];
5030 pNameArray->CurrentEntry = pCurrentElement;
5032 pNameArray->Count = 1;
5034 pNameArray->LinkCount = 0;
5036 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5038 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5039 AFS_TRACE_LEVEL_VERBOSE,
5040 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
5041 &DirectoryCB->NameInformation.FileName,
5045 pCurrentElement->DirectoryCB = DirectoryCB;
5047 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5049 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5051 if( pCurrentElement->FileId.Vnode == 1)
5054 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5057 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5058 AFS_TRACE_LEVEL_VERBOSE,
5059 "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5061 pCurrentElement->DirectoryCB,
5062 pCurrentElement->FileId.Cell,
5063 pCurrentElement->FileId.Volume,
5064 pCurrentElement->FileId.Vnode,
5065 pCurrentElement->FileId.Unique,
5066 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5067 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5079 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
5080 IN UNICODE_STRING *Path,
5081 IN AFSDirectoryCB *DirectoryCB)
5084 NTSTATUS ntStatus = STATUS_SUCCESS;
5085 AFSNameArrayCB *pCurrentElement = NULL;
5086 UNICODE_STRING uniComponentName, uniRemainingPath;
5087 AFSObjectInfoCB *pCurrentObject = NULL;
5088 ULONG ulTotalCount = 0;
5090 USHORT usLength = 0;
5096 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5097 AFS_TRACE_LEVEL_VERBOSE,
5098 "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5102 DirectoryCB->ObjectInformation->FileId.Cell,
5103 DirectoryCB->ObjectInformation->FileId.Volume,
5104 DirectoryCB->ObjectInformation->FileId.Vnode,
5105 DirectoryCB->ObjectInformation->FileId.Unique,
5106 &DirectoryCB->NameInformation.FileName,
5107 DirectoryCB->ObjectInformation->FileType);
5110 // Init some info in the header
5113 pCurrentElement = &NameArray->ElementArray[ 0];
5115 NameArray->CurrentEntry = pCurrentElement;
5118 // The first entry points at the root
5121 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
5123 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5125 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5126 AFS_TRACE_LEVEL_VERBOSE,
5127 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
5128 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5129 pCurrentElement->DirectoryCB,
5132 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
5134 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
5136 pCurrentElement->Flags = 0;
5138 if( pCurrentElement->FileId.Vnode == 1)
5141 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5144 NameArray->Count = 1;
5146 NameArray->LinkCount = 0;
5148 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5149 AFS_TRACE_LEVEL_VERBOSE,
5150 "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5152 pCurrentElement->DirectoryCB,
5153 pCurrentElement->FileId.Cell,
5154 pCurrentElement->FileId.Volume,
5155 pCurrentElement->FileId.Vnode,
5156 pCurrentElement->FileId.Unique,
5157 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5158 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5161 // If the root is the parent then we are done ...
5164 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
5166 try_return( ntStatus);
5178 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
5179 IN AFSNameArrayHdr *RelatedNameArray,
5180 IN AFSDirectoryCB *DirectoryCB)
5183 NTSTATUS ntStatus = STATUS_SUCCESS;
5184 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
5185 UNICODE_STRING uniComponentName, uniRemainingPath;
5186 AFSObjectInfoCB *pObjectInfo = NULL;
5187 ULONG ulTotalCount = 0;
5189 USHORT usLength = 0;
5195 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5196 AFS_TRACE_LEVEL_VERBOSE,
5197 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5201 DirectoryCB->ObjectInformation->FileId.Cell,
5202 DirectoryCB->ObjectInformation->FileId.Volume,
5203 DirectoryCB->ObjectInformation->FileId.Vnode,
5204 DirectoryCB->ObjectInformation->FileId.Unique,
5205 &DirectoryCB->NameInformation.FileName,
5206 DirectoryCB->ObjectInformation->FileType);
5209 // Init some info in the header
5212 pCurrentElement = &NameArray->ElementArray[ 0];
5214 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5216 NameArray->Count = 0;
5218 NameArray->LinkCount = RelatedNameArray->LinkCount;
5221 // Populate the name array with the data from the related array
5227 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5229 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5231 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5233 pCurrentElement->Flags = 0;
5235 if( pCurrentElement->FileId.Vnode == 1)
5238 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5241 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5243 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5244 AFS_TRACE_LEVEL_VERBOSE,
5245 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
5246 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5247 pCurrentElement->DirectoryCB,
5250 lCount = InterlockedIncrement( &NameArray->Count);
5252 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5253 AFS_TRACE_LEVEL_VERBOSE,
5254 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5257 pCurrentElement->DirectoryCB,
5258 pCurrentElement->FileId.Cell,
5259 pCurrentElement->FileId.Volume,
5260 pCurrentElement->FileId.Vnode,
5261 pCurrentElement->FileId.Unique,
5262 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5263 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5265 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5266 NameArray->Count == RelatedNameArray->Count)
5278 pCurrentRelatedElement++;
5281 NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
5288 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5291 NTSTATUS ntStatus = STATUS_SUCCESS;
5292 AFSNameArrayCB *pCurrentElement = NULL;
5293 LONG lCount, lElement;
5298 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5299 AFS_TRACE_LEVEL_VERBOSE,
5300 "AFSFreeNameArray [NA:%p]\n",
5303 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5306 pCurrentElement = &NameArray->ElementArray[ lElement];
5308 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5310 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5311 AFS_TRACE_LEVEL_VERBOSE,
5312 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
5313 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5314 pCurrentElement->DirectoryCB,
5318 AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
5325 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5326 IN AFSDirectoryCB *DirectoryCB)
5329 NTSTATUS ntStatus = STATUS_SUCCESS;
5330 AFSNameArrayCB *pCurrentElement = NULL;
5336 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5337 AFS_TRACE_LEVEL_VERBOSE,
5338 "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5341 DirectoryCB->ObjectInformation->FileId.Cell,
5342 DirectoryCB->ObjectInformation->FileId.Volume,
5343 DirectoryCB->ObjectInformation->FileId.Vnode,
5344 DirectoryCB->ObjectInformation->FileId.Unique,
5345 &DirectoryCB->NameInformation.FileName,
5346 DirectoryCB->ObjectInformation->FileType);
5348 if( NameArray->Count == NameArray->MaxElementCount)
5351 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5352 AFS_TRACE_LEVEL_ERROR,
5353 "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
5356 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5359 for ( lCount = 0; lCount < NameArray->Count; lCount++)
5362 if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
5363 &DirectoryCB->ObjectInformation->FileId) )
5366 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5367 AFS_TRACE_LEVEL_WARNING,
5368 "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
5371 STATUS_ACCESS_DENIED);
5373 try_return( ntStatus = STATUS_ACCESS_DENIED);
5377 if( NameArray->Count > 0)
5380 NameArray->CurrentEntry++;
5384 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5387 pCurrentElement = NameArray->CurrentEntry;
5389 lCount = InterlockedIncrement( &NameArray->Count);
5391 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5393 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5394 AFS_TRACE_LEVEL_VERBOSE,
5395 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
5396 &DirectoryCB->NameInformation.FileName,
5400 pCurrentElement->DirectoryCB = DirectoryCB;
5402 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5404 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5406 pCurrentElement->Flags = 0;
5408 if( pCurrentElement->FileId.Vnode == 1)
5411 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5414 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5415 AFS_TRACE_LEVEL_VERBOSE,
5416 "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5418 NameArray->Count - 1,
5419 pCurrentElement->DirectoryCB,
5420 pCurrentElement->FileId.Cell,
5421 pCurrentElement->FileId.Volume,
5422 pCurrentElement->FileId.Vnode,
5423 pCurrentElement->FileId.Unique,
5424 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5425 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5436 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5439 AFSDirectoryCB *pDirectoryCB = NULL;
5440 AFSNameArrayCB *pCurrentElement = NULL;
5441 BOOLEAN bVolumeRoot = FALSE;
5447 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5448 AFS_TRACE_LEVEL_VERBOSE,
5449 "AFSBackupEntry [NA:%p]\n",
5452 if( NameArray->Count == 0)
5455 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5456 AFS_TRACE_LEVEL_ERROR,
5457 "AFSBackupEntry [NA:%p] No more entries\n",
5460 try_return( pCurrentElement);
5463 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5465 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5466 AFS_TRACE_LEVEL_VERBOSE,
5467 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5468 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5469 NameArray->CurrentEntry->DirectoryCB,
5472 NameArray->CurrentEntry->DirectoryCB = NULL;
5474 lCount = InterlockedDecrement( &NameArray->Count);
5478 NameArray->CurrentEntry = NULL;
5480 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5481 AFS_TRACE_LEVEL_ERROR,
5482 "AFSBackupEntry [NA:%p] No more entries\n",
5488 bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5490 NameArray->CurrentEntry--;
5492 pCurrentElement = NameArray->CurrentEntry;
5494 pDirectoryCB = pCurrentElement->DirectoryCB;
5496 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5497 AFS_TRACE_LEVEL_VERBOSE,
5498 "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5500 NameArray->Count - 1,
5501 pCurrentElement->DirectoryCB,
5502 pCurrentElement->FileId.Cell,
5503 pCurrentElement->FileId.Volume,
5504 pCurrentElement->FileId.Vnode,
5505 pCurrentElement->FileId.Unique,
5506 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5507 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5510 // If the entry we are removing is a volume root,
5511 // we must remove the mount point entry as well.
5512 // If the NameArray was constructed by checking the
5513 // share name via the service, the name array can
5514 // contain two volume roots in sequence without a
5515 // mount point separating them.
5519 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
5522 pDirectoryCB = AFSBackupEntry( NameArray);
5532 return pDirectoryCB;
5536 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5539 AFSDirectoryCB *pDirEntry = NULL;
5540 AFSNameArrayCB *pElement = NULL;
5545 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5546 AFS_TRACE_LEVEL_VERBOSE,
5547 "AFSGetParentEntry [NA:%p]\n",
5550 if( NameArray->Count == 0 ||
5551 NameArray->Count == 1)
5554 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5555 AFS_TRACE_LEVEL_ERROR,
5556 "AFSGetParentEntry [NA:%p] No more entries\n",
5559 try_return( pDirEntry = NULL);
5562 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5564 pDirEntry = pElement->DirectoryCB;
5566 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5567 AFS_TRACE_LEVEL_VERBOSE,
5568 "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5570 NameArray->Count - 2,
5571 pElement->DirectoryCB,
5572 pElement->FileId.Cell,
5573 pElement->FileId.Volume,
5574 pElement->FileId.Vnode,
5575 pElement->FileId.Unique,
5576 &pElement->DirectoryCB->NameInformation.FileName,
5577 pElement->DirectoryCB->ObjectInformation->FileType);
5588 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5589 IN AFSDirectoryCB *DirectoryCB)
5592 AFSNameArrayCB *pCurrentElement = NULL;
5593 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5594 LONG lCount, lElement;
5599 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5600 AFS_TRACE_LEVEL_VERBOSE,
5601 "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5604 DirectoryCB->ObjectInformation->FileId.Cell,
5605 DirectoryCB->ObjectInformation->FileId.Volume,
5606 DirectoryCB->ObjectInformation->FileId.Vnode,
5607 DirectoryCB->ObjectInformation->FileId.Unique,
5608 &DirectoryCB->NameInformation.FileName,
5609 DirectoryCB->ObjectInformation->FileType);
5611 // Dereference previous name array contents
5614 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5617 pCurrentElement = &NameArray->ElementArray[ lElement];
5619 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5621 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5622 AFS_TRACE_LEVEL_VERBOSE,
5623 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5624 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5625 pCurrentElement->DirectoryCB,
5629 RtlZeroMemory( NameArray,
5630 sizeof( AFSNameArrayHdr) +
5631 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5633 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5635 if( DirectoryCB != NULL)
5638 pCurrentElement = &NameArray->ElementArray[ 0];
5640 NameArray->CurrentEntry = pCurrentElement;
5642 NameArray->Count = 1;
5644 NameArray->LinkCount = 0;
5646 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5648 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5649 AFS_TRACE_LEVEL_VERBOSE,
5650 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5651 &DirectoryCB->NameInformation.FileName,
5655 pCurrentElement->DirectoryCB = DirectoryCB;
5657 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5659 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5661 pCurrentElement->Flags = 0;
5663 if( pCurrentElement->FileId.Vnode == 1)
5666 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5669 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5670 AFS_TRACE_LEVEL_VERBOSE,
5671 "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5673 pCurrentElement->DirectoryCB,
5674 pCurrentElement->FileId.Cell,
5675 pCurrentElement->FileId.Volume,
5676 pCurrentElement->FileId.Vnode,
5677 pCurrentElement->FileId.Unique,
5678 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5679 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5687 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5690 AFSNameArrayCB *pCurrentElement = NULL;
5692 pCurrentElement = &NameArray->ElementArray[ 0];
5694 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5696 while( pCurrentElement->DirectoryCB != NULL)
5699 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5700 pCurrentElement->FileId.Cell,
5701 pCurrentElement->FileId.Volume,
5702 pCurrentElement->FileId.Vnode,
5703 pCurrentElement->FileId.Unique,
5704 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5709 AFSPrint("AFSDumpNameArray End\n\n");
5715 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5720 // Depending on the type of node, set the event
5723 switch( Fcb->Header.NodeTypeCode)
5726 case AFS_DIRECTORY_FCB:
5731 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5741 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5747 // Depending on the type of node, set the event
5750 switch( Fcb->Header.NodeTypeCode)
5753 case AFS_DIRECTORY_FCB:
5758 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5760 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5770 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5773 BOOLEAN bIsInProcess = FALSE;
5778 if( ObjectInfo->Fcb == NULL)
5781 try_return( bIsInProcess);
5784 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5787 case AFS_DIRECTORY_FCB:
5792 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5795 bIsInProcess = TRUE;
5807 return bIsInProcess;
5811 AFSVerifyVolume( IN ULONGLONG ProcessId,
5812 IN AFSVolumeCB *VolumeCB)
5815 NTSTATUS ntStatus = STATUS_SUCCESS;
5822 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5825 NTSTATUS ntStatus = STATUS_SUCCESS;
5826 AFSObjectInfoCB *pObjectInfoCB = NULL;
5827 AFSDirectoryCB *pDirNode = NULL;
5828 ULONG ulEntryLength = 0;
5829 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5835 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5838 if( pObjectInfoCB == NULL)
5841 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5844 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5845 AFS_TRACE_LEVEL_VERBOSE,
5846 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5849 pObjectInfoCB->ObjectReferenceCount = 1;
5851 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5853 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5855 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5857 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5861 if( pDirNode == NULL)
5864 AFSDeleteObjectInfo( pObjectInfoCB);
5866 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5869 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5870 sizeof( AFSNonPagedDirectoryCB),
5871 AFS_DIR_ENTRY_NP_TAG);
5873 if( pNonPagedDirEntry == NULL)
5876 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5879 RtlZeroMemory( pDirNode,
5882 RtlZeroMemory( pNonPagedDirEntry,
5883 sizeof( AFSNonPagedDirectoryCB));
5885 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5887 pDirNode->NonPaged = pNonPagedDirEntry;
5889 pDirNode->ObjectInformation = pObjectInfoCB;
5891 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5897 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5899 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5901 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5903 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5905 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5906 AFSPIOCtlName.Buffer,
5907 pDirNode->NameInformation.FileName.Length);
5909 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5912 if ( InterlockedCompareExchangePointer( (PVOID *)&ObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5915 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5916 AFS_TRACE_LEVEL_WARNING,
5917 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %08lX pFcb %08lX\n",
5918 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5922 // Increment the open reference and handle on the node
5925 lCount = AFSObjectInfoIncrement( pDirNode->ObjectInformation);
5927 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
5928 AFS_TRACE_LEVEL_VERBOSE,
5929 "AFSInitPIOCtlDirectoryCB Increment count on Object %08lX Cnt %d\n",
5930 pDirNode->ObjectInformation,
5933 try_return( ntStatus = STATUS_REPARSE);
5938 if ( ntStatus != STATUS_SUCCESS)
5941 if ( pDirNode != NULL)
5944 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5947 if( pNonPagedDirEntry != NULL)
5950 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5952 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5955 if ( pObjectInfoCB != NULL)
5958 AFSDeleteObjectInfo( pObjectInfoCB);
5967 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5968 IN AFSDirectoryCB *DirectoryCB,
5969 IN UNICODE_STRING *ParentPathName,
5970 IN AFSNameArrayHdr *RelatedNameArray,
5972 OUT AFSFileInfoCB *FileInfo)
5975 NTSTATUS ntStatus = STATUS_SUCCESS;
5976 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
5977 UNICODE_STRING uniFullPathName;
5978 AFSNameArrayHdr *pNameArray = NULL;
5979 AFSVolumeCB *pVolumeCB = NULL;
5980 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5981 WCHAR *pwchBuffer = NULL;
5982 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5983 ULONG ulNameDifference = 0;
5990 // Retrieve a target name for the entry
5993 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5996 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5999 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6001 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6006 if( !NT_SUCCESS( ntStatus) ||
6007 pDirEntry->TargetNameLength == 0)
6010 if( pDirEntry != NULL)
6013 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6016 try_return( ntStatus);
6019 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6022 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6026 // Update the target name
6029 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6030 &DirectoryCB->Flags,
6031 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6032 (USHORT)pDirEntry->TargetNameLength);
6034 if( !NT_SUCCESS( ntStatus))
6037 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6039 try_return( ntStatus);
6043 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6047 // Need to pass the full path in for parsing.
6050 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
6053 uniFullPathName.Length = 0;
6054 uniFullPathName.MaximumLength = ParentPathName->Length +
6056 DirectoryCB->NameInformation.TargetName.Length;
6058 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6059 uniFullPathName.MaximumLength,
6060 AFS_NAME_BUFFER_SIX_TAG);
6062 if( uniFullPathName.Buffer == NULL)
6065 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6067 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6070 pwchBuffer = uniFullPathName.Buffer;
6072 RtlZeroMemory( uniFullPathName.Buffer,
6073 uniFullPathName.MaximumLength);
6075 RtlCopyMemory( uniFullPathName.Buffer,
6076 ParentPathName->Buffer,
6077 ParentPathName->Length);
6079 uniFullPathName.Length = ParentPathName->Length;
6081 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
6082 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
6085 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
6087 uniFullPathName.Length += sizeof( WCHAR);
6090 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
6091 DirectoryCB->NameInformation.TargetName.Buffer,
6092 DirectoryCB->NameInformation.TargetName.Length);
6094 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
6096 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
6097 uniParsedName.MaximumLength = uniParsedName.Length;
6099 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
6101 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6104 // We populate up to the current parent
6107 if( RelatedNameArray != NULL)
6110 pNameArray = AFSInitNameArray( NULL,
6111 RelatedNameArray->MaxElementCount);
6113 if( pNameArray == NULL)
6116 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6119 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
6126 pNameArray = AFSInitNameArray( NULL,
6129 if( pNameArray == NULL)
6132 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6135 ntStatus = AFSPopulateNameArray( pNameArray,
6140 if( !NT_SUCCESS( ntStatus))
6143 try_return( ntStatus);
6146 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
6148 pParentDirEntry = ParentDirectoryCB;
6153 uniFullPathName.Length = 0;
6154 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6156 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6157 uniFullPathName.MaximumLength,
6158 AFS_NAME_BUFFER_SEVEN_TAG);
6160 if( uniFullPathName.Buffer == NULL)
6163 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6165 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6168 pwchBuffer = uniFullPathName.Buffer;
6170 RtlZeroMemory( uniFullPathName.Buffer,
6171 uniFullPathName.MaximumLength);
6173 RtlCopyMemory( uniFullPathName.Buffer,
6174 DirectoryCB->NameInformation.TargetName.Buffer,
6175 DirectoryCB->NameInformation.TargetName.Length);
6177 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6180 // This name should begin with the \afs server so parse it off and check it
6183 FsRtlDissectName( uniFullPathName,
6187 if( RtlCompareUnicodeString( &uniComponentName,
6192 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6194 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6195 AFS_TRACE_LEVEL_ERROR,
6196 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
6199 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
6202 uniFullPathName = uniRemainingPath;
6204 uniParsedName = uniFullPathName;
6206 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6208 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6214 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6217 if( pNameArray == NULL)
6220 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6223 pVolumeCB = AFSGlobalRoot;
6225 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6229 // Increment the ref count on the volume and dir entry for correct processing below
6232 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6234 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6235 AFS_TRACE_LEVEL_VERBOSE,
6236 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
6240 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6242 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6243 AFS_TRACE_LEVEL_VERBOSE,
6244 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6245 &pParentDirEntry->NameInformation.FileName,
6250 ntStatus = AFSLocateNameEntry( NULL,
6255 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
6261 if( !NT_SUCCESS( ntStatus))
6265 // The volume lock was released on failure above
6266 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6269 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6272 if( pVolumeCB != NULL)
6275 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6277 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6278 AFS_TRACE_LEVEL_VERBOSE,
6279 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
6284 if( pDirectoryEntry != NULL)
6287 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6289 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6290 AFS_TRACE_LEVEL_VERBOSE,
6291 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6292 &pDirectoryEntry->NameInformation.FileName,
6300 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6302 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6303 AFS_TRACE_LEVEL_VERBOSE,
6304 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6305 &pParentDirEntry->NameInformation.FileName,
6314 try_return( ntStatus);
6318 // Store off the information
6321 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6324 // Check for the mount point being returned
6327 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
6330 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6332 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
6333 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6336 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6339 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6344 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6348 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6350 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6352 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6354 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6356 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6358 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6361 // Remove the reference made above
6364 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6366 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6367 AFS_TRACE_LEVEL_VERBOSE,
6368 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
6369 &pDirectoryEntry->NameInformation.FileName,
6376 if( pDirEntry != NULL)
6379 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6382 if( pVolumeCB != NULL)
6385 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6387 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6388 AFS_TRACE_LEVEL_VERBOSE,
6389 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
6394 if( pNameArray != NULL)
6397 AFSFreeNameArray( pNameArray);
6400 if( pwchBuffer != NULL)
6404 // Always free the buffer that we allocated as AFSLocateNameEntry
6405 // will not free it. If uniFullPathName.Buffer was allocated by
6406 // AFSLocateNameEntry, then we must free that as well.
6407 // Check that the uniFullPathName.Buffer in the string is not the same
6408 // offset by the length of the server name
6411 if( uniFullPathName.Length > 0 &&
6412 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6415 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6418 AFSExFreePoolWithTag( pwchBuffer, 0);
6426 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6427 IN ULONGLONG HashIndex)
6430 NTSTATUS ntStatus = STATUS_SUCCESS;
6431 AFSObjectInfoCB *pObjectInfo = NULL;
6437 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6438 sizeof( AFSObjectInfoCB),
6439 AFS_OBJECT_INFO_TAG);
6441 if( pObjectInfo == NULL)
6444 try_return( pObjectInfo);
6447 RtlZeroMemory( pObjectInfo,
6448 sizeof( AFSObjectInfoCB));
6450 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6451 sizeof( AFSNonPagedObjectInfoCB),
6452 AFS_NP_OBJECT_INFO_TAG);
6454 if( pObjectInfo->NonPagedInfo == NULL)
6457 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6459 try_return( pObjectInfo = NULL);
6462 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6464 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6466 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6468 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6470 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6472 if( ParentObjectInfo != NULL)
6474 lCount = AFSObjectInfoIncrement( ParentObjectInfo);
6478 // Initialize the access time
6481 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6487 // Insert the entry into the object tree and list
6490 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6492 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6495 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6500 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6501 &pObjectInfo->TreeEntry);
6503 ASSERT( NT_SUCCESS( ntStatus));
6507 // And the object list in the volume
6510 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6513 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6518 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6520 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6523 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6526 // Indicate the object is in the hash tree and linked list in the volume
6529 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6541 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo)
6546 if ( ObjectInfo->ObjectReferenceCount == 0)
6549 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6552 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6557 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6560 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6565 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6567 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6572 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6578 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo)
6583 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6586 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6591 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6593 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6595 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6598 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6601 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6609 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6612 BOOLEAN bAcquiredTreeLock = FALSE;
6615 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6618 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6620 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6623 bAcquiredTreeLock = TRUE;
6627 // Remove it from the tree and list if it was inserted
6630 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6633 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6634 &ObjectInfo->TreeEntry);
6637 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6640 if( ObjectInfo->ListEntry.fLink == NULL)
6643 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6645 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6648 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6654 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6657 if( ObjectInfo->ListEntry.bLink == NULL)
6660 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6662 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6665 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6671 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6675 if( ObjectInfo->ParentObjectInformation != NULL)
6678 lCount = AFSObjectInfoDecrement( ObjectInfo->ParentObjectInformation);
6681 if( bAcquiredTreeLock)
6684 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6688 // Release the fid in the service
6691 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6694 AFSReleaseFid( &ObjectInfo->FileId);
6697 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6699 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6701 AFSExFreePoolWithTag( ObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6703 AFSExFreePoolWithTag( ObjectInfo, AFS_OBJECT_INFO_TAG);
6709 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6710 OUT AFSDirectoryCB **TargetDirEntry)
6713 NTSTATUS ntStatus = STATUS_SUCCESS;
6714 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6715 UNICODE_STRING uniFullPathName;
6716 AFSNameArrayHdr *pNameArray = NULL;
6717 AFSVolumeCB *pVolumeCB = NULL;
6718 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6719 WCHAR *pwchBuffer = NULL;
6720 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6721 ULONG ulNameDifference = 0;
6728 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6729 DirectoryCB->ObjectInformation,
6733 if( !NT_SUCCESS( ntStatus))
6735 try_return( ntStatus);
6739 // Retrieve a target name for the entry
6742 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6745 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6748 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6750 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6755 if( !NT_SUCCESS( ntStatus) ||
6756 pDirEntry->TargetNameLength == 0)
6759 if( pDirEntry != NULL)
6762 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6765 try_return( ntStatus);
6768 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6771 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6775 // Update the target name
6778 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6779 &DirectoryCB->Flags,
6780 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6781 (USHORT)pDirEntry->TargetNameLength);
6783 if( !NT_SUCCESS( ntStatus))
6786 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6788 try_return( ntStatus);
6792 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6796 // Need to pass the full path in for parsing.
6799 uniFullPathName.Length = 0;
6800 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6802 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6803 uniFullPathName.MaximumLength,
6804 AFS_NAME_BUFFER_EIGHT_TAG);
6806 if( uniFullPathName.Buffer == NULL)
6809 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6811 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6814 pwchBuffer = uniFullPathName.Buffer;
6816 RtlZeroMemory( uniFullPathName.Buffer,
6817 uniFullPathName.MaximumLength);
6819 RtlCopyMemory( uniFullPathName.Buffer,
6820 DirectoryCB->NameInformation.TargetName.Buffer,
6821 DirectoryCB->NameInformation.TargetName.Length);
6823 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6826 // This name should begin with the \afs server so parse it off and chech it
6829 FsRtlDissectName( uniFullPathName,
6833 if( RtlCompareUnicodeString( &uniComponentName,
6839 // Try evaluating the full path
6842 uniFullPathName.Buffer = pwchBuffer;
6844 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6846 uniFullPathName.MaximumLength = uniFullPathName.Length;
6851 uniFullPathName = uniRemainingPath;
6854 uniParsedName = uniFullPathName;
6856 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6858 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6864 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6867 if( pNameArray == NULL)
6870 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6873 pVolumeCB = AFSGlobalRoot;
6875 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6877 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6879 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6880 AFS_TRACE_LEVEL_VERBOSE,
6881 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6885 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6887 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6888 AFS_TRACE_LEVEL_VERBOSE,
6889 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6890 &pParentDirEntry->NameInformation.FileName,
6895 ntStatus = AFSLocateNameEntry( NULL,
6906 if( !NT_SUCCESS( ntStatus))
6910 // The volume lock was released on failure above
6911 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6914 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6917 if( pVolumeCB != NULL)
6920 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6922 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6923 AFS_TRACE_LEVEL_VERBOSE,
6924 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
6929 if( pDirectoryEntry != NULL)
6932 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6934 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6935 AFS_TRACE_LEVEL_VERBOSE,
6936 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6937 &pDirectoryEntry->NameInformation.FileName,
6945 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6947 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6948 AFS_TRACE_LEVEL_VERBOSE,
6949 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6950 &pParentDirEntry->NameInformation.FileName,
6959 try_return( ntStatus);
6963 // Pass back the target dir entry for this request
6966 *TargetDirEntry = pDirectoryEntry;
6970 if( pDirEntry != NULL)
6973 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6976 if( pVolumeCB != NULL)
6979 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6981 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6982 AFS_TRACE_LEVEL_VERBOSE,
6983 "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
6988 if( pNameArray != NULL)
6991 AFSFreeNameArray( pNameArray);
6994 if( pwchBuffer != NULL)
6998 // Always free the buffer that we allocated as AFSLocateNameEntry
6999 // will not free it. If uniFullPathName.Buffer was allocated by
7000 // AFSLocateNameEntry, then we must free that as well.
7001 // Check that the uniFullPathName.Buffer in the string is not the same
7002 // offset by the length of the server name
7005 if( uniFullPathName.Length > 0 &&
7006 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
7009 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
7012 AFSExFreePoolWithTag( pwchBuffer, 0);
7020 AFSCleanupFcb( IN AFSFcb *Fcb,
7021 IN BOOLEAN ForceFlush)
7024 NTSTATUS ntStatus = STATUS_SUCCESS;
7025 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
7026 LARGE_INTEGER liTime;
7027 IO_STATUS_BLOCK stIoStatus;
7032 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7034 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7036 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
7039 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
7040 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7043 AFSAcquireExcl( &Fcb->NPFcb->Resource,
7046 if( Fcb->OpenReferenceCount > 0)
7052 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7057 if( !NT_SUCCESS( stIoStatus.Status))
7060 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7061 AFS_TRACE_LEVEL_ERROR,
7062 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7063 Fcb->ObjectInformation->FileId.Cell,
7064 Fcb->ObjectInformation->FileId.Volume,
7065 Fcb->ObjectInformation->FileId.Vnode,
7066 Fcb->ObjectInformation->FileId.Unique,
7068 stIoStatus.Information);
7070 ntStatus = stIoStatus.Status;
7073 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7079 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7080 AFS_TRACE_LEVEL_WARNING,
7081 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
7082 Fcb->ObjectInformation->FileId.Cell,
7083 Fcb->ObjectInformation->FileId.Volume,
7084 Fcb->ObjectInformation->FileId.Vnode,
7085 Fcb->ObjectInformation->FileId.Unique);
7087 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7090 __except( EXCEPTION_EXECUTE_HANDLER)
7093 ntStatus = GetExceptionCode();
7097 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7098 Fcb->ObjectInformation->FileId.Cell,
7099 Fcb->ObjectInformation->FileId.Volume,
7100 Fcb->ObjectInformation->FileId.Vnode,
7101 Fcb->ObjectInformation->FileId.Unique,
7104 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7108 AFSReleaseResource( &Fcb->NPFcb->Resource);
7111 // Wait for any currently running flush or release requests to complete
7114 AFSWaitOnQueuedFlushes( Fcb);
7117 // Now perform another flush on the file
7120 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7124 AFSReleaseExtentsWithFlush( Fcb,
7130 if( Fcb->OpenReferenceCount == 0 ||
7131 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7132 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7135 AFSTearDownFcbExtents( Fcb,
7139 try_return( ntStatus);
7142 KeQueryTickCount( &liTime);
7145 // First up are there dirty extents in the cache to flush?
7148 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7149 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7153 // The file has been marked as invalid. Dump it
7156 AFSTearDownFcbExtents( Fcb,
7159 else if( ForceFlush ||
7160 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7161 Fcb->Specific.File.ExtentCount) &&
7162 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7163 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7165 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7167 Fcb->OpenReferenceCount == 0)
7170 AFSReleaseExtentsWithFlush( Fcb,
7177 // If there are extents and they haven't been used recently *and*
7178 // are not being used
7182 ( 0 != Fcb->Specific.File.ExtentCount &&
7183 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7184 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7185 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7188 if ( AFSAcquireExcl( &Fcb->NPFcb->Resource, ForceFlush))
7194 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7199 if( !NT_SUCCESS( stIoStatus.Status))
7202 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7203 AFS_TRACE_LEVEL_ERROR,
7204 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7205 Fcb->ObjectInformation->FileId.Cell,
7206 Fcb->ObjectInformation->FileId.Volume,
7207 Fcb->ObjectInformation->FileId.Vnode,
7208 Fcb->ObjectInformation->FileId.Unique,
7210 stIoStatus.Information);
7212 ntStatus = stIoStatus.Status;
7218 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7224 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7225 AFS_TRACE_LEVEL_WARNING,
7226 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7227 Fcb->ObjectInformation->FileId.Cell,
7228 Fcb->ObjectInformation->FileId.Volume,
7229 Fcb->ObjectInformation->FileId.Vnode,
7230 Fcb->ObjectInformation->FileId.Unique);
7232 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7236 __except( EXCEPTION_EXECUTE_HANDLER)
7239 ntStatus = GetExceptionCode();
7243 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7244 Fcb->ObjectInformation->FileId.Cell,
7245 Fcb->ObjectInformation->FileId.Volume,
7246 Fcb->ObjectInformation->FileId.Vnode,
7247 Fcb->ObjectInformation->FileId.Unique,
7251 AFSReleaseResource( &Fcb->NPFcb->Resource);
7253 if( Fcb->OpenReferenceCount <= 0)
7257 // Tear em down we'll not be needing them again
7260 AFSTearDownFcbExtents( Fcb,
7267 ntStatus = STATUS_RETRY;
7280 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7281 IN UNICODE_STRING *NewFileName)
7284 NTSTATUS ntStatus = STATUS_SUCCESS;
7285 WCHAR *pTmpBuffer = NULL;
7290 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7293 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7296 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7298 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7300 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7304 // OK, we need to allocate a new name buffer
7307 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7308 NewFileName->Length,
7309 AFS_NAME_BUFFER_NINE_TAG);
7311 if( pTmpBuffer == NULL)
7314 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7317 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7319 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7321 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7324 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7326 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7327 NewFileName->Buffer,
7328 NewFileName->Length);
7339 AFSReadCacheFile( IN void *ReadBuffer,
7340 IN LARGE_INTEGER *ReadOffset,
7341 IN ULONG RequestedDataLength,
7342 IN OUT PULONG BytesRead)
7345 NTSTATUS ntStatus = STATUS_SUCCESS;
7348 PIO_STACK_LOCATION pIoStackLocation = NULL;
7349 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7350 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7351 FILE_OBJECT *pCacheFileObject = NULL;
7356 pCacheFileObject = AFSReferenceCacheFileObject();
7358 if( pCacheFileObject == NULL)
7360 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7363 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7366 // Initialize the event
7369 KeInitializeEvent( &kEvent,
7370 SynchronizationEvent,
7374 // Allocate an irp for this request. This could also come from a
7375 // private pool, for instance.
7378 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7384 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7388 // Build the IRP's main body
7391 pIrp->UserBuffer = ReadBuffer;
7393 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7394 pIrp->RequestorMode = KernelMode;
7395 pIrp->Flags |= IRP_READ_OPERATION;
7398 // Set up the I/O stack location.
7401 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7402 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7403 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7404 pIoStackLocation->FileObject = pCacheFileObject;
7405 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7407 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7410 // Set the completion routine.
7413 IoSetCompletionRoutine( pIrp,
7421 // Send it to the FSD
7424 ntStatus = IoCallDriver( pTargetDeviceObject,
7427 if( NT_SUCCESS( ntStatus))
7434 ntStatus = KeWaitForSingleObject( &kEvent,
7440 if( NT_SUCCESS( ntStatus))
7443 ntStatus = pIrp->IoStatus.Status;
7445 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7451 if( pCacheFileObject != NULL)
7453 AFSReleaseCacheFileObject( pCacheFileObject);
7459 if( pIrp->MdlAddress != NULL)
7462 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7465 MmUnlockPages( pIrp->MdlAddress);
7468 IoFreeMdl( pIrp->MdlAddress);
7471 pIrp->MdlAddress = NULL;
7485 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7490 KEVENT *pEvent = (KEVENT *)Context;
7496 return STATUS_MORE_PROCESSING_REQUIRED;
7500 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7503 BOOLEAN bIsEmpty = FALSE;
7504 AFSDirectoryCB *pDirEntry = NULL;
7509 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7514 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7517 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7519 while( pDirEntry != NULL)
7522 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7523 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7531 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7536 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7543 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7544 IN AFSDirectoryCB *DirEntry)
7547 NTSTATUS ntStatus = STATUS_SUCCESS;
7552 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7555 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7556 AFS_TRACE_LEVEL_VERBOSE,
7557 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7559 &DirEntry->NameInformation.FileName);
7561 try_return( ntStatus);
7564 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7567 // Remove the entry from the parent tree
7570 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7571 AFS_TRACE_LEVEL_VERBOSE,
7572 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7574 &DirEntry->NameInformation.FileName);
7576 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7579 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7580 AFS_TRACE_LEVEL_VERBOSE,
7581 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7583 &DirEntry->NameInformation.FileName);
7585 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7588 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7592 // From the short name tree
7595 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7596 AFS_TRACE_LEVEL_VERBOSE,
7597 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7599 &DirEntry->NameInformation.FileName);
7601 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7604 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7607 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7608 AFS_TRACE_LEVEL_VERBOSE,
7609 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7611 &DirEntry->NameInformation.FileName);
7613 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7615 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7626 AFSGetAuthenticationId()
7629 LARGE_INTEGER liAuthId = {0,0};
7630 NTSTATUS ntStatus = STATUS_SUCCESS;
7631 PACCESS_TOKEN hToken = NULL;
7632 PTOKEN_STATISTICS pTokenInfo = NULL;
7633 BOOLEAN bCopyOnOpen = FALSE;
7634 BOOLEAN bEffectiveOnly = FALSE;
7635 BOOLEAN bPrimaryToken = FALSE;
7636 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7641 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7644 &stImpersonationLevel);
7649 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7654 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7655 AFS_TRACE_LEVEL_ERROR,
7656 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7658 try_return( ntStatus);
7661 bPrimaryToken = TRUE;
7664 ntStatus = SeQueryInformationToken( hToken,
7666 (PVOID *)&pTokenInfo);
7668 if( !NT_SUCCESS( ntStatus))
7671 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7672 AFS_TRACE_LEVEL_ERROR,
7673 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7675 try_return( ntStatus);
7678 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7679 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7681 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7682 AFS_TRACE_LEVEL_VERBOSE,
7683 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7694 PsDereferenceImpersonationToken( hToken);
7699 PsDereferencePrimaryToken( hToken);
7703 if( pTokenInfo != NULL)
7706 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7714 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7718 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7720 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7723 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7725 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7728 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7730 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7733 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7735 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7738 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7740 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7747 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7750 BOOLEAN bIsValid = TRUE;
7752 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7754 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7756 while( pCurrentDirEntry != NULL)
7759 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7763 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7768 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7769 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7772 if( pDirEntry == NULL)
7779 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7782 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7785 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7787 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7789 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7798 AFSReferenceCacheFileObject()
7801 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7802 FILE_OBJECT *pCacheFileObject = NULL;
7804 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7807 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7809 if( pCacheFileObject != NULL)
7811 ObReferenceObject( pCacheFileObject);
7814 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7816 return pCacheFileObject;
7820 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7823 ASSERT( CacheFileObject != NULL);
7825 ObDereferenceObject( CacheFileObject);
7831 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7834 NTSTATUS ntStatus = STATUS_SUCCESS;
7835 AFSDeviceExt *pControlDevExt = NULL;
7836 ULONG ulTimeIncrement = 0;
7842 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7844 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7846 AFSServerName = LibraryInit->AFSServerName;
7848 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7851 // Callbacks in the framework
7854 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7856 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7858 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7860 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7862 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
7864 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7866 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7868 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7870 if( LibraryInit->AFSCacheBaseAddress != NULL)
7873 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7875 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7877 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7881 // Initialize some flush parameters
7884 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7886 ulTimeIncrement = KeQueryTimeIncrement();
7888 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7889 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7890 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7891 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7892 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7895 // Initialize the global root entry
7898 ntStatus = AFSInitVolume( NULL,
7899 &LibraryInit->GlobalRootFid,
7902 if( !NT_SUCCESS( ntStatus))
7905 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7906 AFS_TRACE_LEVEL_ERROR,
7907 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7910 try_return( ntStatus);
7913 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7916 if( !NT_SUCCESS( ntStatus))
7919 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7920 AFS_TRACE_LEVEL_ERROR,
7921 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7924 lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
7926 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7928 try_return( ntStatus);
7932 // Update the node type code to AFS_ROOT_ALL
7935 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7937 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7940 // Invalidate all known volumes since contact with the service and therefore
7941 // the file server was lost.
7944 AFSInvalidateAllVolumes();
7947 // Drop the locks acquired above
7950 AFSInitVolumeWorker( AFSGlobalRoot);
7952 lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
7954 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7956 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7970 NTSTATUS ntStatus = STATUS_SUCCESS;
7971 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7976 if( AFSGlobalDotDirEntry != NULL)
7979 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
7981 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7983 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7985 ExFreePool( AFSGlobalDotDirEntry);
7987 AFSGlobalDotDirEntry = NULL;
7990 if( AFSGlobalDotDotDirEntry != NULL)
7993 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
7995 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7997 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7999 ExFreePool( AFSGlobalDotDotDirEntry);
8001 AFSGlobalDotDotDirEntry = NULL;
8004 if( AFSSpecialShareNames != NULL)
8007 pDirNode = AFSSpecialShareNames;
8009 while( pDirNode != NULL)
8012 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
8014 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
8016 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
8018 ExFreePool( pDirNode->NonPaged);
8020 ExFreePool( pDirNode);
8022 pDirNode = pLastDirNode;
8025 AFSSpecialShareNames = NULL;
8033 AFSDefaultLogMsg( IN ULONG Subsystem,
8039 NTSTATUS ntStatus = STATUS_SUCCESS;
8041 char chDebugBuffer[ 256];
8046 va_start( va_args, Format);
8048 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8053 if( NT_SUCCESS( ntStatus))
8055 DbgPrint( chDebugBuffer);
8065 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8066 IN ULONG InputBufferLength,
8067 IN AFSStatusInfoCB *StatusInfo,
8068 OUT ULONG *ReturnLength)
8071 NTSTATUS ntStatus = STATUS_SUCCESS;
8072 AFSFcb *pFcb = NULL;
8073 AFSVolumeCB *pVolumeCB = NULL;
8074 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8075 AFSObjectInfoCB *pObjectInfo = NULL;
8076 ULONGLONG ullIndex = 0;
8077 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8078 AFSNameArrayHdr *pNameArray = NULL;
8079 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8086 // If we are given a FID then look up the entry by that, otherwise
8090 if( GetStatusInfo->FileID.Cell != 0 &&
8091 GetStatusInfo->FileID.Volume != 0 &&
8092 GetStatusInfo->FileID.Vnode != 0 &&
8093 GetStatusInfo->FileID.Unique != 0)
8096 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8099 // Locate the volume node
8102 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8104 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8106 (AFSBTreeEntry **)&pVolumeCB);
8108 if( pVolumeCB != NULL)
8111 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8113 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8114 AFS_TRACE_LEVEL_VERBOSE,
8115 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
8120 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8122 if( !NT_SUCCESS( ntStatus) ||
8125 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8128 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8131 pObjectInfo = &pVolumeCB->ObjectInformation;
8133 lCount = AFSObjectInfoIncrement( pObjectInfo);
8135 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8140 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8143 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8145 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8146 AFS_TRACE_LEVEL_VERBOSE,
8147 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
8151 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8153 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8155 (AFSBTreeEntry **)&pObjectInfo);
8157 if( pObjectInfo != NULL)
8161 // Reference the node so it won't be torn down
8164 lCount = AFSObjectInfoIncrement( pObjectInfo);
8166 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8167 AFS_TRACE_LEVEL_VERBOSE,
8168 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
8173 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8175 if( !NT_SUCCESS( ntStatus) ||
8176 pObjectInfo == NULL)
8178 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8185 if( GetStatusInfo->FileNameLength == 0 ||
8186 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8188 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8191 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8192 uniFullPathName.MaximumLength = uniFullPathName.Length;
8194 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8197 // This name should begin with the \afs server so parse it off and check it
8200 FsRtlDissectName( uniFullPathName,
8204 if( RtlCompareUnicodeString( &uniComponentName,
8208 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8209 AFS_TRACE_LEVEL_ERROR,
8210 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8213 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8216 uniFullPathName = uniRemainingPath;
8218 uniParsedName = uniFullPathName;
8224 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8227 if( pNameArray == NULL)
8229 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8232 pVolumeCB = AFSGlobalRoot;
8234 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8237 // Increment the ref count on the volume and dir entry for correct processing below
8240 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8242 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8243 AFS_TRACE_LEVEL_VERBOSE,
8244 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
8248 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
8250 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8251 AFS_TRACE_LEVEL_VERBOSE,
8252 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8253 &pParentDirEntry->NameInformation.FileName,
8258 ntStatus = AFSLocateNameEntry( NULL,
8263 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8264 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8270 if( !NT_SUCCESS( ntStatus))
8274 // The volume lock was released on failure above
8275 // Except for STATUS_OBJECT_NAME_NOT_FOUND
8278 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
8281 if( pVolumeCB != NULL)
8284 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8286 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8287 AFS_TRACE_LEVEL_VERBOSE,
8288 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
8293 if( pDirectoryEntry != NULL)
8296 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
8298 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8299 AFS_TRACE_LEVEL_VERBOSE,
8300 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8301 &pDirectoryEntry->NameInformation.FileName,
8309 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
8311 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8312 AFS_TRACE_LEVEL_VERBOSE,
8313 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8314 &pParentDirEntry->NameInformation.FileName,
8323 try_return( ntStatus);
8327 // Remove the reference made above
8330 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
8332 pObjectInfo = pDirectoryEntry->ObjectInformation;
8334 lCount = AFSObjectInfoIncrement( pObjectInfo);
8336 if( pVolumeCB != NULL)
8339 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8341 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8342 AFS_TRACE_LEVEL_VERBOSE,
8343 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
8345 pVolumeCB->VolumeReferenceCount);
8350 // At this point we have an object info block, return the information
8353 StatusInfo->FileId = pObjectInfo->FileId;
8355 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8357 StatusInfo->Expiration = pObjectInfo->Expiration;
8359 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8361 StatusInfo->FileType = pObjectInfo->FileType;
8363 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8365 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8367 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8369 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8371 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8373 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8375 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8377 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8379 StatusInfo->EaSize = pObjectInfo->EaSize;
8381 StatusInfo->Links = pObjectInfo->Links;
8384 // Return the information length
8387 *ReturnLength = sizeof( AFSStatusInfoCB);
8391 if( pObjectInfo != NULL)
8394 lCount = AFSObjectInfoDecrement( pObjectInfo);
8397 if( pNameArray != NULL)
8400 AFSFreeNameArray( pNameArray);
8408 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8409 IN UNICODE_STRING *ComponentName)
8412 NTSTATUS ntStatus = STATUS_SUCCESS;
8413 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8414 AFSDirectoryCB *pDirEntry = NULL;
8422 // Search for the entry in the parent
8425 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8426 AFS_TRACE_LEVEL_VERBOSE_2,
8427 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8430 ulCRC = AFSGenerateCRC( ComponentName,
8433 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8436 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8440 if( pDirEntry == NULL)
8444 // Missed so perform a case insensitive lookup
8447 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8448 AFS_TRACE_LEVEL_VERBOSE_2,
8449 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8452 ulCRC = AFSGenerateCRC( ComponentName,
8455 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8459 if( pDirEntry == NULL)
8463 // OK, if this component is a valid short name then try
8464 // a lookup in the short name tree
8467 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8468 RtlIsNameLegalDOS8Dot3( ComponentName,
8473 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8474 AFS_TRACE_LEVEL_VERBOSE_2,
8475 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8478 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8485 if( pDirEntry != NULL)
8487 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
8490 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8492 if( pDirEntry == NULL)
8495 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8496 AFS_TRACE_LEVEL_VERBOSE_2,
8497 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
8500 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8504 // We have the symlink object but previously failed to process it so return access
8508 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8509 AFS_TRACE_LEVEL_VERBOSE_2,
8510 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8513 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8515 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
8526 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8527 OUT UNICODE_STRING *ComponentName)
8530 NTSTATUS ntStatus = STATUS_SUCCESS;
8531 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8533 uniFullPathName = *FullPathName;
8538 FsRtlDissectName( uniFullPathName,
8542 if( uniRemainingPath.Length == 0)
8547 uniFullPathName = uniRemainingPath;
8550 if( uniComponentName.Length > 0)
8552 *ComponentName = uniComponentName;
8559 AFSDumpTraceFiles_Default()
8565 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8568 BOOLEAN bIsValidName = TRUE;
8574 while( usIndex < FileName->Length/sizeof( WCHAR))
8577 if( FileName->Buffer[ usIndex] == L':' ||
8578 FileName->Buffer[ usIndex] == L'*' ||
8579 FileName->Buffer[ usIndex] == L'?' ||
8580 FileName->Buffer[ usIndex] == L'"' ||
8581 FileName->Buffer[ usIndex] == L'<' ||
8582 FileName->Buffer[ usIndex] == L'>')
8584 bIsValidName = FALSE;
8592 return bIsValidName;
8596 AFSCreateDefaultSecurityDescriptor()
8599 NTSTATUS ntStatus = STATUS_SUCCESS;
8601 ULONG ulSACLSize = 0;
8602 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8603 ULONG ulACESize = 0;
8604 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8605 ULONG ulSDLength = 0;
8606 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8607 PSID pWorldSID = NULL;
8608 ULONG *pulSubAuthority = NULL;
8609 ULONG ulWorldSIDLEngth = 0;
8614 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8616 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8618 AFS_GENERIC_MEMORY_29_TAG);
8620 if( pWorldSID == NULL)
8622 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8623 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8626 RtlZeroMemory( pWorldSID,
8629 RtlInitializeSid( pWorldSID,
8630 &SeWorldSidAuthority,
8633 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8634 *pulSubAuthority = SECURITY_WORLD_RID;
8636 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8639 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8644 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8646 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8648 AFS_GENERIC_MEMORY_29_TAG);
8653 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8655 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8658 RtlZeroMemory( pACE,
8661 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8662 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8663 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8664 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8666 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8668 SeExports->SeLowMandatorySid);
8670 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8671 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8673 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8675 AFS_GENERIC_MEMORY_29_TAG);
8680 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8682 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8685 ntStatus = RtlCreateAcl( pSACL,
8689 if( !NT_SUCCESS( ntStatus))
8692 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8695 try_return( ntStatus);
8698 ntStatus = RtlAddAce( pSACL,
8702 pACE->Header.AceSize);
8704 if( !NT_SUCCESS( ntStatus))
8707 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8710 try_return( ntStatus);
8714 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8715 sizeof( SECURITY_DESCRIPTOR),
8716 AFS_GENERIC_MEMORY_27_TAG);
8718 if( pSecurityDescr == NULL)
8721 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8723 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8726 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8727 SECURITY_DESCRIPTOR_REVISION);
8729 if( !NT_SUCCESS( ntStatus))
8732 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8735 try_return( ntStatus);
8738 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8740 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8745 if( !NT_SUCCESS( ntStatus))
8748 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8751 try_return( ntStatus);
8756 // Add in the group and owner to the SD
8759 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8761 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8765 if( !NT_SUCCESS( ntStatus))
8768 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8771 try_return( ntStatus);
8775 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8779 if( !NT_SUCCESS( ntStatus))
8782 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8785 try_return( ntStatus);
8788 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8791 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8793 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8796 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8798 AFS_GENERIC_MEMORY_27_TAG);
8800 if( pRelativeSecurityDescr == NULL)
8803 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8805 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8808 ulSDLength = PAGE_SIZE;
8810 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8811 pRelativeSecurityDescr,
8814 if( !NT_SUCCESS( ntStatus))
8817 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8820 try_return( ntStatus);
8823 AFSDefaultSD = pRelativeSecurityDescr;
8827 if( !NT_SUCCESS( ntStatus))
8830 if( pRelativeSecurityDescr != NULL)
8832 ExFreePool( pRelativeSecurityDescr);
8836 if( pSecurityDescr != NULL)
8838 ExFreePool( pSecurityDescr);
8851 if( pWorldSID != NULL)
8853 ExFreePool( pWorldSID);
8861 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8862 OUT UNICODE_STRING *ParentPath)
8867 *ParentPath = *FullFileName;
8870 // If the final character is a \, jump over it
8873 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8875 ParentPath->Length -= sizeof( WCHAR);
8878 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8880 ParentPath->Length -= sizeof( WCHAR);
8884 // And the separator
8887 ParentPath->Length -= sizeof( WCHAR);
8893 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8894 IN AFSObjectInfoCB *ObjectInfo,
8895 IN BOOLEAN WriteAccess,
8896 OUT GUID *AuthGroup)
8899 NTSTATUS ntStatus = STATUS_SUCCESS;
8900 GUID stAuthGroup, stZeroAuthGroup;
8901 BOOLEAN bFoundAuthGroup = FALSE;
8902 AFSCcb *pCcb = NULL;
8908 RtlZeroMemory( &stAuthGroup,
8911 RtlZeroMemory( &stZeroAuthGroup,
8917 if( ObjectInfo != NULL &&
8918 ObjectInfo->Fcb != NULL)
8920 pFcb = ObjectInfo->Fcb;
8927 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8930 pCcb = Fcb->CcbListHead;
8932 while( pCcb != NULL)
8936 pCcb->GrantedAccess & FILE_WRITE_DATA)
8938 RtlCopyMemory( &stAuthGroup,
8942 bFoundAuthGroup = TRUE;
8946 else if( pCcb->GrantedAccess & FILE_READ_DATA)
8949 // At least get the read-only access
8952 RtlCopyMemory( &stAuthGroup,
8956 bFoundAuthGroup = TRUE;
8959 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
8962 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
8965 if( !bFoundAuthGroup)
8968 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
8969 (ULONGLONG)PsGetCurrentThreadId(),
8972 if( RtlCompareMemory( &stZeroAuthGroup,
8974 sizeof( GUID)) == sizeof( GUID))
8977 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
8979 try_return( ntStatus = STATUS_ACCESS_DENIED);
8983 RtlCopyMemory( AuthGroup,
8996 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
8997 IN ULONG InvalidateReason)
9000 NTSTATUS ntStatus = STATUS_SUCCESS;
9001 IO_STATUS_BLOCK stIoStatus;
9004 ULONG ulProcessCount = 0;
9010 switch( InvalidateReason)
9013 case AFS_INVALIDATE_DELETED:
9016 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9017 ObjectInfo->Fcb != NULL)
9020 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9023 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9025 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9030 // Clear out the extents
9031 // And get rid of them (note this involves waiting
9032 // for any writes or reads to the cache to complete)
9035 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9038 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9044 case AFS_INVALIDATE_DATA_VERSION:
9047 LARGE_INTEGER liCurrentOffset = {0,0};
9048 LARGE_INTEGER liFlushLength = {0,0};
9049 ULONG ulFlushLength = 0;
9050 BOOLEAN bLocked = FALSE;
9051 BOOLEAN bExtentsLocked = FALSE;
9052 BOOLEAN bCleanExtents = FALSE;
9054 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9055 ObjectInfo->Fcb != NULL)
9058 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9063 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9064 AFS_TRACE_LEVEL_VERBOSE,
9065 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %08lX SHARED %08lX\n",
9066 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9067 PsGetCurrentThread());
9069 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9072 bExtentsLocked = TRUE;
9075 // There are several possibilities here:
9077 // 0. If there are no extents or all of the extents are dirty, do nothing.
9079 // 1. There could be nothing dirty and an open reference count of zero
9080 // in which case we can just tear down all of the extents without
9081 // holding any resources.
9083 // 2. There could be nothing dirty and a non-zero open reference count
9084 // in which case we can issue a CcPurge against the entire file
9085 // while holding just the Fcb Resource.
9087 // 3. There can be dirty extents in which case we need to identify
9088 // the non-dirty ranges and then perform a CcPurge on just the
9089 // non-dirty ranges while holding just the Fcb Resource.
9092 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9095 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9098 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9101 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9103 bExtentsLocked = FALSE;
9105 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9109 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9118 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9120 bExtentsLocked = FALSE;
9122 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9128 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9129 AFS_TRACE_LEVEL_WARNING,
9130 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9131 ObjectInfo->FileId.Cell,
9132 ObjectInfo->FileId.Volume,
9133 ObjectInfo->FileId.Vnode,
9134 ObjectInfo->FileId.Unique);
9136 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9141 bCleanExtents = TRUE;
9144 __except( EXCEPTION_EXECUTE_HANDLER)
9147 ntStatus = GetExceptionCode();
9151 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9152 ObjectInfo->FileId.Cell,
9153 ObjectInfo->FileId.Volume,
9154 ObjectInfo->FileId.Vnode,
9155 ObjectInfo->FileId.Unique,
9158 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9166 // Must build a list of non-dirty ranges from the beginning of the file
9167 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9168 // ranges. In all but the most extreme random data write scenario there will
9169 // be significantly fewer.
9171 // For each range we need offset and size.
9174 AFSByteRange * ByteRangeList = NULL;
9175 ULONG ulByteRangeCount = 0;
9177 BOOLEAN bPurgeOnClose = FALSE;
9182 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9185 if ( ByteRangeList != NULL ||
9186 ulByteRangeCount == 0)
9189 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9191 bExtentsLocked = FALSE;
9193 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9200 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9202 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9203 &ByteRangeList[ulIndex].FileOffset,
9208 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9209 AFS_TRACE_LEVEL_WARNING,
9210 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9211 ObjectInfo->FileId.Cell,
9212 ObjectInfo->FileId.Volume,
9213 ObjectInfo->FileId.Vnode,
9214 ObjectInfo->FileId.Unique);
9216 bPurgeOnClose = TRUE;
9221 bCleanExtents = TRUE;
9224 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9226 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9228 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9235 // We couldn't allocate the memory to build the purge list
9236 // so just walk the extent list while holding the ExtentsList Resource.
9237 // This could deadlock but we do not have much choice.
9240 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9244 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9248 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9250 while( ulProcessCount < ulCount)
9252 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9254 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9256 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9257 &pEntry->FileOffset,
9262 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9263 AFS_TRACE_LEVEL_WARNING,
9264 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9265 ObjectInfo->FileId.Cell,
9266 ObjectInfo->FileId.Volume,
9267 ObjectInfo->FileId.Vnode,
9268 ObjectInfo->FileId.Unique);
9270 bPurgeOnClose = TRUE;
9275 bCleanExtents = TRUE;
9279 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9282 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9284 while( liFlushLength.QuadPart > 0)
9287 if( liFlushLength.QuadPart > 512 * 1024000)
9289 ulFlushLength = 512 * 1024000;
9293 ulFlushLength = liFlushLength.LowPart;
9296 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9302 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9303 AFS_TRACE_LEVEL_WARNING,
9304 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9305 ObjectInfo->FileId.Cell,
9306 ObjectInfo->FileId.Volume,
9307 ObjectInfo->FileId.Vnode,
9308 ObjectInfo->FileId.Unique);
9310 bPurgeOnClose = TRUE;
9315 bCleanExtents = TRUE;
9318 liFlushLength.QuadPart -= ulFlushLength;
9322 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9330 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9336 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9337 AFS_TRACE_LEVEL_WARNING,
9338 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9339 ObjectInfo->FileId.Cell,
9340 ObjectInfo->FileId.Volume,
9341 ObjectInfo->FileId.Vnode,
9342 ObjectInfo->FileId.Unique);
9344 bPurgeOnClose = TRUE;
9349 bCleanExtents = TRUE;
9356 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9360 __except( EXCEPTION_EXECUTE_HANDLER)
9363 ntStatus = GetExceptionCode();
9367 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9368 ObjectInfo->FileId.Cell,
9369 ObjectInfo->FileId.Volume,
9370 ObjectInfo->FileId.Vnode,
9371 ObjectInfo->FileId.Unique,
9377 if ( bExtentsLocked)
9380 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9386 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9392 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9401 if( ObjectInfo != NULL)
9404 AFSObjectInfoDecrement( ObjectInfo);