2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2012, 2013 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
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
16 * nor the names of their contributors may be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission from Kernel Drivers, LLC and Your File System, Inc.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 // File: AFSGeneric.cpp
37 #include "AFSCommon.h"
40 // Function: AFSExceptionFilter
44 // This function is the exception handler
48 // A status is returned for the function
52 AFSExceptionFilter( IN CHAR *FunctionString,
54 IN PEXCEPTION_POINTERS ExceptPtrs)
57 UNREFERENCED_PARAMETER(Code);
58 PEXCEPTION_RECORD ExceptRec;
64 ExceptRec = ExceptPtrs->ExceptionRecord;
66 Context = ExceptPtrs->ContextRecord;
70 "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
74 ExceptRec->ExceptionCode,
75 ExceptRec->ExceptionAddress,
76 (void *)AFSExceptionFilter));
78 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
80 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
81 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
83 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
85 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
88 KeBugCheck( (ULONG)-2);
96 __except( EXCEPTION_EXECUTE_HANDLER)
102 return EXCEPTION_EXECUTE_HANDLER;
106 // Function: AFSLibExAllocatePoolWithTag()
108 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
109 // is configured on, then bugcheck the system if
110 // a memory allocation fails. The routine should be
111 // used for all memory allocations that are to be freed
112 // when the library is unloaded. Memory allocations that
113 // are to survive library unload and reload should be
114 // performed using AFSExAllocatePoolWithTag() which is
115 // provided by the AFS Framework.
118 // POOL_TYPE PoolType - Paged or NonPaged
119 // SIZE_T NumberOfBytes - requested allocation size
120 // ULONG Tag - Pool Allocation Tag to be applied for tracking
123 // void * - the memory allocation
127 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
128 IN SIZE_T NumberOfBytes,
132 void *pBuffer = NULL;
134 pBuffer = ExAllocatePoolWithTag( PoolType,
141 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
144 KeBugCheck( (ULONG)-2);
151 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
155 PsGetCurrentThread()));
165 // Function: AFSAcquireExcl()
167 // Purpose: Called to acquire a resource exclusive with optional wait
170 // PERESOURCE Resource - Resource to acquire
171 // BOOLEAN Wait - Whether to block
174 // BOOLEAN - Whether the mask was acquired
178 AFSAcquireExcl( IN PERESOURCE Resource,
182 BOOLEAN bStatus = FALSE;
185 // Normal kernel APCs must be disabled before calling
186 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
189 KeEnterCriticalRegion();
191 bStatus = ExAcquireResourceExclusiveLite( Resource,
197 KeLeaveCriticalRegion();
204 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
208 BOOLEAN bStatus = FALSE;
210 KeEnterCriticalRegion();
212 bStatus = ExAcquireSharedStarveExclusive( Resource,
218 KeLeaveCriticalRegion();
225 // Function: AFSAcquireShared()
227 // Purpose: Called to acquire a resource shared with optional wait
230 // PERESOURCE Resource - Resource to acquire
231 // BOOLEAN Wait - Whether to block
234 // BOOLEAN - Whether the mask was acquired
238 AFSAcquireShared( IN PERESOURCE Resource,
242 BOOLEAN bStatus = FALSE;
244 KeEnterCriticalRegion();
246 bStatus = ExAcquireResourceSharedLite( Resource,
252 KeLeaveCriticalRegion();
259 // Function: AFSReleaseResource()
261 // Purpose: Called to release a resource
264 // PERESOURCE Resource - Resource to release
271 AFSReleaseResource( IN PERESOURCE Resource)
274 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
275 AFS_TRACE_LEVEL_VERBOSE,
276 "AFSReleaseResource Releasing lock %p Thread %08lX\n",
278 PsGetCurrentThread()));
280 ExReleaseResourceLite( Resource);
282 KeLeaveCriticalRegion();
288 AFSConvertToShared( IN PERESOURCE Resource)
291 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
292 AFS_TRACE_LEVEL_VERBOSE,
293 "AFSConvertToShared Converting lock %p Thread %08lX\n",
295 PsGetCurrentThread()));
297 ExConvertExclusiveToSharedLite( Resource);
303 // Function: AFSCompleteRequest
307 // This function completes irps
311 // A status is returned for the function
315 AFSCompleteRequest( IN PIRP Irp,
319 Irp->IoStatus.Status = Status;
321 IoCompleteRequest( Irp,
328 // Function: AFSGenerateCRC
332 // Given a device and filename this function generates a CRC
336 // A status is returned for the function
340 AFSGenerateCRC( IN PUNICODE_STRING FileName,
341 IN BOOLEAN UpperCaseName)
345 NTSTATUS ntStatus = STATUS_SUCCESS;
347 ntStatus = RtlHashUnicodeString( FileName,
349 HASH_STRING_ALGORITHM_DEFAULT,
352 if( !NT_SUCCESS( ntStatus))
361 AFSLockSystemBuffer( IN PIRP Irp,
365 void *pAddress = NULL;
367 if( Irp->MdlAddress != NULL)
370 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
373 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
376 pAddress = Irp->AssociatedIrp.SystemBuffer;
378 else if( Irp->UserBuffer != NULL)
381 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
387 if( Irp->MdlAddress != NULL)
391 // Lock the new Mdl in memory.
396 PIO_STACK_LOCATION pIoStack;
397 pIoStack = IoGetCurrentIrpStackLocation( Irp);
400 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
401 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
403 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
406 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
409 AFSDumpTraceFilesFnc();
411 IoFreeMdl( Irp->MdlAddress );
412 Irp->MdlAddress = NULL;
422 AFSLockUserBuffer( IN void *UserBuffer,
423 IN ULONG BufferLength,
427 NTSTATUS ntStatus = STATUS_SUCCESS;
428 void *pAddress = NULL;
434 pMdl = IoAllocateMdl( UserBuffer,
443 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
447 // Lock the new Mdl in memory.
453 MmProbeAndLockPages( pMdl,
457 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
460 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
463 AFSDumpTraceFilesFnc();
485 AFSMapToService( IN PIRP Irp,
489 NTSTATUS ntStatus = STATUS_SUCCESS;
490 void *pMappedBuffer = NULL;
491 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
497 if( pDevExt->Specific.Control.ServiceProcess == NULL)
500 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
503 if( Irp->MdlAddress == NULL)
506 if( AFSLockSystemBuffer( Irp,
510 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
515 // Attach to the service process for mapping
518 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
519 (PRKAPC_STATE)&stApcState);
521 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
528 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
535 return pMappedBuffer;
539 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
543 NTSTATUS ntStatus = STATUS_SUCCESS;
544 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
550 if( pDevExt->Specific.Control.ServiceProcess == NULL)
553 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
560 // Attach to the service process for mapping
563 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
564 (PRKAPC_STATE)&stApcState);
566 MmUnmapLockedPages( MappedBuffer,
569 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
581 AFSInitializeLibraryDevice()
584 NTSTATUS ntStatus = STATUS_SUCCESS;
585 AFSDeviceExt *pDeviceExt = NULL;
590 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
593 // The PIOCtl file name
596 RtlInitUnicodeString( &AFSPIOCtlName,
597 AFS_PIOCTL_FILE_INTERFACE_NAME);
600 // And the global root share name
603 RtlInitUnicodeString( &AFSGlobalRootName,
604 AFS_GLOBAL_ROOT_SHARE_NAME);
612 AFSRemoveLibraryDevice()
615 NTSTATUS ntStatus = STATUS_SUCCESS;
626 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
630 UNREFERENCED_PARAMETER(DeviceObject);
631 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
633 AFSCompleteRequest( Irp,
640 AFSInitializeGlobalDirectoryEntries()
643 NTSTATUS ntStatus = STATUS_SUCCESS;
644 AFSDirectoryCB *pDirNode = NULL;
645 ULONG ulEntryLength = 0;
646 AFSObjectInfoCB *pObjectInfoCB = NULL;
647 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
654 // Initialize the global . entry
657 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
660 if( pObjectInfoCB == NULL)
663 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
664 AFS_TRACE_LEVEL_ERROR,
665 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
668 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
671 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
672 AFS_OBJECT_REFERENCE_GLOBAL);
674 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
675 AFS_TRACE_LEVEL_VERBOSE,
676 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
680 ntStatus = STATUS_SUCCESS;
682 ulEntryLength = sizeof( AFSDirectoryCB) +
685 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
689 if( pDirNode == NULL)
692 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
693 AFS_OBJECT_REFERENCE_GLOBAL);
695 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
696 AFS_TRACE_LEVEL_VERBOSE,
697 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
704 AFSDeleteObjectInfo( &pObjectInfoCB);
707 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
708 AFS_TRACE_LEVEL_ERROR,
709 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n"));
711 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
714 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
715 AFS_TRACE_LEVEL_VERBOSE,
716 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocated %p\n",
719 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
720 sizeof( AFSNonPagedDirectoryCB),
721 AFS_DIR_ENTRY_NP_TAG);
723 if( pNonPagedDirEntry == NULL)
726 ExFreePool( pDirNode);
728 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
729 AFS_OBJECT_REFERENCE_GLOBAL);
731 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
732 AFS_TRACE_LEVEL_VERBOSE,
733 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
740 AFSDeleteObjectInfo( &pObjectInfoCB);
743 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
744 AFS_TRACE_LEVEL_ERROR,
745 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n"));
747 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
750 RtlZeroMemory( pDirNode,
753 RtlZeroMemory( pNonPagedDirEntry,
754 sizeof( AFSNonPagedDirectoryCB));
756 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
758 pDirNode->NonPaged = pNonPagedDirEntry;
760 pDirNode->ObjectInformation = pObjectInfoCB;
766 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
768 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
771 // Setup the names in the entry
774 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
776 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
778 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
780 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
783 // Populate the rest of the data
786 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
788 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
790 AFSGlobalDotDirEntry = pDirNode;
796 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
799 if( pObjectInfoCB == NULL)
802 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
803 AFS_TRACE_LEVEL_ERROR,
804 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
807 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
810 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
811 AFS_OBJECT_REFERENCE_GLOBAL);
813 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
814 AFS_TRACE_LEVEL_VERBOSE,
815 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
819 ntStatus = STATUS_SUCCESS;
821 ulEntryLength = sizeof( AFSDirectoryCB) +
822 ( 2 * sizeof( WCHAR));
824 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
828 if( pDirNode == NULL)
831 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
832 AFS_TRACE_LEVEL_ERROR,
833 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocation failure\n"));
835 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
836 AFS_OBJECT_REFERENCE_GLOBAL);
838 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
839 AFS_TRACE_LEVEL_VERBOSE,
840 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
847 AFSDeleteObjectInfo( &pObjectInfoCB);
850 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
853 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
854 AFS_TRACE_LEVEL_VERBOSE,
855 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocated %p\n",
858 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
859 sizeof( AFSNonPagedDirectoryCB),
860 AFS_DIR_ENTRY_NP_TAG);
862 if( pNonPagedDirEntry == NULL)
865 ExFreePool( pDirNode);
867 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
868 AFS_OBJECT_REFERENCE_GLOBAL);
870 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
871 AFS_TRACE_LEVEL_VERBOSE,
872 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
879 AFSDeleteObjectInfo( &pObjectInfoCB);
882 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
885 RtlZeroMemory( pDirNode,
888 RtlZeroMemory( pNonPagedDirEntry,
889 sizeof( AFSNonPagedDirectoryCB));
891 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
893 pDirNode->NonPaged = pNonPagedDirEntry;
895 pDirNode->ObjectInformation = pObjectInfoCB;
901 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
903 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
906 // Setup the names in the entry
909 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
911 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
913 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
915 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
917 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
920 // Populate the rest of the data
923 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
925 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
927 AFSGlobalDotDotDirEntry = pDirNode;
931 if( !NT_SUCCESS( ntStatus))
934 if( AFSGlobalDotDirEntry != NULL)
937 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
938 AFS_OBJECT_REFERENCE_GLOBAL);
940 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
941 AFS_TRACE_LEVEL_VERBOSE,
942 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
943 AFSGlobalDotDirEntry->ObjectInformation,
949 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
952 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
954 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
956 ExFreePool( AFSGlobalDotDirEntry);
958 AFSGlobalDotDirEntry = NULL;
961 if( AFSGlobalDotDotDirEntry != NULL)
964 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
965 AFS_OBJECT_REFERENCE_GLOBAL);
967 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
968 AFS_TRACE_LEVEL_VERBOSE,
969 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
970 AFSGlobalDotDotDirEntry->ObjectInformation,
976 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
979 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
981 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
983 ExFreePool( AFSGlobalDotDotDirEntry);
985 AFSGlobalDotDotDirEntry = NULL;
994 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
995 IN PUNICODE_STRING FileName,
996 IN PUNICODE_STRING TargetName,
997 IN AFSDirEnumEntry *DirEnumEntry,
1001 AFSDirectoryCB *pDirNode = NULL;
1002 NTSTATUS ntStatus = STATUS_SUCCESS;
1003 ULONG ulEntryLength = 0;
1004 AFSObjectInfoCB *pObjectInfoCB = NULL;
1005 ULONGLONG ullIndex = 0;
1006 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
1012 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1013 AFS_TRACE_LEVEL_VERBOSE,
1014 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
1016 ParentObjectInfo->FileId.Cell,
1017 ParentObjectInfo->FileId.Volume,
1018 ParentObjectInfo->FileId.Vnode,
1019 ParentObjectInfo->FileId.Unique));
1022 // First thing is to locate/create our object information block
1026 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
1029 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
1031 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
1033 (AFSBTreeEntry **)&pObjectInfoCB);
1035 if( !NT_SUCCESS( ntStatus))
1039 // Allocate our object info cb
1042 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
1045 if( pObjectInfoCB == NULL)
1048 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1050 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1053 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1054 AFS_TRACE_LEVEL_VERBOSE,
1055 "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
1061 // If we allocated the object information cb then set the information
1064 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1066 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1068 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1070 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1072 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1073 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1076 pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1079 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
1082 if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1085 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1090 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1095 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1096 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1100 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1101 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1102 pObjectInfoCB->TargetFileId.Unique == 0 &&
1103 (TargetName == NULL || TargetName->Length == 0))
1107 // This will ensure we perform a validation on the node
1110 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1113 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1116 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1119 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1122 if ( BooleanFlagOn( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY))
1125 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1127 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1129 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1131 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1133 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1135 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1137 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1139 pObjectInfoCB->Links = DirEnumEntry->Links;
1141 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1143 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1145 ClearFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1149 // This reference count is either stored into the return DirectoryCB
1150 // or released before function exit.
1153 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
1154 AFS_OBJECT_REFERENCE_DIRENTRY);
1156 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1157 AFS_TRACE_LEVEL_VERBOSE,
1158 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
1162 KeQueryTickCount( &pObjectInfoCB->LastAccessCount);
1164 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1166 ntStatus = STATUS_SUCCESS;
1168 ulEntryLength = sizeof( AFSDirectoryCB) +
1171 if( TargetName != NULL)
1174 ulEntryLength += TargetName->Length;
1177 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1181 if( pDirNode == NULL)
1184 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1187 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1188 AFS_TRACE_LEVEL_VERBOSE,
1189 "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
1192 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1193 sizeof( AFSNonPagedDirectoryCB),
1194 AFS_DIR_ENTRY_NP_TAG);
1196 if( pNonPagedDirEntry == NULL)
1199 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1202 RtlZeroMemory( pDirNode,
1205 RtlZeroMemory( pNonPagedDirEntry,
1206 sizeof( AFSNonPagedDirectoryCB));
1208 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1210 pDirNode->NonPaged = pNonPagedDirEntry;
1212 pDirNode->ObjectInformation = pObjectInfoCB;
1215 // Set valid entry and NOT_IN_PARENT flag
1218 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1220 pDirNode->FileIndex = FileIndex;
1223 // Setup the names in the entry
1226 if( FileName->Length > 0)
1229 pDirNode->NameInformation.FileName.Length = FileName->Length;
1231 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1233 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1235 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1237 pDirNode->NameInformation.FileName.Length);
1240 // Create a CRC for the file
1243 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1246 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1250 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1251 AFS_TRACE_LEVEL_VERBOSE,
1252 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1255 ParentObjectInfo->FileId.Cell,
1256 ParentObjectInfo->FileId.Volume,
1257 ParentObjectInfo->FileId.Vnode,
1258 ParentObjectInfo->FileId.Unique));
1260 if( TargetName != NULL &&
1261 TargetName->Length > 0)
1264 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1266 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1268 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1269 sizeof( AFSDirectoryCB) +
1270 pDirNode->NameInformation.FileName.Length);
1272 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1274 pDirNode->NameInformation.TargetName.Length);
1280 if( !NT_SUCCESS( ntStatus))
1283 if( pNonPagedDirEntry != NULL)
1286 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1288 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1291 if( pDirNode != NULL)
1294 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1295 AFS_TRACE_LEVEL_VERBOSE,
1296 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1299 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1305 // Dereference our object info block if we have one
1308 if( pObjectInfoCB != NULL)
1311 AFSAcquireShared( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
1314 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1315 AFS_OBJECT_REFERENCE_DIRENTRY);
1317 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1318 AFS_TRACE_LEVEL_VERBOSE,
1319 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1323 AFSReleaseResource( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
1332 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1333 IN BOOLEAN DirectoryEntry)
1336 BOOLEAN bReturn = TRUE;
1337 ACCESS_MASK stAccessMask = 0;
1340 // Get rid of anything we don't know about
1343 DesiredAccess = (DesiredAccess &
1349 ACCESS_SYSTEM_SECURITY |
1353 FILE_READ_ATTRIBUTES |
1354 FILE_WRITE_ATTRIBUTES |
1355 FILE_LIST_DIRECTORY |
1361 // Our 'read only' access mask. These are the accesses we will
1362 // allow for a read only file
1365 stAccessMask = DELETE |
1370 ACCESS_SYSTEM_SECURITY |
1374 FILE_READ_ATTRIBUTES |
1375 FILE_WRITE_ATTRIBUTES |
1377 FILE_LIST_DIRECTORY |
1381 // For a directory, add in the directory specific accesses
1387 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1392 if( FlagOn( DesiredAccess, ~stAccessMask))
1396 // A write access is set ...
1406 AFSEvaluateNode( IN GUID *AuthGroup,
1407 IN AFSDirectoryCB *DirEntry)
1410 NTSTATUS ntStatus = STATUS_SUCCESS;
1411 AFSDirEnumEntry *pDirEntry = NULL;
1412 UNICODE_STRING uniTargetName;
1417 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1422 if( !NT_SUCCESS( ntStatus))
1425 try_return( ntStatus);
1428 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1430 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1432 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1434 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1436 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1438 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1440 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1442 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1444 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1446 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1448 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1450 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1451 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1454 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1457 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1460 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1463 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1468 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1472 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1474 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1477 // If we have a target name then see if it needs updating ...
1480 if( pDirEntry->TargetNameLength > 0)
1484 // Update the target name information if needed
1487 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1489 uniTargetName.MaximumLength = uniTargetName.Length;
1491 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1493 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1496 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1497 RtlCompareUnicodeString( &uniTargetName,
1498 &DirEntry->NameInformation.TargetName,
1503 // Update the target name
1506 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1508 uniTargetName.Buffer,
1509 uniTargetName.Length);
1511 if( !NT_SUCCESS( ntStatus))
1514 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1516 try_return( ntStatus);
1520 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1525 if( pDirEntry != NULL)
1528 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1536 AFSValidateSymLink( IN GUID *AuthGroup,
1537 IN AFSDirectoryCB *DirEntry)
1540 NTSTATUS ntStatus = STATUS_SUCCESS;
1541 AFSDirEnumEntry *pDirEntry = NULL;
1542 UNICODE_STRING uniTargetName;
1547 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1552 if( !NT_SUCCESS( ntStatus))
1555 try_return( ntStatus);
1558 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1559 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1562 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1563 AFS_TRACE_LEVEL_VERBOSE_2,
1564 "AFSValidateSymLink Invalid type Status %08lX\n",
1565 STATUS_OBJECT_NAME_NOT_FOUND));
1567 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1570 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1572 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1574 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1577 // Update the target name information if needed
1580 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1582 uniTargetName.MaximumLength = uniTargetName.Length;
1584 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1586 if( uniTargetName.Length > 0)
1589 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1592 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1593 RtlCompareUnicodeString( &uniTargetName,
1594 &DirEntry->NameInformation.TargetName,
1599 // Update the target name
1602 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1604 uniTargetName.Buffer,
1605 uniTargetName.Length);
1607 if( !NT_SUCCESS( ntStatus))
1610 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1612 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1616 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1620 // If the FileType is the same then nothing to do since it IS
1624 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1627 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1629 try_return( ntStatus = STATUS_SUCCESS);
1632 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1634 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1636 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1638 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1640 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1642 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1644 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1646 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1648 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1649 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1652 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1655 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1658 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1661 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1666 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1670 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1672 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1676 if( pDirEntry != NULL)
1679 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1687 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1691 NTSTATUS ntStatus = STATUS_SUCCESS;
1692 IO_STATUS_BLOCK stIoStatus;
1694 AFSObjectInfoCB * pParentObjectInfo = NULL;
1696 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1697 AFS_TRACE_LEVEL_VERBOSE,
1698 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1699 (*ppObjectInfo)->FileType,
1700 (*ppObjectInfo)->FileId.Cell,
1701 (*ppObjectInfo)->FileId.Volume,
1702 (*ppObjectInfo)->FileId.Vnode,
1703 (*ppObjectInfo)->FileId.Unique,
1706 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1709 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1710 &(*ppObjectInfo)->ParentFileId,
1714 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1715 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1716 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1719 // We only act on the mount point itself, not the target. If the
1720 // node has been deleted then mark it as such otherwise indicate
1721 // it requires verification
1724 if( Reason == AFS_INVALIDATE_DELETED)
1726 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1731 if( Reason == AFS_INVALIDATE_FLUSHED)
1734 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1736 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1739 (*ppObjectInfo)->Expiration.QuadPart = 0;
1741 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1743 (*ppObjectInfo)->TargetFileId.Unique = 0;
1745 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1746 AFS_TRACE_LEVEL_VERBOSE,
1747 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1748 (*ppObjectInfo)->FileId.Cell,
1749 (*ppObjectInfo)->FileId.Volume,
1750 (*ppObjectInfo)->FileId.Vnode,
1751 (*ppObjectInfo)->FileId.Unique));
1753 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1756 if ( pParentObjectInfo != NULL)
1759 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1761 if( Reason == AFS_INVALIDATE_CREDS)
1763 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1766 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1767 Reason == AFS_INVALIDATE_FLUSHED)
1769 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1773 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1776 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1779 FILE_ACTION_MODIFIED);
1782 try_return( ntStatus);
1786 // Depending on the reason for invalidation then perform work on the node
1792 case AFS_INVALIDATE_DELETED:
1796 // Mark this node as invalid
1799 (*ppObjectInfo)->Links = 0;
1801 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1803 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1804 AFS_TRACE_LEVEL_VERBOSE,
1805 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1806 (*ppObjectInfo)->FileId.Cell,
1807 (*ppObjectInfo)->FileId.Volume,
1808 (*ppObjectInfo)->FileId.Vnode,
1809 (*ppObjectInfo)->FileId.Unique));
1811 if( pParentObjectInfo != NULL)
1814 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1815 AFS_TRACE_LEVEL_VERBOSE,
1816 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1817 pParentObjectInfo->FileId.Cell,
1818 pParentObjectInfo->FileId.Volume,
1819 pParentObjectInfo->FileId.Vnode,
1820 pParentObjectInfo->FileId.Unique));
1822 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1824 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1826 pParentObjectInfo->Expiration.QuadPart = 0;
1828 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1830 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1834 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1837 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1840 FILE_ACTION_REMOVED);
1843 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1846 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1852 case AFS_INVALIDATE_FLUSHED:
1855 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1856 (*ppObjectInfo)->Fcb != NULL)
1859 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1860 AFS_TRACE_LEVEL_VERBOSE,
1861 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1862 (*ppObjectInfo)->FileId.Cell,
1863 (*ppObjectInfo)->FileId.Volume,
1864 (*ppObjectInfo)->FileId.Vnode,
1865 (*ppObjectInfo)->FileId.Unique));
1867 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1873 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1878 if( !NT_SUCCESS( stIoStatus.Status))
1881 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1882 AFS_TRACE_LEVEL_ERROR,
1883 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1884 (*ppObjectInfo)->FileId.Cell,
1885 (*ppObjectInfo)->FileId.Volume,
1886 (*ppObjectInfo)->FileId.Vnode,
1887 (*ppObjectInfo)->FileId.Unique,
1889 stIoStatus.Information));
1891 ntStatus = stIoStatus.Status;
1895 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1898 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1904 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1905 AFS_TRACE_LEVEL_WARNING,
1906 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1907 (*ppObjectInfo)->FileId.Cell,
1908 (*ppObjectInfo)->FileId.Volume,
1909 (*ppObjectInfo)->FileId.Vnode,
1910 (*ppObjectInfo)->FileId.Unique));
1912 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1916 __except( EXCEPTION_EXECUTE_HANDLER)
1919 ntStatus = GetExceptionCode();
1923 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1924 (*ppObjectInfo)->FileId.Cell,
1925 (*ppObjectInfo)->FileId.Volume,
1926 (*ppObjectInfo)->FileId.Vnode,
1927 (*ppObjectInfo)->FileId.Unique,
1930 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1933 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1936 // Clear out the extents
1937 // Get rid of them (note this involves waiting
1938 // for any writes or reads to the cache to complete)
1941 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1945 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1948 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1951 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1952 AFS_TRACE_LEVEL_VERBOSE,
1953 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1954 (*ppObjectInfo)->FileId.Cell,
1955 (*ppObjectInfo)->FileId.Volume,
1956 (*ppObjectInfo)->FileId.Vnode,
1957 (*ppObjectInfo)->FileId.Unique));
1959 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1962 // Fall through to the default processing
1968 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1970 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1974 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1977 if( Reason == AFS_INVALIDATE_CREDS)
1979 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1982 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1984 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1988 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1991 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1994 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1997 FILE_ACTION_MODIFIED);
1999 else if ( pParentObjectInfo != NULL)
2002 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2005 FILE_ACTION_MODIFIED);
2009 // Indicate this node requires re-evaluation for the remaining reasons
2012 (*ppObjectInfo)->Expiration.QuadPart = 0;
2014 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2015 AFS_TRACE_LEVEL_VERBOSE,
2016 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2017 (*ppObjectInfo)->FileId.Cell,
2018 (*ppObjectInfo)->FileId.Volume,
2019 (*ppObjectInfo)->FileId.Vnode,
2020 (*ppObjectInfo)->FileId.Unique));
2022 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
2024 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2025 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
2026 ( Reason == AFS_INVALIDATE_CALLBACK ||
2027 Reason == AFS_INVALIDATE_EXPIRED))
2029 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
2030 AFS_INVALIDATE_DATA_VERSION)))
2033 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
2043 if ( pParentObjectInfo != NULL)
2046 AFSReleaseObjectInfo( &pParentObjectInfo);
2053 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
2056 NTSTATUS ntStatus = STATUS_SUCCESS;
2057 AFSVolumeCB *pVolumeCB = NULL;
2058 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2059 ULONGLONG ullIndex = 0;
2060 AFSObjectInfoCB *pObjectInfo = NULL;
2066 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2067 AFS_TRACE_LEVEL_VERBOSE,
2068 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
2069 InvalidateCB->FileID.Cell,
2070 InvalidateCB->FileID.Volume,
2071 InvalidateCB->FileID.Vnode,
2072 InvalidateCB->FileID.Unique,
2073 InvalidateCB->FileType,
2074 InvalidateCB->WholeVolume,
2075 InvalidateCB->Reason));
2078 // Need to locate the Fcb for the directory to purge
2081 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2082 AFS_TRACE_LEVEL_VERBOSE,
2083 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2084 &pDevExt->Specific.RDR.VolumeTreeLock,
2085 PsGetCurrentThread()));
2088 // Starve any exclusive waiters on this paticular call
2091 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2094 // Locate the volume node
2097 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2099 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2101 (AFSBTreeEntry **)&pVolumeCB);
2103 if( pVolumeCB != NULL)
2106 lCount = AFSVolumeIncrement( pVolumeCB,
2107 AFS_VOLUME_REFERENCE_INVALIDATE);
2109 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2110 AFS_TRACE_LEVEL_VERBOSE,
2111 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2116 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2118 if( !NT_SUCCESS( ntStatus) ||
2122 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2123 AFS_TRACE_LEVEL_WARNING,
2124 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2125 InvalidateCB->FileID.Cell,
2126 InvalidateCB->FileID.Volume,
2127 InvalidateCB->FileID.Vnode,
2128 InvalidateCB->FileID.Unique,
2131 try_return( ntStatus = STATUS_SUCCESS);
2135 // If this is a whole volume invalidation then go do it now
2138 if( InvalidateCB->WholeVolume)
2141 ntStatus = AFSInvalidateVolume( pVolumeCB,
2142 InvalidateCB->Reason);
2144 try_return( ntStatus);
2147 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
2150 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2153 pObjectInfo = &pVolumeCB->ObjectInformation;
2158 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2160 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2162 (AFSBTreeEntry **)&pObjectInfo);
2165 if( pObjectInfo != NULL)
2169 // Reference the node so it won't be torn down
2172 lCount = AFSObjectInfoIncrement( pObjectInfo,
2173 AFS_OBJECT_REFERENCE_INVALIDATION);
2175 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2176 AFS_TRACE_LEVEL_VERBOSE,
2177 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2182 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2184 if( !NT_SUCCESS( ntStatus) ||
2185 pObjectInfo == NULL)
2188 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2189 AFS_TRACE_LEVEL_VERBOSE,
2190 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2191 InvalidateCB->FileID.Cell,
2192 InvalidateCB->FileID.Volume,
2193 InvalidateCB->FileID.Vnode,
2194 InvalidateCB->FileID.Unique,
2197 try_return( ntStatus = STATUS_SUCCESS);
2200 AFSInvalidateObject( &pObjectInfo,
2201 InvalidateCB->Reason);
2205 if( pObjectInfo != NULL)
2208 lCount = AFSObjectInfoDecrement( pObjectInfo,
2209 AFS_OBJECT_REFERENCE_INVALIDATION);
2211 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2212 AFS_TRACE_LEVEL_VERBOSE,
2213 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2218 if ( pVolumeCB != NULL)
2221 lCount = AFSVolumeDecrement( pVolumeCB,
2222 AFS_VOLUME_REFERENCE_INVALIDATE);
2224 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2225 AFS_TRACE_LEVEL_VERBOSE,
2226 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2236 AFSIsChildOfParent( IN AFSFcb *Dcb,
2240 BOOLEAN bIsChild = FALSE;
2241 AFSFcb *pCurrentFcb = Fcb;
2242 AFSObjectInfoCB * pParentObjectInfo = NULL;
2244 while( pCurrentFcb != NULL)
2247 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2248 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2256 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2257 &pCurrentFcb->ObjectInformation->ParentFileId,
2260 if ( pParentObjectInfo != NULL)
2263 pCurrentFcb = pParentObjectInfo->Fcb;
2265 AFSReleaseObjectInfo( &pParentObjectInfo);
2279 AFSCreateHighIndex( IN AFSFileID *FileID)
2282 ULONGLONG ullIndex = 0;
2284 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2291 AFSCreateLowIndex( IN AFSFileID *FileID)
2294 ULONGLONG ullIndex = 0;
2296 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2302 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2303 IN ACCESS_MASK GrantedAccess,
2304 IN BOOLEAN DirectoryEntry)
2307 BOOLEAN bAccessGranted = TRUE;
2310 // Check if we are asking for read/write and granted only read only
2311 // NOTE: There will be more checks here
2314 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2316 AFSCheckForReadOnlyAccess( GrantedAccess,
2320 bAccessGranted = FALSE;
2323 return bAccessGranted;
2327 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2330 NTSTATUS ntStatus = STATUS_SUCCESS;
2331 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2337 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2339 if( AFSGlobalRoot == NULL)
2346 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2349 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2356 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2363 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2364 IN UNICODE_STRING *SubstituteName,
2365 IN ULONG StringIndex)
2368 NTSTATUS ntStatus = STATUS_SUCCESS;
2369 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2370 AFSSysNameCB *pSysName = NULL;
2371 ERESOURCE *pSysNameLock = NULL;
2374 UNICODE_STRING uniSysName;
2381 if( IoIs32bitProcess( NULL))
2384 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2386 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2391 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2393 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2397 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2399 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2403 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2404 AFS_TRACE_LEVEL_VERBOSE,
2405 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2407 PsGetCurrentThread()));
2409 AFSAcquireShared( pSysNameLock,
2413 // Find where we are in the list
2416 while( pSysName != NULL &&
2417 ulIndex < StringIndex)
2420 pSysName = pSysName->fLink;
2425 if( pSysName == NULL)
2428 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2429 AFS_TRACE_LEVEL_VERBOSE_2,
2430 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2432 STATUS_OBJECT_NAME_NOT_FOUND));
2434 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2437 RtlInitUnicodeString( &uniSysName,
2440 // If it is a full component of @SYS then just substitue the
2444 if( RtlCompareUnicodeString( &uniSysName,
2449 SubstituteName->Length = pSysName->SysName.Length;
2450 SubstituteName->MaximumLength = SubstituteName->Length;
2452 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2453 SubstituteName->Length,
2454 AFS_SUBST_BUFFER_TAG);
2456 if( SubstituteName->Buffer == NULL)
2459 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2462 RtlCopyMemory( SubstituteName->Buffer,
2463 pSysName->SysName.Buffer,
2464 pSysName->SysName.Length);
2471 while( ComponentName->Buffer[ usIndex] != L'@')
2477 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2478 SubstituteName->MaximumLength = SubstituteName->Length;
2480 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2481 SubstituteName->Length,
2482 AFS_SUBST_BUFFER_TAG);
2484 if( SubstituteName->Buffer == NULL)
2487 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2490 RtlCopyMemory( SubstituteName->Buffer,
2491 ComponentName->Buffer,
2492 usIndex * sizeof( WCHAR));
2494 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2495 pSysName->SysName.Buffer,
2496 pSysName->SysName.Length);
2501 AFSReleaseResource( pSysNameLock);
2508 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2509 IN OUT UNICODE_STRING *ComponentName,
2510 IN UNICODE_STRING *SubstituteName,
2511 IN OUT UNICODE_STRING *RemainingPath,
2512 IN BOOLEAN FreePathName)
2515 NTSTATUS ntStatus = STATUS_SUCCESS;
2516 UNICODE_STRING uniPathName;
2517 USHORT usPrefixNameLen = 0;
2518 SHORT sNameLenDelta = 0;
2524 // If the passed in name can handle the additional length
2525 // then just moves things around
2528 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2530 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2532 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2535 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2538 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2539 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2540 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2543 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2544 SubstituteName->Buffer,
2545 SubstituteName->Length);
2547 FullPathName->Length += sNameLenDelta;
2549 ComponentName->Length += sNameLenDelta;
2551 ComponentName->MaximumLength = ComponentName->Length;
2553 if ( RemainingPath->Buffer)
2556 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2559 try_return( ntStatus);
2563 // Need to re-allocate the buffer
2566 uniPathName.Length = FullPathName->Length -
2567 ComponentName->Length +
2568 SubstituteName->Length;
2570 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2572 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2573 uniPathName.MaximumLength,
2574 AFS_NAME_BUFFER_FOUR_TAG);
2576 if( uniPathName.Buffer == NULL)
2579 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2582 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2584 usPrefixNameLen *= sizeof( WCHAR);
2586 RtlZeroMemory( uniPathName.Buffer,
2587 uniPathName.MaximumLength);
2589 RtlCopyMemory( uniPathName.Buffer,
2590 FullPathName->Buffer,
2593 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2594 SubstituteName->Buffer,
2595 SubstituteName->Length);
2597 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2600 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2601 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2602 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2605 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2607 ComponentName->Length += sNameLenDelta;
2609 ComponentName->MaximumLength = ComponentName->Length;
2611 if ( RemainingPath->Buffer)
2614 RemainingPath->Buffer = uniPathName.Buffer
2615 + (RemainingPath->Buffer - FullPathName->Buffer)
2616 + sNameLenDelta/sizeof( WCHAR);
2621 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2624 *FullPathName = uniPathName;
2635 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2639 NTSTATUS ntStatus = STATUS_SUCCESS;
2640 AFSObjectInfoCB *pCurrentObject = NULL;
2641 AFSObjectInfoCB *pNextObject = NULL;
2647 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2648 AFS_TRACE_LEVEL_VERBOSE,
2649 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2650 VolumeCB->ObjectInformation.FileId.Cell,
2651 VolumeCB->ObjectInformation.FileId.Volume,
2652 VolumeCB->ObjectInformation.FileId.Vnode,
2653 VolumeCB->ObjectInformation.FileId.Unique,
2657 // Depending on the reason for invalidation then perform work on the node
2663 case AFS_INVALIDATE_DELETED:
2667 // Mark this volume as invalid
2670 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2672 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2679 // Invalidate the volume root directory
2682 pCurrentObject = &VolumeCB->ObjectInformation;
2684 if ( pCurrentObject )
2687 lCount = AFSObjectInfoIncrement( pCurrentObject,
2688 AFS_OBJECT_REFERENCE_INVALIDATION);
2690 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2691 AFS_TRACE_LEVEL_VERBOSE,
2692 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2696 AFSInvalidateObject( &pCurrentObject,
2699 if ( pCurrentObject)
2702 lCount = AFSObjectInfoDecrement( pCurrentObject,
2703 AFS_OBJECT_REFERENCE_INVALIDATION);
2705 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2706 AFS_TRACE_LEVEL_VERBOSE,
2707 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2714 // Apply invalidation to all other volume objects
2717 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2720 pCurrentObject = VolumeCB->ObjectInfoListHead;
2722 if ( pCurrentObject)
2726 // Reference the node so it won't be torn down
2729 lCount = AFSObjectInfoIncrement( pCurrentObject,
2730 AFS_OBJECT_REFERENCE_INVALIDATION);
2732 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2733 AFS_TRACE_LEVEL_VERBOSE,
2734 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2739 while( pCurrentObject != NULL)
2742 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2748 // Reference the node so it won't be torn down
2751 lCount = AFSObjectInfoIncrement( pNextObject,
2752 AFS_OBJECT_REFERENCE_INVALIDATION);
2754 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2755 AFS_TRACE_LEVEL_VERBOSE,
2756 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2761 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2763 AFSInvalidateObject( &pCurrentObject,
2766 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2769 if ( pCurrentObject )
2772 lCount = AFSObjectInfoDecrement( pCurrentObject,
2773 AFS_OBJECT_REFERENCE_INVALIDATION);
2775 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2776 AFS_TRACE_LEVEL_VERBOSE,
2777 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2782 pCurrentObject = pNextObject;
2785 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2792 AFSInvalidateAllVolumes( VOID)
2794 AFSVolumeCB *pVolumeCB = NULL;
2795 AFSVolumeCB *pNextVolumeCB = NULL;
2796 AFSDeviceExt *pRDRDeviceExt = NULL;
2799 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2801 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2802 AFS_TRACE_LEVEL_VERBOSE,
2803 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2804 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2805 PsGetCurrentThread()));
2807 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2810 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2815 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2816 AFS_TRACE_LEVEL_VERBOSE,
2817 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2818 pVolumeCB->ObjectInfoTree.TreeLock,
2819 PsGetCurrentThread()));
2821 lCount = AFSVolumeIncrement( pVolumeCB,
2822 AFS_VOLUME_REFERENCE_INVALIDATE);
2824 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2825 AFS_TRACE_LEVEL_VERBOSE,
2826 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2831 while( pVolumeCB != NULL)
2834 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2839 lCount = AFSVolumeIncrement( pNextVolumeCB,
2840 AFS_VOLUME_REFERENCE_INVALIDATE);
2842 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2843 AFS_TRACE_LEVEL_VERBOSE,
2844 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2849 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2851 // do I need to hold the volume lock here?
2853 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2855 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2858 lCount = AFSVolumeDecrement( pVolumeCB,
2859 AFS_VOLUME_REFERENCE_INVALIDATE);
2861 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2862 AFS_TRACE_LEVEL_VERBOSE,
2863 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2867 pVolumeCB = pNextVolumeCB;
2870 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2874 AFSVerifyEntry( IN GUID *AuthGroup,
2875 IN AFSDirectoryCB *DirEntry)
2878 NTSTATUS ntStatus = STATUS_SUCCESS;
2879 AFSDirEnumEntry *pDirEnumEntry = NULL;
2880 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2881 IO_STATUS_BLOCK stIoStatus;
2886 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2887 AFS_TRACE_LEVEL_VERBOSE_2,
2888 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2889 &DirEntry->NameInformation.FileName,
2890 pObjectInfo->FileId.Cell,
2891 pObjectInfo->FileId.Volume,
2892 pObjectInfo->FileId.Vnode,
2893 pObjectInfo->FileId.Unique));
2895 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2900 if( !NT_SUCCESS( ntStatus))
2903 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2904 AFS_TRACE_LEVEL_ERROR,
2905 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2906 &DirEntry->NameInformation.FileName,
2907 pObjectInfo->FileId.Cell,
2908 pObjectInfo->FileId.Volume,
2909 pObjectInfo->FileId.Vnode,
2910 pObjectInfo->FileId.Unique,
2913 try_return( ntStatus);
2917 // Check the data version of the file
2920 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2922 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2925 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2926 AFS_TRACE_LEVEL_VERBOSE,
2927 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2928 pObjectInfo->DataVersion.QuadPart,
2929 &DirEntry->NameInformation.FileName,
2930 pObjectInfo->FileId.Cell,
2931 pObjectInfo->FileId.Volume,
2932 pObjectInfo->FileId.Vnode,
2933 pObjectInfo->FileId.Unique));
2936 // We are ok, just get out
2939 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2941 try_return( ntStatus = STATUS_SUCCESS);
2946 // New data version so we will need to process the node based on the type
2949 switch( pDirEnumEntry->FileType)
2952 case AFS_FILE_TYPE_MOUNTPOINT:
2956 // For a mount point we need to ensure the target is the same
2959 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2960 &pDirEnumEntry->TargetFileId))
2966 // Update the metadata for the entry
2969 ntStatus = AFSUpdateMetaData( DirEntry,
2972 if( NT_SUCCESS( ntStatus))
2975 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2981 case AFS_FILE_TYPE_SYMLINK:
2985 // Update the metadata for the entry
2988 ntStatus = AFSUpdateMetaData( DirEntry,
2991 if( NT_SUCCESS( ntStatus))
2994 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3000 case AFS_FILE_TYPE_FILE:
3002 FILE_OBJECT * pCCFileObject = NULL;
3003 BOOLEAN bPurgeExtents = FALSE;
3005 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3008 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3009 AFS_TRACE_LEVEL_VERBOSE,
3010 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
3011 &DirEntry->NameInformation.FileName,
3012 pObjectInfo->FileId.Cell,
3013 pObjectInfo->FileId.Volume,
3014 pObjectInfo->FileId.Vnode,
3015 pObjectInfo->FileId.Unique,
3016 pObjectInfo->DataVersion.LowPart,
3017 pDirEnumEntry->DataVersion.LowPart));
3019 bPurgeExtents = TRUE;
3022 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3025 bPurgeExtents = TRUE;
3027 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3028 AFS_TRACE_LEVEL_VERBOSE,
3029 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3030 &DirEntry->NameInformation.FileName,
3031 pObjectInfo->FileId.Cell,
3032 pObjectInfo->FileId.Volume,
3033 pObjectInfo->FileId.Vnode,
3034 pObjectInfo->FileId.Unique));
3036 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3039 if( pObjectInfo->Fcb != NULL)
3042 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3043 AFS_TRACE_LEVEL_VERBOSE,
3044 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3045 &DirEntry->NameInformation.FileName,
3046 pObjectInfo->FileId.Cell,
3047 pObjectInfo->FileId.Volume,
3048 pObjectInfo->FileId.Vnode,
3049 pObjectInfo->FileId.Unique));
3051 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3057 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3062 if( !NT_SUCCESS( stIoStatus.Status))
3065 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3066 AFS_TRACE_LEVEL_ERROR,
3067 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3068 &DirEntry->NameInformation.FileName,
3069 pObjectInfo->FileId.Cell,
3070 pObjectInfo->FileId.Volume,
3071 pObjectInfo->FileId.Vnode,
3072 pObjectInfo->FileId.Unique,
3074 stIoStatus.Information));
3076 ntStatus = stIoStatus.Status;
3079 if ( bPurgeExtents &&
3080 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3083 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3089 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3090 AFS_TRACE_LEVEL_WARNING,
3091 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3092 &DirEntry->NameInformation.FileName,
3093 pObjectInfo->FileId.Cell,
3094 pObjectInfo->FileId.Volume,
3095 pObjectInfo->FileId.Vnode,
3096 pObjectInfo->FileId.Unique));
3098 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3102 __except( EXCEPTION_EXECUTE_HANDLER)
3104 ntStatus = GetExceptionCode();
3108 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3109 &DirEntry->NameInformation.FileName,
3110 pObjectInfo->FileId.Cell,
3111 pObjectInfo->FileId.Volume,
3112 pObjectInfo->FileId.Vnode,
3113 pObjectInfo->FileId.Unique,
3116 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3119 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3123 AFSFlushExtents( pObjectInfo->Fcb,
3128 // Reacquire the Fcb to purge the cache
3131 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3132 AFS_TRACE_LEVEL_VERBOSE,
3133 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3134 &pObjectInfo->Fcb->NPFcb->Resource,
3135 PsGetCurrentThread()));
3137 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3141 // Update the metadata for the entry
3144 ntStatus = AFSUpdateMetaData( DirEntry,
3147 if( !NT_SUCCESS( ntStatus))
3150 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3151 AFS_TRACE_LEVEL_ERROR,
3152 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3153 &DirEntry->NameInformation.FileName,
3154 pObjectInfo->FileId.Cell,
3155 pObjectInfo->FileId.Volume,
3156 pObjectInfo->FileId.Vnode,
3157 pObjectInfo->FileId.Unique,
3164 // Update file sizes
3167 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3168 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3169 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3171 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3172 AFS_TRACE_LEVEL_VERBOSE,
3173 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3174 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3175 PsGetCurrentThread()));
3177 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3180 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3182 if ( pCCFileObject != NULL)
3184 CcSetFileSizes( pCCFileObject,
3185 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3188 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3189 AFS_TRACE_LEVEL_VERBOSE,
3190 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3191 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3192 PsGetCurrentThread()));
3194 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3196 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3202 // Update the metadata for the entry
3205 ntStatus = AFSUpdateMetaData( DirEntry,
3208 if( !NT_SUCCESS( ntStatus))
3211 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3212 AFS_TRACE_LEVEL_ERROR,
3213 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3214 &DirEntry->NameInformation.FileName,
3215 pObjectInfo->FileId.Cell,
3216 pObjectInfo->FileId.Volume,
3217 pObjectInfo->FileId.Vnode,
3218 pObjectInfo->FileId.Unique,
3224 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3225 AFS_TRACE_LEVEL_WARNING,
3226 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3227 &DirEntry->NameInformation.FileName,
3228 pObjectInfo->FileId.Cell,
3229 pObjectInfo->FileId.Volume,
3230 pObjectInfo->FileId.Vnode,
3231 pObjectInfo->FileId.Unique));
3234 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3239 case AFS_FILE_TYPE_DIRECTORY:
3243 // For a directory or root entry flush the content of
3244 // the directory enumeration.
3247 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3250 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3251 AFS_TRACE_LEVEL_VERBOSE_2,
3252 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3253 &DirEntry->NameInformation.FileName,
3254 pObjectInfo->FileId.Cell,
3255 pObjectInfo->FileId.Volume,
3256 pObjectInfo->FileId.Vnode,
3257 pObjectInfo->FileId.Unique));
3259 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3262 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3265 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3267 if ( !NT_SUCCESS( ntStatus))
3270 try_return( ntStatus);
3275 // Update the metadata for the entry
3278 ntStatus = AFSUpdateMetaData( DirEntry,
3281 if( NT_SUCCESS( ntStatus))
3284 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3290 case AFS_FILE_TYPE_DFSLINK:
3293 UNICODE_STRING uniTargetName;
3296 // For a DFS link need to check the target name has not changed
3299 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3301 uniTargetName.MaximumLength = uniTargetName.Length;
3303 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3305 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3308 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3309 RtlCompareUnicodeString( &uniTargetName,
3310 &DirEntry->NameInformation.TargetName,
3315 // Update the target name
3318 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3320 uniTargetName.Buffer,
3321 uniTargetName.Length);
3323 if( !NT_SUCCESS( ntStatus))
3326 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3332 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3335 // Update the metadata for the entry
3338 ntStatus = AFSUpdateMetaData( DirEntry,
3341 if( NT_SUCCESS( ntStatus))
3344 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3352 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3353 AFS_TRACE_LEVEL_WARNING,
3354 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3355 pObjectInfo->FileType,
3356 &DirEntry->NameInformation.FileName,
3357 pObjectInfo->FileId.Cell,
3358 pObjectInfo->FileId.Volume,
3359 pObjectInfo->FileId.Vnode,
3360 pObjectInfo->FileId.Unique));
3367 if( pDirEnumEntry != NULL)
3370 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3378 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3381 NTSTATUS ntStatus = STATUS_SUCCESS;
3382 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3383 ULONGLONG ullIndex = 0;
3384 AFSVolumeCB *pVolumeCB = NULL;
3390 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3391 AFS_TRACE_LEVEL_VERBOSE,
3392 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3393 VolumeStatus->Online,
3394 VolumeStatus->FileID.Cell,
3395 VolumeStatus->FileID.Volume));
3398 // Need to locate the Fcb for the directory to purge
3401 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3402 AFS_TRACE_LEVEL_VERBOSE,
3403 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3404 &pDevExt->Specific.RDR.VolumeTreeLock,
3405 PsGetCurrentThread()));
3407 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3410 // Locate the volume node
3413 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3415 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3417 (AFSBTreeEntry **)&pVolumeCB);
3419 if( pVolumeCB != NULL)
3422 lCount = AFSVolumeIncrement( pVolumeCB,
3423 AFS_VOLUME_REFERENCE_INVALIDATE);
3425 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3426 AFS_TRACE_LEVEL_VERBOSE,
3427 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3431 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3434 // Set the volume state accordingly
3437 if( VolumeStatus->Online)
3440 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3445 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3454 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3457 NTSTATUS ntStatus = STATUS_SUCCESS;
3462 if( AFSGlobalRoot == NULL)
3465 try_return( ntStatus);
3468 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3472 // Set the network state according to the information
3475 if( NetworkStatus->Online)
3478 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3483 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3486 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3497 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3501 NTSTATUS ntStatus = STATUS_SUCCESS;
3502 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3503 BOOLEAN bAcquiredLock = FALSE;
3504 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3509 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3510 AFS_TRACE_LEVEL_VERBOSE,
3511 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3512 ObjectInfo->FileId.Cell,
3513 ObjectInfo->FileId.Volume,
3514 ObjectInfo->FileId.Vnode,
3515 ObjectInfo->FileId.Unique));
3517 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3520 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3521 AFS_TRACE_LEVEL_VERBOSE,
3522 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3523 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3524 PsGetCurrentThread()));
3526 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3529 bAcquiredLock = TRUE;
3533 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3536 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3537 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3540 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3541 AFS_TRACE_LEVEL_ERROR,
3542 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3543 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3544 ObjectInfo->FileId.Cell,
3545 ObjectInfo->FileId.Volume,
3546 ObjectInfo->FileId.Vnode,
3547 ObjectInfo->FileId.Unique));
3551 // Reset the directory list information by clearing all valid entries
3554 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3556 while( pCurrentDirEntry != NULL)
3559 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3561 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3565 // If this entry has been deleted then process it here
3568 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3569 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3570 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3573 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3574 AFS_TRACE_LEVEL_VERBOSE,
3575 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3577 &pCurrentDirEntry->NameInformation.FileName));
3579 AFSDeleteDirEntry( ObjectInfo,
3585 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3587 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3588 AFS_TRACE_LEVEL_VERBOSE,
3589 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3591 pCurrentDirEntry->DirOpenReferenceCount));
3594 // We pull the short name from the parent tree since it could change below
3597 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3600 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3601 AFS_TRACE_LEVEL_VERBOSE,
3602 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3604 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3605 &pCurrentDirEntry->NameInformation.FileName));
3607 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3610 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3615 pCurrentDirEntry = pNextDirEntry;
3619 // Reget the directory contents
3622 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3625 if ( !NT_SUCCESS( ntStatus))
3627 try_return( ntStatus);
3631 // Now start again and tear down any entries not valid
3634 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3636 while( pCurrentDirEntry != NULL)
3639 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3641 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3644 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3645 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3646 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3649 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3652 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3654 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3655 AFS_TRACE_LEVEL_VERBOSE,
3656 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3658 &pCurrentDirEntry->NameInformation.FileName));
3660 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3665 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3668 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3669 AFS_TRACE_LEVEL_VERBOSE,
3670 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3672 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3673 &pCurrentDirEntry->NameInformation.FileName));
3677 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3679 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3680 AFS_TRACE_LEVEL_VERBOSE,
3681 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3683 &pCurrentDirEntry->NameInformation.FileName));
3688 pCurrentDirEntry = pNextDirEntry;
3693 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3694 AFS_TRACE_LEVEL_VERBOSE,
3695 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3697 pCurrentDirEntry->DirOpenReferenceCount));
3699 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3700 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3703 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3704 AFS_TRACE_LEVEL_VERBOSE,
3705 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3706 &pCurrentDirEntry->NameInformation.FileName,
3707 ObjectInfo->FileId.Cell,
3708 ObjectInfo->FileId.Volume,
3709 ObjectInfo->FileId.Vnode,
3710 ObjectInfo->FileId.Unique));
3712 AFSDeleteDirEntry( ObjectInfo,
3718 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3719 AFS_TRACE_LEVEL_VERBOSE,
3720 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3722 &pCurrentDirEntry->NameInformation.FileName,
3723 ObjectInfo->FileId.Cell,
3724 ObjectInfo->FileId.Volume,
3725 ObjectInfo->FileId.Vnode,
3726 ObjectInfo->FileId.Unique));
3728 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3730 AFSRemoveNameEntry( ObjectInfo,
3734 pCurrentDirEntry = pNextDirEntry;
3738 if( !AFSValidateDirList( ObjectInfo))
3741 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3750 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3758 AFSIsVolumeFID( IN AFSFileID *FileID)
3761 BOOLEAN bIsVolume = FALSE;
3763 if( FileID->Vnode == 1 &&
3764 FileID->Unique == 1)
3774 AFSIsFinalNode( IN AFSFcb *Fcb)
3777 BOOLEAN bIsFinalNode = FALSE;
3779 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3780 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3781 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3782 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3783 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3786 bIsFinalNode = TRUE;
3791 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3792 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3795 return bIsFinalNode;
3799 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3800 IN AFSDirEnumEntry *DirEnumEntry)
3803 NTSTATUS ntStatus = STATUS_SUCCESS;
3804 UNICODE_STRING uniTargetName;
3805 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3810 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3812 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3814 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3816 pObjectInfo->FileType = DirEnumEntry->FileType;
3818 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3820 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3822 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3824 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3826 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3828 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3830 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3832 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3833 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3836 pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3839 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
3842 if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
3845 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3850 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3854 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3856 pObjectInfo->Links = DirEnumEntry->Links;
3858 if( DirEnumEntry->TargetNameLength > 0 &&
3859 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3860 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3864 // Update the target name information if needed
3867 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3869 uniTargetName.MaximumLength = uniTargetName.Length;
3871 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3873 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3876 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3877 RtlCompareUnicodeString( &uniTargetName,
3878 &DirEntry->NameInformation.TargetName,
3883 // Update the target name
3886 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3888 uniTargetName.Buffer,
3889 uniTargetName.Length);
3891 if( !NT_SUCCESS( ntStatus))
3894 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3896 try_return( ntStatus);
3900 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3902 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3903 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3906 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3909 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3910 DirEntry->NameInformation.TargetName.Buffer != NULL)
3912 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3915 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3917 DirEntry->NameInformation.TargetName.Length = 0;
3918 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3919 DirEntry->NameInformation.TargetName.Buffer = NULL;
3921 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3933 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3935 IN BOOLEAN FastCall,
3936 IN BOOLEAN bSafeToPurge)
3939 NTSTATUS ntStatus = STATUS_SUCCESS;
3940 LARGE_INTEGER liSystemTime;
3941 AFSDirEnumEntry *pDirEnumEntry = NULL;
3942 AFSFcb *pCurrentFcb = NULL;
3943 BOOLEAN bReleaseFcb = FALSE;
3944 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3950 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3954 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3955 AFS_TRACE_LEVEL_VERBOSE_2,
3956 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3957 &DirEntry->NameInformation.FileName,
3958 pObjectInfo->FileId.Cell,
3959 pObjectInfo->FileId.Volume,
3960 pObjectInfo->FileId.Vnode,
3961 pObjectInfo->FileId.Unique,
3965 // If this is a fake node then bail since the service knows nothing about it
3968 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3971 try_return( ntStatus);
3975 // This routine ensures that the current entry is valid by:
3977 // 1) Checking that the expiration time is non-zero and after where we
3981 KeQuerySystemTime( &liSystemTime);
3983 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3984 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3985 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3986 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3989 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3990 AFS_TRACE_LEVEL_VERBOSE_2,
3991 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3992 &DirEntry->NameInformation.FileName,
3993 pObjectInfo->FileId.Cell,
3994 pObjectInfo->FileId.Volume,
3995 pObjectInfo->FileId.Vnode,
3996 pObjectInfo->FileId.Unique));
3998 try_return( ntStatus);
4002 // This node requires updating
4005 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
4010 if( !NT_SUCCESS( ntStatus))
4013 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4014 AFS_TRACE_LEVEL_ERROR,
4015 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4017 &DirEntry->NameInformation.FileName,
4018 pObjectInfo->FileId.Cell,
4019 pObjectInfo->FileId.Volume,
4020 pObjectInfo->FileId.Vnode,
4021 pObjectInfo->FileId.Unique,
4025 // Failed validation of node so return access-denied
4028 try_return( ntStatus);
4031 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4032 AFS_TRACE_LEVEL_VERBOSE,
4033 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
4035 &DirEntry->NameInformation.FileName,
4036 pObjectInfo->FileId.Cell,
4037 pObjectInfo->FileId.Volume,
4038 pObjectInfo->FileId.Vnode,
4039 pObjectInfo->FileId.Unique,
4040 pObjectInfo->DataVersion.QuadPart,
4041 pDirEnumEntry->DataVersion.QuadPart,
4042 pDirEnumEntry->FileType));
4046 // Based on the file type, process the node
4049 switch( pDirEnumEntry->FileType)
4052 case AFS_FILE_TYPE_MOUNTPOINT:
4056 // Update the metadata for the entry
4059 ntStatus = AFSUpdateMetaData( DirEntry,
4062 if( NT_SUCCESS( ntStatus))
4065 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4071 case AFS_FILE_TYPE_SYMLINK:
4072 case AFS_FILE_TYPE_DFSLINK:
4076 // Update the metadata for the entry
4079 ntStatus = AFSUpdateMetaData( DirEntry,
4082 if( NT_SUCCESS( ntStatus))
4085 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4091 case AFS_FILE_TYPE_FILE:
4094 BOOLEAN bPurgeExtents = FALSE;
4097 // For a file where the data version has become invalid we need to
4098 // fail any current extent requests and purge the cache for the file
4099 // Can't hold the Fcb resource while doing this
4102 if( pObjectInfo->Fcb != NULL &&
4103 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4104 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4107 pCurrentFcb = pObjectInfo->Fcb;
4109 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4112 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4113 AFS_TRACE_LEVEL_VERBOSE,
4114 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4115 &pCurrentFcb->NPFcb->Resource,
4116 PsGetCurrentThread()));
4118 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4124 if( pCurrentFcb != NULL)
4127 IO_STATUS_BLOCK stIoStatus;
4129 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4130 AFS_TRACE_LEVEL_VERBOSE_2,
4131 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4132 &DirEntry->NameInformation.FileName,
4133 pObjectInfo->FileId.Cell,
4134 pObjectInfo->FileId.Volume,
4135 pObjectInfo->FileId.Vnode,
4136 pObjectInfo->FileId.Unique));
4138 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4141 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4142 AFS_TRACE_LEVEL_VERBOSE,
4143 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4144 &DirEntry->NameInformation.FileName,
4145 pObjectInfo->FileId.Cell,
4146 pObjectInfo->FileId.Volume,
4147 pObjectInfo->FileId.Vnode,
4148 pObjectInfo->FileId.Unique,
4149 pObjectInfo->DataVersion.LowPart,
4150 pDirEnumEntry->DataVersion.LowPart));
4152 bPurgeExtents = TRUE;
4158 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4160 bPurgeExtents = TRUE;
4162 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4163 AFS_TRACE_LEVEL_VERBOSE,
4164 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4165 &DirEntry->NameInformation.FileName,
4166 pObjectInfo->FileId.Cell,
4167 pObjectInfo->FileId.Volume,
4168 pObjectInfo->FileId.Vnode,
4169 pObjectInfo->FileId.Unique));
4171 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4174 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4175 AFS_TRACE_LEVEL_VERBOSE,
4176 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4177 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4178 PsGetCurrentThread()));
4180 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4184 // Release Fcb->Resource to avoid Trend Micro deadlock
4187 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
4192 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4197 if( !NT_SUCCESS( stIoStatus.Status))
4200 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4201 AFS_TRACE_LEVEL_ERROR,
4202 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4203 &DirEntry->NameInformation.FileName,
4204 pObjectInfo->FileId.Cell,
4205 pObjectInfo->FileId.Volume,
4206 pObjectInfo->FileId.Vnode,
4207 pObjectInfo->FileId.Unique,
4209 stIoStatus.Information));
4211 ntStatus = stIoStatus.Status;
4214 if ( bPurgeExtents &&
4215 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4218 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4224 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4225 AFS_TRACE_LEVEL_WARNING,
4226 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4227 &DirEntry->NameInformation.FileName,
4228 pObjectInfo->FileId.Cell,
4229 pObjectInfo->FileId.Volume,
4230 pObjectInfo->FileId.Vnode,
4231 pObjectInfo->FileId.Unique));
4233 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4237 __except( EXCEPTION_EXECUTE_HANDLER)
4239 ntStatus = GetExceptionCode();
4243 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4244 &DirEntry->NameInformation.FileName,
4245 pObjectInfo->FileId.Cell,
4246 pObjectInfo->FileId.Volume,
4247 pObjectInfo->FileId.Vnode,
4248 pObjectInfo->FileId.Unique,
4251 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4254 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4255 AFS_TRACE_LEVEL_VERBOSE,
4256 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4257 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4258 PsGetCurrentThread()));
4260 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4262 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4271 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4276 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4278 bReleaseFcb = FALSE;
4280 if ( bPurgeExtents &&
4283 AFSFlushExtents( pCurrentFcb,
4290 // Update the metadata for the entry but only if it is safe to do so.
4291 // If it was determined that a data version change has occurred or
4292 // that a pending data verification was required, do not update the
4293 // ObjectInfo meta data or the FileObject size information. That
4294 // way it is consistent for the next time that the data is verified
4298 if ( !(bPurgeExtents && bSafeToPurge))
4301 ntStatus = AFSUpdateMetaData( DirEntry,
4304 if( !NT_SUCCESS( ntStatus))
4307 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4308 AFS_TRACE_LEVEL_ERROR,
4309 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4310 &DirEntry->NameInformation.FileName,
4311 pObjectInfo->FileId.Cell,
4312 pObjectInfo->FileId.Volume,
4313 pObjectInfo->FileId.Vnode,
4314 pObjectInfo->FileId.Unique,
4320 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4323 // Update file sizes
4326 if( pObjectInfo->Fcb != NULL)
4328 FILE_OBJECT *pCCFileObject;
4330 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4331 AFS_TRACE_LEVEL_VERBOSE,
4332 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4333 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4334 PsGetCurrentThread()));
4336 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4339 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4341 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4342 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4343 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4345 if ( pCCFileObject != NULL)
4347 CcSetFileSizes( pCCFileObject,
4348 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4351 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4352 AFS_TRACE_LEVEL_VERBOSE,
4353 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4354 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4355 PsGetCurrentThread()));
4357 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4363 case AFS_FILE_TYPE_DIRECTORY:
4366 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4370 // For a directory or root entry flush the content of
4371 // the directory enumeration.
4374 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4375 AFS_TRACE_LEVEL_VERBOSE,
4376 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4377 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4378 PsGetCurrentThread()));
4380 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4383 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4384 AFS_TRACE_LEVEL_VERBOSE_2,
4385 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4386 &DirEntry->NameInformation.FileName,
4387 pObjectInfo->FileId.Cell,
4388 pObjectInfo->FileId.Volume,
4389 pObjectInfo->FileId.Vnode,
4390 pObjectInfo->FileId.Unique));
4392 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4395 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4398 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4401 if( !NT_SUCCESS( ntStatus))
4404 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4405 AFS_TRACE_LEVEL_ERROR,
4406 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4407 &DirEntry->NameInformation.FileName,
4408 pObjectInfo->FileId.Cell,
4409 pObjectInfo->FileId.Volume,
4410 pObjectInfo->FileId.Vnode,
4411 pObjectInfo->FileId.Unique,
4419 // Update the metadata for the entry
4422 ntStatus = AFSUpdateMetaData( DirEntry,
4425 if( NT_SUCCESS( ntStatus))
4428 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4436 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4437 AFS_TRACE_LEVEL_WARNING,
4438 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4439 pObjectInfo->FileType,
4441 &DirEntry->NameInformation.FileName,
4442 pObjectInfo->FileId.Cell,
4443 pObjectInfo->FileId.Volume,
4444 pObjectInfo->FileId.Vnode,
4445 pObjectInfo->FileId.Unique));
4455 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4458 if( pDirEnumEntry != NULL)
4461 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4469 AFSInitializeSpecialShareNameList()
4472 NTSTATUS ntStatus = STATUS_SUCCESS;
4473 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4474 AFSObjectInfoCB *pObjectInfoCB = NULL;
4475 UNICODE_STRING uniShareName;
4476 ULONG ulEntryLength = 0;
4477 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4483 RtlInitUnicodeString( &uniShareName,
4486 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4489 if( pObjectInfoCB == NULL)
4492 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4495 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4496 AFS_OBJECT_REFERENCE_GLOBAL);
4498 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4499 AFS_TRACE_LEVEL_VERBOSE,
4500 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4504 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4506 ulEntryLength = sizeof( AFSDirectoryCB) +
4507 uniShareName.Length;
4509 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4513 if( pDirNode == NULL)
4516 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4517 AFS_OBJECT_REFERENCE_GLOBAL);
4519 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4520 AFS_TRACE_LEVEL_VERBOSE,
4521 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4528 AFSDeleteObjectInfo( &pObjectInfoCB);
4531 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4534 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4535 AFS_TRACE_LEVEL_VERBOSE,
4536 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4539 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4540 sizeof( AFSNonPagedDirectoryCB),
4541 AFS_DIR_ENTRY_NP_TAG);
4543 if( pNonPagedDirEntry == NULL)
4546 ExFreePool( pDirNode);
4548 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4549 AFS_OBJECT_REFERENCE_GLOBAL);
4551 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4552 AFS_TRACE_LEVEL_VERBOSE,
4553 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4560 AFSDeleteObjectInfo( &pObjectInfoCB);
4563 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4566 RtlZeroMemory( pDirNode,
4569 RtlZeroMemory( pNonPagedDirEntry,
4570 sizeof( AFSNonPagedDirectoryCB));
4572 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4574 pDirNode->NonPaged = pNonPagedDirEntry;
4576 pDirNode->ObjectInformation = pObjectInfoCB;
4582 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4584 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4586 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4588 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4590 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4591 uniShareName.Buffer,
4592 pDirNode->NameInformation.FileName.Length);
4594 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4597 AFSSpecialShareNames = pDirNode;
4599 pLastDirNode = pDirNode;
4602 RtlInitUnicodeString( &uniShareName,
4605 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4608 if( pObjectInfoCB == NULL)
4611 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4614 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4615 AFS_OBJECT_REFERENCE_GLOBAL);
4617 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4618 AFS_TRACE_LEVEL_VERBOSE,
4619 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4623 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4625 ulEntryLength = sizeof( AFSDirectoryCB) +
4626 uniShareName.Length;
4628 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4632 if( pDirNode == NULL)
4635 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4636 AFS_OBJECT_REFERENCE_GLOBAL);
4638 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4639 AFS_TRACE_LEVEL_VERBOSE,
4640 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4647 AFSDeleteObjectInfo( &pObjectInfoCB);
4650 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4653 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4654 AFS_TRACE_LEVEL_VERBOSE,
4655 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4658 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4659 sizeof( AFSNonPagedDirectoryCB),
4660 AFS_DIR_ENTRY_NP_TAG);
4662 if( pNonPagedDirEntry == NULL)
4665 ExFreePool( pDirNode);
4667 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4668 AFS_OBJECT_REFERENCE_GLOBAL);
4670 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4671 AFS_TRACE_LEVEL_VERBOSE,
4672 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4679 AFSDeleteObjectInfo( &pObjectInfoCB);
4682 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4685 RtlZeroMemory( pDirNode,
4688 RtlZeroMemory( pNonPagedDirEntry,
4689 sizeof( AFSNonPagedDirectoryCB));
4691 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4693 pDirNode->NonPaged = pNonPagedDirEntry;
4695 pDirNode->ObjectInformation = pObjectInfoCB;
4701 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4703 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4705 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4707 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4709 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4710 uniShareName.Buffer,
4711 pDirNode->NameInformation.FileName.Length);
4713 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4716 pLastDirNode->ListEntry.fLink = pDirNode;
4718 pDirNode->ListEntry.bLink = pLastDirNode;
4722 if( !NT_SUCCESS( ntStatus))
4725 if( AFSSpecialShareNames != NULL)
4728 pDirNode = AFSSpecialShareNames;
4730 while( pDirNode != NULL)
4733 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4735 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
4736 AFS_OBJECT_REFERENCE_GLOBAL);
4738 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4739 AFS_TRACE_LEVEL_VERBOSE,
4740 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4741 pDirNode->ObjectInformation,
4747 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4750 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4752 ExFreePool( pDirNode->NonPaged);
4754 ExFreePool( pDirNode);
4756 pDirNode = pLastDirNode;
4759 AFSSpecialShareNames = NULL;
4768 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4769 IN UNICODE_STRING *SecondaryName)
4772 AFSDirectoryCB *pDirectoryCB = NULL;
4773 ULONGLONG ullHash = 0;
4774 UNICODE_STRING uniFullShareName;
4780 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4781 AFS_TRACE_LEVEL_VERBOSE_2,
4782 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4786 uniFullShareName = *ShareName;
4789 // Generate our hash value
4792 ullHash = AFSGenerateCRC( &uniFullShareName,
4796 // Loop through our special share names to see if this is one of them
4799 pDirectoryCB = AFSSpecialShareNames;
4801 while( pDirectoryCB != NULL)
4804 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4810 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4814 return pDirectoryCB;
4818 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4822 // Block on the queue flush event
4825 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4835 AFSWaitOnQueuedReleases()
4838 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4841 // Block on the queue flush event
4844 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4854 AFSIsEqualFID( IN AFSFileID *FileId1,
4855 IN AFSFileID *FileId2)
4858 BOOLEAN bIsEqual = FALSE;
4860 if( FileId1->Hash == FileId2->Hash &&
4861 FileId1->Unique == FileId2->Unique &&
4862 FileId1->Vnode == FileId2->Vnode &&
4863 FileId1->Volume == FileId2->Volume &&
4864 FileId1->Cell == FileId2->Cell)
4874 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4877 NTSTATUS ntStatus = STATUS_SUCCESS;
4878 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4883 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4886 // Reset the directory list information
4889 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4891 while( pCurrentDirEntry != NULL)
4894 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4896 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
4897 pCurrentDirEntry->NameArrayReferenceCount <= 0)
4900 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4901 AFS_TRACE_LEVEL_VERBOSE,
4902 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4904 &pCurrentDirEntry->NameInformation.FileName));
4906 AFSDeleteDirEntry( ObjectInfoCB,
4912 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4913 AFS_TRACE_LEVEL_VERBOSE,
4914 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4916 &pCurrentDirEntry->NameInformation.FileName));
4918 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4920 AFSRemoveNameEntry( ObjectInfoCB,
4924 pCurrentDirEntry = pNextDirEntry;
4927 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4929 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4931 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4933 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4935 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4937 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4939 AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4940 AFS_TRACE_LEVEL_VERBOSE,
4941 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4942 ObjectInfoCB->FileId.Cell,
4943 ObjectInfoCB->FileId.Volume,
4944 ObjectInfoCB->FileId.Vnode,
4945 ObjectInfoCB->FileId.Unique));
4952 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4955 NTSTATUS ntStatus = STATUS_SUCCESS;
4956 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4957 UNICODE_STRING uniFullName;
4962 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4963 AFS_TRACE_LEVEL_VERBOSE,
4964 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4965 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4966 PsGetCurrentThread()));
4968 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4971 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4974 try_return( ntStatus);
4978 // Initialize the root information
4981 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4984 // Enumerate the shares in the volume
4987 ntStatus = AFSEnumerateDirectory( AuthGroup,
4988 &AFSGlobalRoot->ObjectInformation,
4991 if( !NT_SUCCESS( ntStatus))
4994 try_return( ntStatus);
4997 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4999 uniFullName.MaximumLength = PAGE_SIZE;
5000 uniFullName.Length = 0;
5002 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
5003 uniFullName.MaximumLength,
5004 AFS_GENERIC_MEMORY_12_TAG);
5006 if( uniFullName.Buffer == NULL)
5010 // Reset the directory content
5013 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
5015 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
5017 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5021 // Populate our list of entries in the NP enumeration list
5024 while( pDirGlobalDirNode != NULL)
5027 uniFullName.Buffer[ 0] = L'\\';
5028 uniFullName.Buffer[ 1] = L'\\';
5030 uniFullName.Length = 2 * sizeof( WCHAR);
5032 RtlCopyMemory( &uniFullName.Buffer[ 2],
5033 AFSServerName.Buffer,
5034 AFSServerName.Length);
5036 uniFullName.Length += AFSServerName.Length;
5038 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
5040 uniFullName.Length += sizeof( WCHAR);
5042 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
5043 pDirGlobalDirNode->NameInformation.FileName.Buffer,
5044 pDirGlobalDirNode->NameInformation.FileName.Length);
5046 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
5048 AFSAddConnectionEx( &uniFullName,
5049 RESOURCEDISPLAYTYPE_SHARE,
5052 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
5055 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
5059 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
5066 AFSIsRelativeName( IN UNICODE_STRING *Name)
5069 BOOLEAN bIsRelative = FALSE;
5071 if( Name->Length > 0 &&
5072 Name->Buffer[ 0] != L'\\')
5082 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
5084 UNICODE_STRING uniTempName;
5085 BOOLEAN bIsAbsolute = FALSE;
5088 // An absolute AFS path must begin with \afs\... or equivalent
5091 if ( Name->Length == 0 ||
5092 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
5093 Name->Buffer[ 0] != L'\\' ||
5094 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
5100 uniTempName.Length = AFSMountRootName.Length;
5101 uniTempName.MaximumLength = AFSMountRootName.Length;
5103 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5104 uniTempName.MaximumLength,
5105 AFS_NAME_BUFFER_TWO_TAG);
5107 if( uniTempName.Buffer == NULL)
5113 RtlCopyMemory( uniTempName.Buffer,
5115 AFSMountRootName.Length);
5117 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
5121 AFSExFreePoolWithTag( uniTempName.Buffer,
5122 AFS_NAME_BUFFER_TWO_TAG);
5129 AFSUpdateName( IN UNICODE_STRING *Name)
5134 while( usIndex < Name->Length/sizeof( WCHAR))
5137 if( Name->Buffer[ usIndex] == L'/')
5140 Name->Buffer[ usIndex] = L'\\';
5150 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
5151 IN OUT ULONG *Flags,
5152 IN WCHAR *NameBuffer,
5153 IN USHORT NameLength)
5156 NTSTATUS ntStatus = STATUS_SUCCESS;
5157 WCHAR *pTmpBuffer = NULL;
5163 // If we have enough space then just move in the name otherwise
5164 // allocate a new buffer
5167 if( TargetName->Length < NameLength)
5170 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5172 AFS_NAME_BUFFER_FIVE_TAG);
5174 if( pTmpBuffer == NULL)
5177 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5180 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5183 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5186 TargetName->MaximumLength = NameLength;
5188 TargetName->Buffer = pTmpBuffer;
5190 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5193 TargetName->Length = NameLength;
5195 RtlCopyMemory( TargetName->Buffer,
5197 TargetName->Length);
5200 // Update the name in the buffer
5203 AFSUpdateName( TargetName);
5214 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5219 // Depending on the type of node, set the event
5222 switch( Fcb->Header.NodeTypeCode)
5225 case AFS_DIRECTORY_FCB:
5230 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5240 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5246 // Depending on the type of node, set the event
5249 switch( Fcb->Header.NodeTypeCode)
5252 case AFS_DIRECTORY_FCB:
5257 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5259 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5269 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5272 BOOLEAN bIsInProcess = FALSE;
5277 if( ObjectInfo->Fcb == NULL)
5280 try_return( bIsInProcess);
5283 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5286 case AFS_DIRECTORY_FCB:
5291 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5294 bIsInProcess = TRUE;
5306 return bIsInProcess;
5310 AFSVerifyVolume( IN ULONGLONG ProcessId,
5311 IN AFSVolumeCB *VolumeCB)
5314 UNREFERENCED_PARAMETER(ProcessId);
5315 UNREFERENCED_PARAMETER(VolumeCB);
5316 NTSTATUS ntStatus = STATUS_SUCCESS;
5323 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5326 NTSTATUS ntStatus = STATUS_SUCCESS;
5327 AFSObjectInfoCB *pObjectInfoCB = NULL;
5328 AFSDirectoryCB *pDirNode = NULL;
5329 ULONG ulEntryLength = 0;
5330 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5336 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
5339 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5342 if( pObjectInfoCB == NULL)
5345 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5347 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5350 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5351 AFS_OBJECT_REFERENCE_PIOCTL);
5353 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5354 AFS_TRACE_LEVEL_VERBOSE,
5355 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5359 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5361 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5363 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5365 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5367 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5371 if( pDirNode == NULL)
5374 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5377 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5378 AFS_TRACE_LEVEL_VERBOSE,
5379 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5382 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5383 sizeof( AFSNonPagedDirectoryCB),
5384 AFS_DIR_ENTRY_NP_TAG);
5386 if( pNonPagedDirEntry == NULL)
5389 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5392 RtlZeroMemory( pDirNode,
5395 RtlZeroMemory( pNonPagedDirEntry,
5396 sizeof( AFSNonPagedDirectoryCB));
5398 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5400 pDirNode->NonPaged = pNonPagedDirEntry;
5402 pDirNode->ObjectInformation = pObjectInfoCB;
5404 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5410 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5412 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5414 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5416 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5418 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5419 AFSPIOCtlName.Buffer,
5420 pDirNode->NameInformation.FileName.Length);
5422 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5425 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5428 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5429 AFS_TRACE_LEVEL_WARNING,
5430 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5431 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5434 try_return( ntStatus = STATUS_REPARSE);
5439 if ( ntStatus != STATUS_SUCCESS)
5442 if ( pDirNode != NULL)
5445 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5446 AFS_TRACE_LEVEL_VERBOSE,
5447 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
5450 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5453 if( pNonPagedDirEntry != NULL)
5456 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5458 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5461 if ( pObjectInfoCB != NULL)
5464 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
5465 AFS_OBJECT_REFERENCE_PIOCTL);
5467 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5468 AFS_TRACE_LEVEL_VERBOSE,
5469 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
5476 AFSDeleteObjectInfo( &pObjectInfoCB);
5486 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5487 IN AFSDirectoryCB *DirectoryCB,
5488 IN UNICODE_STRING *ParentPathName,
5489 IN AFSNameArrayHdr *RelatedNameArray,
5491 OUT AFSFileInfoCB *FileInfo)
5494 NTSTATUS ntStatus = STATUS_SUCCESS;
5495 AFSDirEnumEntry *pDirEntry = NULL;
5496 UNICODE_STRING uniFullPathName = {0};
5497 AFSNameArrayHdr *pNameArray = NULL;
5498 AFSVolumeCB *pVolumeCB = NULL;
5499 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5500 AFSVolumeCB *pNewVolumeCB = NULL;
5501 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5502 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5503 AFSDirectoryCB *pNewParentDirEntry = NULL;
5504 WCHAR *pwchBuffer = NULL;
5505 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5506 ULONG ulNameDifference = 0;
5513 // Retrieve a target name for the entry
5516 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5519 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5522 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5524 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5529 if( !NT_SUCCESS( ntStatus) ||
5530 pDirEntry->TargetNameLength == 0)
5533 if( pDirEntry != NULL)
5536 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5539 try_return( ntStatus);
5542 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5545 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5549 // Update the target name
5552 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5553 &DirectoryCB->Flags,
5554 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5555 (USHORT)pDirEntry->TargetNameLength);
5557 if( !NT_SUCCESS( ntStatus))
5560 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5562 try_return( ntStatus);
5566 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5570 // Need to pass the full path in for parsing.
5573 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5576 uniFullPathName.Length = 0;
5577 uniFullPathName.MaximumLength = ParentPathName->Length +
5579 DirectoryCB->NameInformation.TargetName.Length;
5581 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5582 uniFullPathName.MaximumLength,
5583 AFS_NAME_BUFFER_SIX_TAG);
5585 if( uniFullPathName.Buffer == NULL)
5588 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5590 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5593 pwchBuffer = uniFullPathName.Buffer;
5595 RtlZeroMemory( uniFullPathName.Buffer,
5596 uniFullPathName.MaximumLength);
5598 RtlCopyMemory( uniFullPathName.Buffer,
5599 ParentPathName->Buffer,
5600 ParentPathName->Length);
5602 uniFullPathName.Length = ParentPathName->Length;
5604 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5605 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5608 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5610 uniFullPathName.Length += sizeof( WCHAR);
5613 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5614 DirectoryCB->NameInformation.TargetName.Buffer,
5615 DirectoryCB->NameInformation.TargetName.Length);
5617 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5619 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5620 uniParsedName.MaximumLength = uniParsedName.Length;
5622 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5624 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5627 // We populate up to the current parent
5630 if( RelatedNameArray != NULL)
5633 pNameArray = AFSInitNameArray( NULL,
5634 RelatedNameArray->MaxElementCount);
5636 if( pNameArray == NULL)
5639 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5642 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5649 pNameArray = AFSInitNameArray( NULL,
5652 if( pNameArray == NULL)
5655 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5658 ntStatus = AFSPopulateNameArray( pNameArray,
5663 if( !NT_SUCCESS( ntStatus))
5666 try_return( ntStatus);
5669 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5671 pParentDirEntry = ParentDirectoryCB;
5676 uniFullPathName.Length = 0;
5677 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5679 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5680 uniFullPathName.MaximumLength,
5681 AFS_NAME_BUFFER_SEVEN_TAG);
5683 if( uniFullPathName.Buffer == NULL)
5686 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5688 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5691 pwchBuffer = uniFullPathName.Buffer;
5693 RtlZeroMemory( uniFullPathName.Buffer,
5694 uniFullPathName.MaximumLength);
5696 RtlCopyMemory( uniFullPathName.Buffer,
5697 DirectoryCB->NameInformation.TargetName.Buffer,
5698 DirectoryCB->NameInformation.TargetName.Length);
5700 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5703 // This name should begin with the \afs server so parse it off and check it
5706 FsRtlDissectName( uniFullPathName,
5710 if( RtlCompareUnicodeString( &uniComponentName,
5715 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5717 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5718 AFS_TRACE_LEVEL_ERROR,
5719 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5722 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5725 uniFullPathName = uniRemainingPath;
5727 uniParsedName = uniFullPathName;
5729 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5731 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5737 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5740 if( pNameArray == NULL)
5743 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5746 pVolumeCB = AFSGlobalRoot;
5748 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5752 // Increment the ref count on the volume and dir entry for correct processing below
5755 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
5757 lCount = AFSVolumeIncrement( pVolumeCB,
5758 VolumeReferenceReason);
5760 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5761 AFS_TRACE_LEVEL_VERBOSE,
5762 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
5764 VolumeReferenceReason,
5767 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
5769 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5770 AFS_TRACE_LEVEL_VERBOSE,
5771 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5772 &pParentDirEntry->NameInformation.FileName,
5777 ntStatus = AFSLocateNameEntry( NULL,
5782 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5786 &NewVolumeReferenceReason,
5787 &pNewParentDirEntry,
5791 if ( pNewVolumeCB != NULL)
5794 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
5795 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
5796 // the reference on pVolumeCB that was held prior to the call.
5797 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
5798 // will be released second.
5801 lCount = AFSVolumeDecrement( pVolumeCB,
5802 VolumeReferenceReason);
5804 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5805 AFS_TRACE_LEVEL_VERBOSE,
5806 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
5808 VolumeReferenceReason,
5811 pVolumeCB = pNewVolumeCB;
5813 pNewVolumeCB = NULL;
5815 VolumeReferenceReason = NewVolumeReferenceReason;
5817 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5821 // AFSLocateNameEntry does not alter the reference count of
5822 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
5823 // a reference held.
5826 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5828 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5829 AFS_TRACE_LEVEL_VERBOSE,
5830 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
5831 &pParentDirEntry->NameInformation.FileName,
5835 pParentDirEntry = pNewParentDirEntry;
5837 pNewParentDirEntry = NULL;
5839 if( !NT_SUCCESS( ntStatus) ||
5840 ntStatus == STATUS_REPARSE)
5843 try_return( ntStatus);
5847 // Store off the information
5850 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5853 // Check for the mount point being returned
5856 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
5857 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5860 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5862 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
5865 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
5868 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
5873 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5877 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5879 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5881 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5883 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5885 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5887 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5891 if( pDirEntry != NULL)
5894 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
5897 if( pDirectoryEntry != NULL)
5900 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
5902 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5903 AFS_TRACE_LEVEL_VERBOSE,
5904 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5905 &pDirectoryEntry->NameInformation.FileName,
5910 ASSERT( lCount >= 0);
5913 if ( pParentDirEntry != NULL)
5916 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5918 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5919 AFS_TRACE_LEVEL_VERBOSE,
5920 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5921 &pParentDirEntry->NameInformation.FileName,
5926 ASSERT( lCount >= 0);
5929 if( pVolumeCB != NULL)
5932 lCount = AFSVolumeDecrement( pVolumeCB,
5933 VolumeReferenceReason);
5935 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5936 AFS_TRACE_LEVEL_VERBOSE,
5937 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
5939 VolumeReferenceReason,
5943 if( pNameArray != NULL)
5946 AFSFreeNameArray( pNameArray);
5949 if( pwchBuffer != NULL)
5953 // Always free the buffer that we allocated as AFSLocateNameEntry
5954 // will not free it. If uniFullPathName.Buffer was allocated by
5955 // AFSLocateNameEntry, then we must free that as well.
5956 // Check that the uniFullPathName.Buffer in the string is not the same
5957 // offset by the length of the server name
5960 if( uniFullPathName.Length > 0 &&
5961 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
5964 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
5967 AFSExFreePoolWithTag( pwchBuffer, 0);
5975 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
5976 IN ULONGLONG HashIndex)
5979 NTSTATUS ntStatus = STATUS_SUCCESS;
5980 AFSObjectInfoCB *pObjectInfo = NULL;
5986 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
5987 sizeof( AFSObjectInfoCB),
5988 AFS_OBJECT_INFO_TAG);
5990 if( pObjectInfo == NULL)
5993 try_return( pObjectInfo);
5996 RtlZeroMemory( pObjectInfo,
5997 sizeof( AFSObjectInfoCB));
5999 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6000 sizeof( AFSNonPagedObjectInfoCB),
6001 AFS_NP_OBJECT_INFO_TAG);
6003 if( pObjectInfo->NonPagedInfo == NULL)
6006 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6008 try_return( pObjectInfo = NULL);
6011 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6013 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6015 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6017 if( ParentObjectInfo != NULL)
6020 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6022 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6024 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6026 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6027 AFS_OBJECT_REFERENCE_CHILD);
6029 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6030 AFS_TRACE_LEVEL_VERBOSE,
6031 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6037 // Initialize the access time
6040 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6045 ASSERT( ParentObjectInfo);
6048 // Insert the entry into the object tree and list
6051 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6053 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6056 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6061 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6062 &pObjectInfo->TreeEntry);
6064 ASSERT( NT_SUCCESS( ntStatus));
6068 // And the object list in the volume
6071 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6074 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6079 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6081 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6084 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6087 // Indicate the object is in the hash tree and linked list in the volume
6090 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6102 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6108 if ( ObjectInfo->ObjectReferenceCount == 0)
6111 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6114 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6119 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6122 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6127 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6129 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6134 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6136 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6142 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6146 LONG lCount, lCount2;
6148 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6151 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6156 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6158 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6160 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6163 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6166 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6168 ASSERT( lCount2 >= 0);
6170 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6176 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6177 IN AFSFileID *FileId,
6178 IN BOOLEAN bUpdateLastUse)
6180 DWORD ntStatus = STATUS_SUCCESS;
6182 AFSObjectInfoCB *pObjectInfo = NULL;
6185 ullIndex = AFSCreateLowIndex( FileId);
6187 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
6190 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6193 pObjectInfo = &VolumeCB->ObjectInformation;
6198 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6200 (AFSBTreeEntry **)&pObjectInfo);
6203 if ( NT_SUCCESS( ntStatus)) {
6205 lCount = AFSObjectInfoIncrement( pObjectInfo,
6206 AFS_OBJECT_REFERENCE_FIND);
6208 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6209 AFS_TRACE_LEVEL_VERBOSE,
6210 "AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
6214 if ( bUpdateLastUse)
6217 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6221 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6227 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6231 lCount = AFSObjectInfoDecrement( *ppObjectInfo,
6232 AFS_OBJECT_REFERENCE_FIND);
6234 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6235 AFS_TRACE_LEVEL_VERBOSE,
6236 "AFSReleaseObjectInfo Decrement count on object %p Cnt %d\n",
6240 *ppObjectInfo = NULL;
6244 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6246 BOOLEAN bAcquiredTreeLock = FALSE;
6247 AFSObjectInfoCB *pObjectInfo = NULL;
6248 AFSVolumeCB * pVolume = NULL;
6249 BOOLEAN bHeldInService;
6250 AFSObjectInfoCB * pParentObjectInfo = NULL;
6256 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
6260 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6261 // embedded in the VolumeCB.
6269 pVolume = (*ppObjectInfo)->VolumeCB;
6271 if( !ExIsResourceAcquiredExclusiveLite( pVolume->ObjectInfoTree.TreeLock))
6274 ASSERT( !ExIsResourceAcquiredLite( pVolume->ObjectInfoTree.TreeLock));
6276 AFSAcquireExcl( pVolume->ObjectInfoTree.TreeLock,
6279 bAcquiredTreeLock = TRUE;
6282 for ( lCount = 0; lCount < AFS_OBJECT_REFERENCE_MAX; lCount++)
6285 ASSERT( (*ppObjectInfo)->ObjectReferences[ lCount] >= 0);
6288 ASSERT( (*ppObjectInfo)->ObjectReferenceCount == 0);
6290 pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
6294 if ( pObjectInfo == NULL)
6297 try_return( NOTHING);
6300 ASSERT( *ppObjectInfo == NULL);
6302 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6305 pParentObjectInfo = AFSFindObjectInfo( pVolume,
6306 &pObjectInfo->ParentFileId,
6309 if( pParentObjectInfo != NULL)
6312 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6314 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6315 AFS_OBJECT_REFERENCE_CHILD);
6317 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6318 AFS_TRACE_LEVEL_VERBOSE,
6319 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6323 AFSReleaseObjectInfo( &pParentObjectInfo);
6328 // Remove it from the tree and list if it was inserted
6331 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6334 AFSRemoveHashEntry( &pVolume->ObjectInfoTree.TreeHead,
6335 &pObjectInfo->TreeEntry);
6338 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6341 if( pObjectInfo->ListEntry.fLink == NULL)
6344 pVolume->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6346 if( pVolume->ObjectInfoListTail != NULL)
6349 pVolume->ObjectInfoListTail->ListEntry.fLink = NULL;
6355 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6358 if( pObjectInfo->ListEntry.bLink == NULL)
6361 pVolume->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6363 if( pVolume->ObjectInfoListHead != NULL)
6366 pVolume->ObjectInfoListHead->ListEntry.bLink = NULL;
6372 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6376 bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6381 FileId = pObjectInfo->FileId;
6384 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6386 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6388 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6390 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6392 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6396 if( bAcquiredTreeLock)
6399 AFSReleaseResource( pVolume->ObjectInfoTree.TreeLock);
6403 // Release the fid in the service
6409 AFSReleaseFid( &FileId);
6417 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6418 OUT AFSDirectoryCB **TargetDirEntry)
6421 NTSTATUS ntStatus = STATUS_SUCCESS;
6422 AFSDirEnumEntry *pDirEntry = NULL;
6423 UNICODE_STRING uniFullPathName = {0};
6424 AFSNameArrayHdr *pNameArray = NULL;
6425 AFSVolumeCB *pVolumeCB = NULL;
6426 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6427 AFSVolumeCB *pNewVolumeCB = NULL;
6428 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6429 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6430 AFSDirectoryCB *pNewParentDirEntry = NULL;
6431 WCHAR *pwchBuffer = NULL;
6432 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6433 ULONG ulNameDifference = 0;
6440 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6441 DirectoryCB->ObjectInformation,
6445 if( !NT_SUCCESS( ntStatus))
6447 try_return( ntStatus);
6451 // Retrieve a target name for the entry
6454 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6457 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6460 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6462 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6467 if( !NT_SUCCESS( ntStatus) ||
6468 pDirEntry->TargetNameLength == 0)
6471 if( pDirEntry != NULL)
6474 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6477 try_return( ntStatus);
6480 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6483 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6487 // Update the target name
6490 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6491 &DirectoryCB->Flags,
6492 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6493 (USHORT)pDirEntry->TargetNameLength);
6495 if( !NT_SUCCESS( ntStatus))
6498 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6500 try_return( ntStatus);
6504 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6508 // Need to pass the full path in for parsing.
6511 uniFullPathName.Length = 0;
6512 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6514 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6515 uniFullPathName.MaximumLength,
6516 AFS_NAME_BUFFER_EIGHT_TAG);
6518 if( uniFullPathName.Buffer == NULL)
6521 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6523 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6526 pwchBuffer = uniFullPathName.Buffer;
6528 RtlZeroMemory( uniFullPathName.Buffer,
6529 uniFullPathName.MaximumLength);
6531 RtlCopyMemory( uniFullPathName.Buffer,
6532 DirectoryCB->NameInformation.TargetName.Buffer,
6533 DirectoryCB->NameInformation.TargetName.Length);
6535 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6538 // This name should begin with the \afs server so parse it off and chech it
6541 FsRtlDissectName( uniFullPathName,
6545 if( RtlCompareUnicodeString( &uniComponentName,
6551 // Try evaluating the full path
6554 uniFullPathName.Buffer = pwchBuffer;
6556 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6558 uniFullPathName.MaximumLength = uniFullPathName.Length;
6563 uniFullPathName = uniRemainingPath;
6566 uniParsedName = uniFullPathName;
6568 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6570 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6576 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6579 if( pNameArray == NULL)
6582 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6585 pVolumeCB = AFSGlobalRoot;
6587 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6589 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
6591 lCount = AFSVolumeIncrement( pVolumeCB,
6592 VolumeReferenceReason);
6594 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6595 AFS_TRACE_LEVEL_VERBOSE,
6596 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
6598 VolumeReferenceReason,
6601 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6603 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6604 AFS_TRACE_LEVEL_VERBOSE,
6605 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6606 &pParentDirEntry->NameInformation.FileName,
6611 ntStatus = AFSLocateNameEntry( NULL,
6620 &VolumeReferenceReason,
6621 &pNewParentDirEntry,
6625 if ( pNewVolumeCB != NULL)
6628 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6629 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6630 // the reference on pVolumeCB that was held prior to the call.
6631 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6632 // will be released second.
6635 lCount = AFSVolumeDecrement( pVolumeCB,
6636 VolumeReferenceReason);
6638 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6639 AFS_TRACE_LEVEL_VERBOSE,
6640 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
6642 VolumeReferenceReason,
6645 pVolumeCB = pNewVolumeCB;
6647 pNewVolumeCB = NULL;
6649 VolumeReferenceReason = NewVolumeReferenceReason;
6651 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6655 // AFSLocateNameEntry does not alter the reference count of
6656 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6657 // a reference held.
6660 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6662 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6663 AFS_TRACE_LEVEL_VERBOSE,
6664 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
6665 &pParentDirEntry->NameInformation.FileName,
6669 pParentDirEntry = pNewParentDirEntry;
6671 pNewParentDirEntry = NULL;
6673 if( !NT_SUCCESS( ntStatus) ||
6674 ntStatus == STATUS_REPARSE)
6679 try_return( ntStatus);
6683 // Pass back the target dir entry for this request
6684 // The caller must release the DirOpenReferenceCount
6687 *TargetDirEntry = pDirectoryEntry;
6689 pDirectoryEntry = NULL;
6693 if( pDirectoryEntry != NULL)
6696 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6698 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6699 AFS_TRACE_LEVEL_VERBOSE,
6700 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6701 &pDirectoryEntry->NameInformation.FileName,
6706 ASSERT( lCount >= 0);
6709 if ( pParentDirEntry != NULL)
6712 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6714 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6715 AFS_TRACE_LEVEL_VERBOSE,
6716 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6717 &pParentDirEntry->NameInformation.FileName,
6722 ASSERT( lCount >= 0);
6725 if( pDirEntry != NULL)
6728 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6731 if( pVolumeCB != NULL)
6734 lCount = AFSVolumeDecrement( pVolumeCB,
6735 VolumeReferenceReason);
6737 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6738 AFS_TRACE_LEVEL_VERBOSE,
6739 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
6741 VolumeReferenceReason,
6745 if( pNameArray != NULL)
6748 AFSFreeNameArray( pNameArray);
6751 if( pwchBuffer != NULL)
6755 // Always free the buffer that we allocated as AFSLocateNameEntry
6756 // will not free it. If uniFullPathName.Buffer was allocated by
6757 // AFSLocateNameEntry, then we must free that as well.
6758 // Check that the uniFullPathName.Buffer in the string is not the same
6759 // offset by the length of the server name
6762 if( uniFullPathName.Length > 0 &&
6763 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6766 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6769 AFSExFreePoolWithTag( pwchBuffer, 0);
6777 AFSCleanupFcb( IN AFSFcb *Fcb,
6778 IN BOOLEAN ForceFlush)
6781 NTSTATUS ntStatus = STATUS_SUCCESS;
6782 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6783 LARGE_INTEGER liTime;
6784 IO_STATUS_BLOCK stIoStatus;
6789 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6791 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6793 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6796 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6797 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6800 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6801 AFS_TRACE_LEVEL_VERBOSE,
6802 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
6803 &Fcb->NPFcb->Resource,
6804 PsGetCurrentThread()));
6806 AFSAcquireShared( &Fcb->NPFcb->Resource,
6809 if( Fcb->OpenReferenceCount > 0)
6812 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6813 AFS_TRACE_LEVEL_VERBOSE,
6814 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
6815 &Fcb->NPFcb->SectionObjectResource,
6816 PsGetCurrentThread()));
6818 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
6824 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6829 if( !NT_SUCCESS( stIoStatus.Status))
6832 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6833 AFS_TRACE_LEVEL_ERROR,
6834 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6835 Fcb->ObjectInformation->FileId.Cell,
6836 Fcb->ObjectInformation->FileId.Volume,
6837 Fcb->ObjectInformation->FileId.Vnode,
6838 Fcb->ObjectInformation->FileId.Unique,
6840 stIoStatus.Information));
6842 ntStatus = stIoStatus.Status;
6845 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
6848 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6854 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6855 AFS_TRACE_LEVEL_WARNING,
6856 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
6857 Fcb->ObjectInformation->FileId.Cell,
6858 Fcb->ObjectInformation->FileId.Volume,
6859 Fcb->ObjectInformation->FileId.Vnode,
6860 Fcb->ObjectInformation->FileId.Unique));
6862 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6866 __except( EXCEPTION_EXECUTE_HANDLER)
6869 ntStatus = GetExceptionCode();
6873 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
6874 Fcb->ObjectInformation->FileId.Cell,
6875 Fcb->ObjectInformation->FileId.Volume,
6876 Fcb->ObjectInformation->FileId.Vnode,
6877 Fcb->ObjectInformation->FileId.Unique,
6880 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6883 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6884 AFS_TRACE_LEVEL_VERBOSE,
6885 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
6886 &Fcb->NPFcb->SectionObjectResource,
6887 PsGetCurrentThread()));
6889 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
6892 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6893 AFS_TRACE_LEVEL_VERBOSE,
6894 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
6895 &Fcb->NPFcb->Resource,
6896 PsGetCurrentThread()));
6898 AFSReleaseResource( &Fcb->NPFcb->Resource);
6901 // Wait for any currently running flush or release requests to complete
6904 AFSWaitOnQueuedFlushes( Fcb);
6907 // Now perform another flush on the file
6910 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6914 AFSReleaseExtentsWithFlush( Fcb,
6920 if( Fcb->OpenReferenceCount == 0 ||
6921 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6922 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6925 AFSTearDownFcbExtents( Fcb,
6929 try_return( ntStatus);
6932 KeQueryTickCount( &liTime);
6935 // First up are there dirty extents in the cache to flush?
6938 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6939 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6943 // The file has been marked as invalid. Dump it
6946 AFSTearDownFcbExtents( Fcb,
6949 else if( ForceFlush ||
6950 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
6951 Fcb->Specific.File.ExtentCount) &&
6952 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6953 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6955 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6957 Fcb->OpenReferenceCount == 0)
6960 AFSReleaseExtentsWithFlush( Fcb,
6967 // If there are extents and they haven't been used recently *and*
6968 // are not being used
6972 ( 0 != Fcb->Specific.File.ExtentCount &&
6973 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6974 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6975 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
6978 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6979 AFS_TRACE_LEVEL_VERBOSE,
6980 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
6981 &Fcb->NPFcb->SectionObjectResource,
6982 PsGetCurrentThread()));
6984 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
6990 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6995 if( !NT_SUCCESS( stIoStatus.Status))
6998 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6999 AFS_TRACE_LEVEL_ERROR,
7000 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7001 Fcb->ObjectInformation->FileId.Cell,
7002 Fcb->ObjectInformation->FileId.Volume,
7003 Fcb->ObjectInformation->FileId.Vnode,
7004 Fcb->ObjectInformation->FileId.Unique,
7006 stIoStatus.Information));
7008 ntStatus = stIoStatus.Status;
7012 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7015 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7021 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7022 AFS_TRACE_LEVEL_WARNING,
7023 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7024 Fcb->ObjectInformation->FileId.Cell,
7025 Fcb->ObjectInformation->FileId.Volume,
7026 Fcb->ObjectInformation->FileId.Vnode,
7027 Fcb->ObjectInformation->FileId.Unique));
7029 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7033 __except( EXCEPTION_EXECUTE_HANDLER)
7036 ntStatus = GetExceptionCode();
7040 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7041 Fcb->ObjectInformation->FileId.Cell,
7042 Fcb->ObjectInformation->FileId.Volume,
7043 Fcb->ObjectInformation->FileId.Vnode,
7044 Fcb->ObjectInformation->FileId.Unique,
7048 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7049 AFS_TRACE_LEVEL_VERBOSE,
7050 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7051 &Fcb->NPFcb->SectionObjectResource,
7052 PsGetCurrentThread()));
7054 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7056 if( Fcb->OpenReferenceCount <= 0)
7060 // Tear em down we'll not be needing them again
7063 AFSTearDownFcbExtents( Fcb,
7070 ntStatus = STATUS_RETRY;
7083 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7084 IN UNICODE_STRING *NewFileName)
7087 NTSTATUS ntStatus = STATUS_SUCCESS;
7088 WCHAR *pTmpBuffer = NULL;
7093 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7096 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7099 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7101 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7103 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7107 // OK, we need to allocate a new name buffer
7110 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7111 NewFileName->Length,
7112 AFS_NAME_BUFFER_NINE_TAG);
7114 if( pTmpBuffer == NULL)
7117 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7120 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7122 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7124 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7127 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7129 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7130 NewFileName->Buffer,
7131 NewFileName->Length);
7142 AFSReadCacheFile( IN void *ReadBuffer,
7143 IN LARGE_INTEGER *ReadOffset,
7144 IN ULONG RequestedDataLength,
7145 IN OUT PULONG BytesRead)
7148 NTSTATUS ntStatus = STATUS_SUCCESS;
7151 PIO_STACK_LOCATION pIoStackLocation = NULL;
7152 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7153 FILE_OBJECT *pCacheFileObject = NULL;
7158 pCacheFileObject = AFSReferenceCacheFileObject();
7160 if( pCacheFileObject == NULL)
7162 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7165 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7168 // Initialize the event
7171 KeInitializeEvent( &kEvent,
7172 SynchronizationEvent,
7176 // Allocate an irp for this request. This could also come from a
7177 // private pool, for instance.
7180 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7186 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7190 // Build the IRP's main body
7193 pIrp->UserBuffer = ReadBuffer;
7195 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7196 pIrp->RequestorMode = KernelMode;
7197 pIrp->Flags |= IRP_READ_OPERATION;
7200 // Set up the I/O stack location.
7203 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7204 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7205 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7206 pIoStackLocation->FileObject = pCacheFileObject;
7207 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7209 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7212 // Set the completion routine.
7215 IoSetCompletionRoutine( pIrp,
7223 // Send it to the FSD
7226 ntStatus = IoCallDriver( pTargetDeviceObject,
7229 if( NT_SUCCESS( ntStatus))
7236 ntStatus = KeWaitForSingleObject( &kEvent,
7242 if( NT_SUCCESS( ntStatus))
7245 ntStatus = pIrp->IoStatus.Status;
7247 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7253 if( pCacheFileObject != NULL)
7255 AFSReleaseCacheFileObject( pCacheFileObject);
7261 if( pIrp->MdlAddress != NULL)
7264 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7267 MmUnlockPages( pIrp->MdlAddress);
7270 IoFreeMdl( pIrp->MdlAddress);
7273 pIrp->MdlAddress = NULL;
7287 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7292 UNREFERENCED_PARAMETER(Irp);
7293 UNREFERENCED_PARAMETER(DeviceObject);
7294 KEVENT *pEvent = (KEVENT *)Context;
7300 return STATUS_MORE_PROCESSING_REQUIRED;
7304 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7307 BOOLEAN bIsEmpty = FALSE;
7308 AFSDirectoryCB *pDirEntry = NULL;
7313 ASSERT( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY);
7315 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7320 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7323 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7325 while( pDirEntry != NULL)
7328 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7329 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7337 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7342 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7349 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7350 IN AFSDirectoryCB *DirEntry)
7353 NTSTATUS ntStatus = STATUS_SUCCESS;
7358 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7361 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7362 AFS_TRACE_LEVEL_VERBOSE,
7363 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7365 &DirEntry->NameInformation.FileName));
7367 try_return( ntStatus);
7370 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7373 // Remove the entry from the parent tree
7376 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7377 AFS_TRACE_LEVEL_VERBOSE,
7378 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7380 &DirEntry->NameInformation.FileName));
7382 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7385 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7386 AFS_TRACE_LEVEL_VERBOSE,
7387 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7389 &DirEntry->NameInformation.FileName));
7391 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7394 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7398 // From the short name tree
7401 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7402 AFS_TRACE_LEVEL_VERBOSE,
7403 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7405 &DirEntry->NameInformation.FileName));
7407 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7410 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7413 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7414 AFS_TRACE_LEVEL_VERBOSE,
7415 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7417 &DirEntry->NameInformation.FileName));
7419 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7421 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7432 AFSGetAuthenticationId()
7435 LARGE_INTEGER liAuthId = {0,0};
7436 NTSTATUS ntStatus = STATUS_SUCCESS;
7437 PACCESS_TOKEN hToken = NULL;
7438 PTOKEN_STATISTICS pTokenInfo = NULL;
7439 BOOLEAN bCopyOnOpen = FALSE;
7440 BOOLEAN bEffectiveOnly = FALSE;
7441 BOOLEAN bPrimaryToken = FALSE;
7442 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7447 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7450 &stImpersonationLevel);
7455 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7460 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7461 AFS_TRACE_LEVEL_ERROR,
7462 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
7464 try_return( ntStatus);
7467 bPrimaryToken = TRUE;
7470 ntStatus = SeQueryInformationToken( hToken,
7472 (PVOID *)&pTokenInfo);
7474 if( !NT_SUCCESS( ntStatus))
7477 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7478 AFS_TRACE_LEVEL_ERROR,
7479 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
7482 try_return( ntStatus);
7485 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7486 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7488 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7489 AFS_TRACE_LEVEL_VERBOSE,
7490 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7491 liAuthId.QuadPart));
7501 PsDereferenceImpersonationToken( hToken);
7506 PsDereferencePrimaryToken( hToken);
7510 if( pTokenInfo != NULL)
7513 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7521 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7525 UNREFERENCED_PARAMETER(Fcb);
7526 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7528 Fcb->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7531 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7533 Fcb->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7536 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7538 Fcb->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7541 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7543 Fcb->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7546 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7548 Fcb->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7555 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7558 BOOLEAN bIsValid = TRUE;
7560 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7562 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7564 while( pCurrentDirEntry != NULL)
7567 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7571 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7576 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7577 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7580 if( pDirEntry == NULL)
7587 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7590 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
7593 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7595 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7597 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7606 AFSReferenceCacheFileObject()
7609 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7610 FILE_OBJECT *pCacheFileObject = NULL;
7612 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7615 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7617 if( pCacheFileObject != NULL)
7619 ObReferenceObject( pCacheFileObject);
7622 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7624 return pCacheFileObject;
7628 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7631 ASSERT( CacheFileObject != NULL);
7633 ObDereferenceObject( CacheFileObject);
7639 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7642 NTSTATUS ntStatus = STATUS_SUCCESS;
7643 AFSDeviceExt *pControlDevExt = NULL;
7644 ULONG ulTimeIncrement = 0;
7650 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7652 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7654 AFSServerName = LibraryInit->AFSServerName;
7656 AFSMountRootName = LibraryInit->AFSMountRootName;
7658 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7661 // Callbacks in the framework
7664 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7666 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7668 AFSDebugTraceFnc = AFSDbgLogMsg;
7670 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7672 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7674 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
7676 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7678 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7680 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7682 if( LibraryInit->AFSCacheBaseAddress != NULL)
7685 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7687 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7689 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7693 // Initialize some flush parameters
7696 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7698 ulTimeIncrement = KeQueryTimeIncrement();
7700 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7701 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7702 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7703 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7704 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7707 // Initialize the global root entry
7710 ntStatus = AFSInitVolume( NULL,
7711 &LibraryInit->GlobalRootFid,
7712 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
7715 if( !NT_SUCCESS( ntStatus))
7718 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7719 AFS_TRACE_LEVEL_ERROR,
7720 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7723 try_return( ntStatus);
7726 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7729 if( !NT_SUCCESS( ntStatus))
7732 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7733 AFS_TRACE_LEVEL_ERROR,
7734 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7737 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7738 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7740 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7741 AFS_TRACE_LEVEL_VERBOSE,
7742 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7746 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7748 try_return( ntStatus);
7752 // Update the node type code to AFS_ROOT_ALL
7755 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7757 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7760 // Invalidate all known volumes since contact with the service and therefore
7761 // the file server was lost.
7764 AFSInvalidateAllVolumes();
7767 // Drop the locks acquired above
7770 AFSInitVolumeWorker( AFSGlobalRoot);
7772 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7773 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7775 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7776 AFS_TRACE_LEVEL_VERBOSE,
7777 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7781 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7783 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7797 NTSTATUS ntStatus = STATUS_SUCCESS;
7798 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7804 if( AFSGlobalDotDirEntry != NULL)
7807 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
7808 AFS_OBJECT_REFERENCE_GLOBAL);
7810 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7811 AFS_TRACE_LEVEL_VERBOSE,
7812 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7813 AFSGlobalDotDirEntry->ObjectInformation,
7819 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
7822 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7824 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7826 ExFreePool( AFSGlobalDotDirEntry);
7828 AFSGlobalDotDirEntry = NULL;
7831 if( AFSGlobalDotDotDirEntry != NULL)
7834 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
7835 AFS_OBJECT_REFERENCE_GLOBAL);
7837 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7838 AFS_TRACE_LEVEL_VERBOSE,
7839 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7840 AFSGlobalDotDotDirEntry->ObjectInformation,
7846 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
7849 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7851 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7853 ExFreePool( AFSGlobalDotDotDirEntry);
7855 AFSGlobalDotDotDirEntry = NULL;
7858 if( AFSSpecialShareNames != NULL)
7861 pDirNode = AFSSpecialShareNames;
7863 while( pDirNode != NULL)
7866 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7868 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
7869 AFS_OBJECT_REFERENCE_GLOBAL);
7871 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7872 AFS_TRACE_LEVEL_VERBOSE,
7873 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7874 pDirNode->ObjectInformation,
7880 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
7883 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7885 ExFreePool( pDirNode->NonPaged);
7887 ExFreePool( pDirNode);
7889 pDirNode = pLastDirNode;
7892 AFSSpecialShareNames = NULL;
7900 AFSDefaultLogMsg( IN ULONG Subsystem,
7906 UNREFERENCED_PARAMETER(Subsystem);
7907 UNREFERENCED_PARAMETER(Level);
7908 NTSTATUS ntStatus = STATUS_SUCCESS;
7910 char chDebugBuffer[ 256];
7915 va_start( va_args, Format);
7917 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7922 if( NT_SUCCESS( ntStatus))
7924 DbgPrint( chDebugBuffer);
7934 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7935 IN ULONG InputBufferLength,
7936 IN AFSStatusInfoCB *StatusInfo,
7937 OUT ULONG *ReturnLength)
7940 NTSTATUS ntStatus = STATUS_SUCCESS;
7941 AFSVolumeCB *pVolumeCB = NULL;
7942 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7943 AFSVolumeCB *pNewVolumeCB = NULL;
7944 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7945 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7946 AFSObjectInfoCB *pObjectInfo = NULL;
7947 ULONGLONG ullIndex = 0;
7948 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7949 AFSNameArrayHdr *pNameArray = NULL;
7950 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7951 AFSDirectoryCB *pNewParentDirEntry = NULL;
7958 // If we are given a FID then look up the entry by that, otherwise
7962 if( GetStatusInfo->FileID.Cell != 0 &&
7963 GetStatusInfo->FileID.Volume != 0 &&
7964 GetStatusInfo->FileID.Vnode != 0 &&
7965 GetStatusInfo->FileID.Unique != 0)
7968 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7971 // Locate the volume node
7974 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7976 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7978 (AFSBTreeEntry **)&pVolumeCB);
7980 if( pVolumeCB != NULL)
7983 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
7985 lCount = AFSVolumeIncrement( pVolumeCB,
7986 VolumeReferenceReason);
7988 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7989 AFS_TRACE_LEVEL_VERBOSE,
7990 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
7992 VolumeReferenceReason,
7996 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7998 if( !NT_SUCCESS( ntStatus) ||
8001 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8004 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8007 pObjectInfo = &pVolumeCB->ObjectInformation;
8009 lCount = AFSObjectInfoIncrement( pObjectInfo,
8010 AFS_OBJECT_REFERENCE_STATUS);
8012 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8013 AFS_TRACE_LEVEL_VERBOSE,
8014 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8021 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8024 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8026 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8028 (AFSBTreeEntry **)&pObjectInfo);
8030 if( pObjectInfo != NULL)
8034 // Reference the node so it won't be torn down
8037 lCount = AFSObjectInfoIncrement( pObjectInfo,
8038 AFS_OBJECT_REFERENCE_STATUS);
8040 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8041 AFS_TRACE_LEVEL_VERBOSE,
8042 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8046 KeQueryTickCount( &pObjectInfo->LastAccessCount);
8049 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8051 if( !NT_SUCCESS( ntStatus) ||
8052 pObjectInfo == NULL)
8054 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8061 if( GetStatusInfo->FileNameLength == 0 ||
8062 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8064 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8067 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8068 uniFullPathName.MaximumLength = uniFullPathName.Length;
8070 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8073 // This name should begin with the \afs server so parse it off and check it
8076 FsRtlDissectName( uniFullPathName,
8080 if( RtlCompareUnicodeString( &uniComponentName,
8084 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8085 AFS_TRACE_LEVEL_ERROR,
8086 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8089 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8092 uniFullPathName = uniRemainingPath;
8094 uniParsedName = uniFullPathName;
8100 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8103 if( pNameArray == NULL)
8105 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8108 pVolumeCB = AFSGlobalRoot;
8110 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8113 // Increment the ref count on the volume and dir entry for correct processing below
8116 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8118 lCount = AFSVolumeIncrement( pVolumeCB,
8119 VolumeReferenceReason);
8121 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8122 AFS_TRACE_LEVEL_VERBOSE,
8123 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8125 VolumeReferenceReason,
8128 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8130 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8131 AFS_TRACE_LEVEL_VERBOSE,
8132 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8133 &pParentDirEntry->NameInformation.FileName,
8138 ntStatus = AFSLocateNameEntry( NULL,
8143 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8144 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8148 &NewVolumeReferenceReason,
8149 &pNewParentDirEntry,
8153 if ( pNewVolumeCB != NULL)
8157 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8158 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8159 // the reference on pVolumeCB that was held prior to the call.
8160 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8161 // will be released second.
8164 lCount = AFSVolumeDecrement( pVolumeCB,
8165 VolumeReferenceReason);
8167 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8168 AFS_TRACE_LEVEL_VERBOSE,
8169 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8171 VolumeReferenceReason,
8174 pVolumeCB = pNewVolumeCB;
8176 pNewVolumeCB = NULL;
8178 VolumeReferenceReason = NewVolumeReferenceReason;
8180 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8184 // AFSLocateNameEntry does not alter the reference count of
8185 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8186 // a reference held.
8189 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8191 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8192 AFS_TRACE_LEVEL_VERBOSE,
8193 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8194 &pParentDirEntry->NameInformation.FileName,
8198 pParentDirEntry = pNewParentDirEntry;
8200 pNewParentDirEntry = NULL;
8202 if( !NT_SUCCESS( ntStatus) ||
8203 ntStatus == STATUS_REPARSE)
8208 try_return( ntStatus);
8211 pObjectInfo = pDirectoryEntry->ObjectInformation;
8213 lCount = AFSObjectInfoIncrement( pObjectInfo,
8214 AFS_OBJECT_REFERENCE_STATUS);
8216 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8217 AFS_TRACE_LEVEL_VERBOSE,
8218 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8224 // At this point we have an object info block, return the information
8227 StatusInfo->FileId = pObjectInfo->FileId;
8229 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8231 StatusInfo->Expiration = pObjectInfo->Expiration;
8233 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8235 StatusInfo->FileType = pObjectInfo->FileType;
8237 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8239 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8241 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8243 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8245 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8247 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8249 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8251 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8253 StatusInfo->EaSize = pObjectInfo->EaSize;
8255 StatusInfo->Links = pObjectInfo->Links;
8258 // Return the information length
8261 *ReturnLength = sizeof( AFSStatusInfoCB);
8265 if( pDirectoryEntry != NULL)
8268 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8270 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8271 AFS_TRACE_LEVEL_VERBOSE,
8272 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8273 &pDirectoryEntry->NameInformation.FileName,
8278 ASSERT( lCount >= 0);
8281 if ( pParentDirEntry != NULL)
8284 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8286 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8287 AFS_TRACE_LEVEL_VERBOSE,
8288 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8289 &pParentDirEntry->NameInformation.FileName,
8294 ASSERT( lCount >= 0);
8297 if( pObjectInfo != NULL)
8300 lCount = AFSObjectInfoDecrement( pObjectInfo,
8301 AFS_OBJECT_REFERENCE_STATUS);
8303 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8304 AFS_TRACE_LEVEL_VERBOSE,
8305 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8310 if( pVolumeCB != NULL)
8313 lCount = AFSVolumeDecrement( pVolumeCB,
8314 VolumeReferenceReason);
8316 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8317 AFS_TRACE_LEVEL_VERBOSE,
8318 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8320 VolumeReferenceReason,
8324 if( pNameArray != NULL)
8327 AFSFreeNameArray( pNameArray);
8335 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8336 IN UNICODE_STRING *ComponentName)
8339 NTSTATUS ntStatus = STATUS_SUCCESS;
8340 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8341 AFSDirectoryCB *pDirEntry = NULL;
8349 // Search for the entry in the parent
8352 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8353 AFS_TRACE_LEVEL_VERBOSE_2,
8354 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8357 ulCRC = AFSGenerateCRC( ComponentName,
8360 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8363 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8367 if( pDirEntry == NULL)
8371 // Missed so perform a case insensitive lookup
8374 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8375 AFS_TRACE_LEVEL_VERBOSE_2,
8376 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8379 ulCRC = AFSGenerateCRC( ComponentName,
8382 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8386 if( pDirEntry == NULL)
8390 // OK, if this component is a valid short name then try
8391 // a lookup in the short name tree
8394 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8395 RtlIsNameLegalDOS8Dot3( ComponentName,
8400 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8401 AFS_TRACE_LEVEL_VERBOSE_2,
8402 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8405 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8412 if( pDirEntry != NULL)
8414 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8416 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8417 AFS_TRACE_LEVEL_VERBOSE,
8418 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8419 &pDirEntry->NameInformation.FileName,
8424 ASSERT( lCount >= 0);
8427 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8429 if( pDirEntry == NULL)
8432 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8433 AFS_TRACE_LEVEL_VERBOSE_2,
8434 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8436 STATUS_OBJECT_NAME_NOT_FOUND));
8438 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8442 // We have the symlink object but previously failed to process it so return access
8446 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8447 AFS_TRACE_LEVEL_VERBOSE_2,
8448 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8451 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8453 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8455 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8456 AFS_TRACE_LEVEL_VERBOSE,
8457 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8458 &pDirEntry->NameInformation.FileName,
8463 ASSERT( lCount >= 0);
8474 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8475 OUT UNICODE_STRING *ComponentName)
8478 NTSTATUS ntStatus = STATUS_SUCCESS;
8479 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8481 uniFullPathName = *FullPathName;
8486 FsRtlDissectName( uniFullPathName,
8490 if( uniRemainingPath.Length == 0)
8495 uniFullPathName = uniRemainingPath;
8498 if( uniComponentName.Length > 0)
8500 *ComponentName = uniComponentName;
8507 AFSDumpTraceFiles_Default()
8513 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8516 BOOLEAN bIsValidName = TRUE;
8522 while( usIndex < FileName->Length/sizeof( WCHAR))
8525 if( FileName->Buffer[ usIndex] == L':' ||
8526 FileName->Buffer[ usIndex] == L'*' ||
8527 FileName->Buffer[ usIndex] == L'?' ||
8528 FileName->Buffer[ usIndex] == L'"' ||
8529 FileName->Buffer[ usIndex] == L'<' ||
8530 FileName->Buffer[ usIndex] == L'>')
8532 bIsValidName = FALSE;
8540 return bIsValidName;
8544 AFSCreateDefaultSecurityDescriptor()
8547 NTSTATUS ntStatus = STATUS_SUCCESS;
8549 ULONG ulSACLSize = 0;
8550 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8551 ULONG ulACESize = 0;
8552 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8553 ULONG ulSDLength = 0;
8554 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8555 PSID pWorldSID = NULL;
8556 ULONG *pulSubAuthority = NULL;
8557 ULONG ulWorldSIDLEngth = 0;
8562 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8564 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8566 AFS_GENERIC_MEMORY_29_TAG);
8568 if( pWorldSID == NULL)
8570 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8572 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8575 RtlZeroMemory( pWorldSID,
8578 RtlInitializeSid( pWorldSID,
8579 &SeWorldSidAuthority,
8582 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8583 *pulSubAuthority = SECURITY_WORLD_RID;
8585 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8588 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8593 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8595 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8597 AFS_GENERIC_MEMORY_29_TAG);
8602 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8604 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8607 RtlZeroMemory( pACE,
8610 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8611 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8612 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8613 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8615 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8617 SeExports->SeLowMandatorySid);
8619 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8620 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8622 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8624 AFS_GENERIC_MEMORY_29_TAG);
8629 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8631 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8634 ntStatus = RtlCreateAcl( pSACL,
8638 if( !NT_SUCCESS( ntStatus))
8641 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8644 try_return( ntStatus);
8647 ntStatus = RtlAddAce( pSACL,
8651 pACE->Header.AceSize);
8653 if( !NT_SUCCESS( ntStatus))
8656 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8659 try_return( ntStatus);
8663 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8664 sizeof( SECURITY_DESCRIPTOR),
8665 AFS_GENERIC_MEMORY_27_TAG);
8667 if( pSecurityDescr == NULL)
8670 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8672 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8675 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8676 SECURITY_DESCRIPTOR_REVISION);
8678 if( !NT_SUCCESS( ntStatus))
8681 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8684 try_return( ntStatus);
8687 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8689 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8694 if( !NT_SUCCESS( ntStatus))
8697 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8700 try_return( ntStatus);
8705 // Add in the group and owner to the SD
8708 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8710 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8714 if( !NT_SUCCESS( ntStatus))
8717 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8720 try_return( ntStatus);
8724 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8728 if( !NT_SUCCESS( ntStatus))
8731 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8734 try_return( ntStatus);
8737 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8740 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8742 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8745 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8747 AFS_GENERIC_MEMORY_27_TAG);
8749 if( pRelativeSecurityDescr == NULL)
8752 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8754 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8757 ulSDLength = PAGE_SIZE;
8759 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8760 pRelativeSecurityDescr,
8763 if( !NT_SUCCESS( ntStatus))
8766 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8769 try_return( ntStatus);
8772 AFSDefaultSD = pRelativeSecurityDescr;
8776 if( !NT_SUCCESS( ntStatus))
8779 if( pRelativeSecurityDescr != NULL)
8781 ExFreePool( pRelativeSecurityDescr);
8785 if( pSecurityDescr != NULL)
8787 ExFreePool( pSecurityDescr);
8800 if( pWorldSID != NULL)
8802 ExFreePool( pWorldSID);
8810 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8811 OUT UNICODE_STRING *ParentPath)
8814 *ParentPath = *FullFileName;
8817 // If the final character is a \, jump over it
8820 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8822 ParentPath->Length -= sizeof( WCHAR);
8825 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8827 ParentPath->Length -= sizeof( WCHAR);
8831 // And the separator
8834 ParentPath->Length -= sizeof( WCHAR);
8840 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8841 IN AFSObjectInfoCB *ObjectInfo,
8842 IN BOOLEAN WriteAccess,
8843 OUT GUID *AuthGroup)
8846 NTSTATUS ntStatus = STATUS_SUCCESS;
8847 GUID stAuthGroup, stZeroAuthGroup;
8848 BOOLEAN bFoundAuthGroup = FALSE;
8849 AFSCcb *pCcb = NULL;
8855 RtlZeroMemory( &stAuthGroup,
8858 RtlZeroMemory( &stZeroAuthGroup,
8864 if( ObjectInfo != NULL &&
8865 ObjectInfo->Fcb != NULL)
8867 pFcb = ObjectInfo->Fcb;
8874 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8877 pCcb = Fcb->CcbListHead;
8879 while( pCcb != NULL)
8883 pCcb->GrantedAccess & FILE_WRITE_DATA)
8885 RtlCopyMemory( &stAuthGroup,
8889 bFoundAuthGroup = TRUE;
8893 else if( pCcb->GrantedAccess & FILE_READ_DATA)
8896 // At least get the read-only access
8899 RtlCopyMemory( &stAuthGroup,
8903 bFoundAuthGroup = TRUE;
8906 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
8909 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
8912 if( !bFoundAuthGroup)
8915 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
8916 (ULONGLONG)PsGetCurrentThreadId(),
8919 if( RtlCompareMemory( &stZeroAuthGroup,
8921 sizeof( GUID)) == sizeof( GUID))
8924 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
8926 try_return( ntStatus = STATUS_ACCESS_DENIED);
8930 RtlCopyMemory( AuthGroup,
8943 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
8944 IN ULONG InvalidateReason)
8947 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8948 NTSTATUS ntStatus = STATUS_SUCCESS;
8951 ULONG ulProcessCount = 0;
8958 switch( InvalidateReason)
8961 case AFS_INVALIDATE_DELETED:
8964 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8965 ObjectInfo->Fcb != NULL)
8968 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
8971 ObjectInfo->Links = 0;
8973 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
8975 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
8980 // Clear out the extents
8981 // And get rid of them (note this involves waiting
8982 // for any writes or reads to the cache to complete)
8985 AFSTearDownFcbExtents( ObjectInfo->Fcb,
8988 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
8994 case AFS_INVALIDATE_DATA_VERSION:
8997 LARGE_INTEGER liCurrentOffset = {0,0};
8998 LARGE_INTEGER liFlushLength = {0,0};
8999 ULONG ulFlushLength = 0;
9000 BOOLEAN bLocked = FALSE;
9001 BOOLEAN bExtentsLocked = FALSE;
9002 BOOLEAN bCleanExtents = FALSE;
9004 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9005 ObjectInfo->Fcb != NULL)
9008 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9013 if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
9016 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9017 AFS_TRACE_LEVEL_VERBOSE,
9018 "AFSPerformObjectInvalidation DirectIO Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9019 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9020 PsGetCurrentThread()));
9022 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9025 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9032 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9033 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9039 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9040 AFS_TRACE_LEVEL_WARNING,
9041 "AFSPerformObjectInvalidation DirectIO CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9042 ObjectInfo->FileId.Cell,
9043 ObjectInfo->FileId.Volume,
9044 ObjectInfo->FileId.Vnode,
9045 ObjectInfo->FileId.Unique));
9047 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9052 bCleanExtents = TRUE;
9055 __except( EXCEPTION_EXECUTE_HANDLER)
9058 ntStatus = GetExceptionCode();
9062 "EXCEPTION - AFSPerformObjectInvalidation DirectIO FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9063 ObjectInfo->FileId.Cell,
9064 ObjectInfo->FileId.Volume,
9065 ObjectInfo->FileId.Vnode,
9066 ObjectInfo->FileId.Unique,
9069 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9072 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9073 AFS_TRACE_LEVEL_VERBOSE,
9074 "AFSPerformObjectInvalidation DirectIO Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9075 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9076 PsGetCurrentThread()));
9078 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9083 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9084 AFS_TRACE_LEVEL_VERBOSE,
9085 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9086 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9087 PsGetCurrentThread()));
9089 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9092 bExtentsLocked = TRUE;
9095 // There are several possibilities here:
9097 // 0. If there are no extents or all of the extents are dirty, do nothing.
9099 // 1. There could be nothing dirty and an open reference count of zero
9100 // in which case we can just tear down all of the extents without
9101 // holding any resources.
9103 // 2. There could be nothing dirty and a non-zero open reference count
9104 // in which case we can issue a CcPurge against the entire file
9105 // while holding just the Fcb Resource.
9107 // 3. There can be dirty extents in which case we need to identify
9108 // the non-dirty ranges and then perform a CcPurge on just the
9109 // non-dirty ranges while holding just the Fcb Resource.
9112 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9115 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9118 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9120 bExtentsLocked = FALSE;
9122 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9125 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9129 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9135 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9136 AFS_TRACE_LEVEL_VERBOSE,
9137 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9138 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9139 PsGetCurrentThread()));
9141 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9144 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9151 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9152 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9158 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9159 AFS_TRACE_LEVEL_WARNING,
9160 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9161 ObjectInfo->FileId.Cell,
9162 ObjectInfo->FileId.Volume,
9163 ObjectInfo->FileId.Vnode,
9164 ObjectInfo->FileId.Unique));
9166 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9171 bCleanExtents = TRUE;
9174 __except( EXCEPTION_EXECUTE_HANDLER)
9177 ntStatus = GetExceptionCode();
9181 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9182 ObjectInfo->FileId.Cell,
9183 ObjectInfo->FileId.Volume,
9184 ObjectInfo->FileId.Vnode,
9185 ObjectInfo->FileId.Unique,
9188 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9191 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9192 AFS_TRACE_LEVEL_VERBOSE,
9193 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9194 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9195 PsGetCurrentThread()));
9197 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9203 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9205 bExtentsLocked = FALSE;
9207 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9208 AFS_TRACE_LEVEL_VERBOSE,
9209 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9210 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9211 PsGetCurrentThread()));
9213 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9216 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9221 // Must build a list of non-dirty ranges from the beginning of the file
9222 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9223 // ranges. In all but the most extreme random data write scenario there will
9224 // be significantly fewer.
9226 // For each range we need offset and size.
9229 AFSByteRange * ByteRangeList = NULL;
9230 ULONG ulByteRangeCount = 0;
9232 BOOLEAN bPurgeOnClose = FALSE;
9237 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9240 if ( ByteRangeList != NULL ||
9241 ulByteRangeCount == 0)
9244 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9251 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9253 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9254 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9255 &ByteRangeList[ulIndex].FileOffset,
9260 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9261 AFS_TRACE_LEVEL_WARNING,
9262 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9263 ObjectInfo->FileId.Cell,
9264 ObjectInfo->FileId.Volume,
9265 ObjectInfo->FileId.Vnode,
9266 ObjectInfo->FileId.Unique));
9268 bPurgeOnClose = TRUE;
9273 bCleanExtents = TRUE;
9276 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9278 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9280 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9287 // We couldn't allocate the memory to build the purge list
9288 // so just walk the extent list while holding the ExtentsList Resource.
9289 // This could deadlock but we do not have much choice.
9292 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9294 bExtentsLocked = TRUE;
9296 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9300 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9304 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9306 while( ulProcessCount < ulCount)
9308 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9310 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9312 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9313 &pEntry->FileOffset,
9318 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9319 AFS_TRACE_LEVEL_WARNING,
9320 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9321 ObjectInfo->FileId.Cell,
9322 ObjectInfo->FileId.Volume,
9323 ObjectInfo->FileId.Vnode,
9324 ObjectInfo->FileId.Unique));
9326 bPurgeOnClose = TRUE;
9331 bCleanExtents = TRUE;
9335 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9338 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9340 while( liFlushLength.QuadPart > 0)
9343 if( liFlushLength.QuadPart > 512 * 1024000)
9345 ulFlushLength = 512 * 1024000;
9349 ulFlushLength = liFlushLength.LowPart;
9352 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9358 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9359 AFS_TRACE_LEVEL_WARNING,
9360 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9361 ObjectInfo->FileId.Cell,
9362 ObjectInfo->FileId.Volume,
9363 ObjectInfo->FileId.Vnode,
9364 ObjectInfo->FileId.Unique));
9366 bPurgeOnClose = TRUE;
9371 bCleanExtents = TRUE;
9374 liFlushLength.QuadPart -= ulFlushLength;
9378 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9386 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9392 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9393 AFS_TRACE_LEVEL_WARNING,
9394 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9395 ObjectInfo->FileId.Cell,
9396 ObjectInfo->FileId.Volume,
9397 ObjectInfo->FileId.Vnode,
9398 ObjectInfo->FileId.Unique));
9400 bPurgeOnClose = TRUE;
9405 bCleanExtents = TRUE;
9412 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9416 __except( EXCEPTION_EXECUTE_HANDLER)
9419 ntStatus = GetExceptionCode();
9423 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9424 ObjectInfo->FileId.Cell,
9425 ObjectInfo->FileId.Volume,
9426 ObjectInfo->FileId.Vnode,
9427 ObjectInfo->FileId.Unique,
9431 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9432 AFS_TRACE_LEVEL_VERBOSE,
9433 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9434 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9435 PsGetCurrentThread()));
9437 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9441 if ( bExtentsLocked)
9444 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9451 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9457 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9467 // Destroy the reference passed in by the caller to AFSInvalidateObject
9468 // or AFSQueueInvalidateObject
9471 AFSAcquireShared( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
9474 lCount = AFSObjectInfoDecrement( ObjectInfo,
9475 AFS_OBJECT_REFERENCE_INVALIDATION);
9477 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9478 AFS_TRACE_LEVEL_VERBOSE,
9479 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",
9483 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);