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 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1164 ntStatus = STATUS_SUCCESS;
1166 ulEntryLength = sizeof( AFSDirectoryCB) +
1169 if( TargetName != NULL)
1172 ulEntryLength += TargetName->Length;
1175 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1179 if( pDirNode == NULL)
1182 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1185 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1186 AFS_TRACE_LEVEL_VERBOSE,
1187 "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
1190 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1191 sizeof( AFSNonPagedDirectoryCB),
1192 AFS_DIR_ENTRY_NP_TAG);
1194 if( pNonPagedDirEntry == NULL)
1197 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1200 RtlZeroMemory( pDirNode,
1203 RtlZeroMemory( pNonPagedDirEntry,
1204 sizeof( AFSNonPagedDirectoryCB));
1206 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1208 pDirNode->NonPaged = pNonPagedDirEntry;
1210 pDirNode->ObjectInformation = pObjectInfoCB;
1213 // Set valid entry and NOT_IN_PARENT flag
1216 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1218 pDirNode->FileIndex = FileIndex;
1221 // Setup the names in the entry
1224 if( FileName->Length > 0)
1227 pDirNode->NameInformation.FileName.Length = FileName->Length;
1229 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1231 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1233 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1235 pDirNode->NameInformation.FileName.Length);
1238 // Create a CRC for the file
1241 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1244 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1248 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1249 AFS_TRACE_LEVEL_VERBOSE,
1250 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1253 ParentObjectInfo->FileId.Cell,
1254 ParentObjectInfo->FileId.Volume,
1255 ParentObjectInfo->FileId.Vnode,
1256 ParentObjectInfo->FileId.Unique));
1258 if( TargetName != NULL &&
1259 TargetName->Length > 0)
1262 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1264 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1266 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1267 sizeof( AFSDirectoryCB) +
1268 pDirNode->NameInformation.FileName.Length);
1270 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1272 pDirNode->NameInformation.TargetName.Length);
1278 if( !NT_SUCCESS( ntStatus))
1281 if( pNonPagedDirEntry != NULL)
1284 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1286 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1289 if( pDirNode != NULL)
1292 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1293 AFS_TRACE_LEVEL_VERBOSE,
1294 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1297 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1303 // Dereference our object info block if we have one
1306 if( pObjectInfoCB != NULL)
1309 AFSAcquireShared( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
1312 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1313 AFS_OBJECT_REFERENCE_DIRENTRY);
1315 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1316 AFS_TRACE_LEVEL_VERBOSE,
1317 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1321 AFSReleaseResource( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
1330 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1331 IN BOOLEAN DirectoryEntry)
1334 BOOLEAN bReturn = TRUE;
1335 ACCESS_MASK stAccessMask = 0;
1338 // Get rid of anything we don't know about
1341 DesiredAccess = (DesiredAccess &
1347 ACCESS_SYSTEM_SECURITY |
1351 FILE_READ_ATTRIBUTES |
1352 FILE_WRITE_ATTRIBUTES |
1353 FILE_LIST_DIRECTORY |
1359 // Our 'read only' access mask. These are the accesses we will
1360 // allow for a read only file
1363 stAccessMask = DELETE |
1368 ACCESS_SYSTEM_SECURITY |
1372 FILE_READ_ATTRIBUTES |
1373 FILE_WRITE_ATTRIBUTES |
1375 FILE_LIST_DIRECTORY |
1379 // For a directory, add in the directory specific accesses
1385 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1390 if( FlagOn( DesiredAccess, ~stAccessMask))
1394 // A write access is set ...
1404 AFSEvaluateNode( IN GUID *AuthGroup,
1405 IN AFSDirectoryCB *DirEntry)
1408 NTSTATUS ntStatus = STATUS_SUCCESS;
1409 AFSDirEnumEntry *pDirEntry = NULL;
1410 UNICODE_STRING uniTargetName;
1415 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1420 if( !NT_SUCCESS( ntStatus))
1423 try_return( ntStatus);
1426 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1428 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1430 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1432 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1434 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1436 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1438 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1440 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1442 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1444 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1446 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1448 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1449 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1452 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1455 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1458 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1461 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1466 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1470 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1472 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1475 // If we have a target name then see if it needs updating ...
1478 if( pDirEntry->TargetNameLength > 0)
1482 // Update the target name information if needed
1485 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1487 uniTargetName.MaximumLength = uniTargetName.Length;
1489 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1491 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1494 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1495 RtlCompareUnicodeString( &uniTargetName,
1496 &DirEntry->NameInformation.TargetName,
1501 // Update the target name
1504 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1506 uniTargetName.Buffer,
1507 uniTargetName.Length);
1509 if( !NT_SUCCESS( ntStatus))
1512 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1514 try_return( ntStatus);
1518 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1523 if( pDirEntry != NULL)
1526 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1534 AFSValidateSymLink( IN GUID *AuthGroup,
1535 IN AFSDirectoryCB *DirEntry)
1538 NTSTATUS ntStatus = STATUS_SUCCESS;
1539 AFSDirEnumEntry *pDirEntry = NULL;
1540 UNICODE_STRING uniTargetName;
1545 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1550 if( !NT_SUCCESS( ntStatus))
1553 try_return( ntStatus);
1556 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1557 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1560 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1561 AFS_TRACE_LEVEL_VERBOSE_2,
1562 "AFSValidateSymLink Invalid type Status %08lX\n",
1563 STATUS_OBJECT_NAME_NOT_FOUND));
1565 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1568 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1570 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1572 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1575 // Update the target name information if needed
1578 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1580 uniTargetName.MaximumLength = uniTargetName.Length;
1582 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1584 if( uniTargetName.Length > 0)
1587 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1590 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1591 RtlCompareUnicodeString( &uniTargetName,
1592 &DirEntry->NameInformation.TargetName,
1597 // Update the target name
1600 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1602 uniTargetName.Buffer,
1603 uniTargetName.Length);
1605 if( !NT_SUCCESS( ntStatus))
1608 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1610 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1614 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1618 // If the FileType is the same then nothing to do since it IS
1622 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1625 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1627 try_return( ntStatus = STATUS_SUCCESS);
1630 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1632 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1634 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1636 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1638 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1640 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1642 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1644 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1646 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1647 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1650 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1653 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1656 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1659 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1664 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1668 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1670 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1674 if( pDirEntry != NULL)
1677 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1685 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1689 NTSTATUS ntStatus = STATUS_SUCCESS;
1690 IO_STATUS_BLOCK stIoStatus;
1692 AFSObjectInfoCB * pParentObjectInfo = NULL;
1694 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1695 AFS_TRACE_LEVEL_VERBOSE,
1696 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1697 (*ppObjectInfo)->FileType,
1698 (*ppObjectInfo)->FileId.Cell,
1699 (*ppObjectInfo)->FileId.Volume,
1700 (*ppObjectInfo)->FileId.Vnode,
1701 (*ppObjectInfo)->FileId.Unique,
1704 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1707 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1708 &(*ppObjectInfo)->ParentFileId);
1711 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1712 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1713 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1716 // We only act on the mount point itself, not the target. If the
1717 // node has been deleted then mark it as such otherwise indicate
1718 // it requires verification
1721 if( Reason == AFS_INVALIDATE_DELETED)
1723 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1728 if( Reason == AFS_INVALIDATE_FLUSHED)
1731 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1733 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1736 (*ppObjectInfo)->Expiration.QuadPart = 0;
1738 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1740 (*ppObjectInfo)->TargetFileId.Unique = 0;
1742 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1743 AFS_TRACE_LEVEL_VERBOSE,
1744 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1745 (*ppObjectInfo)->FileId.Cell,
1746 (*ppObjectInfo)->FileId.Volume,
1747 (*ppObjectInfo)->FileId.Vnode,
1748 (*ppObjectInfo)->FileId.Unique));
1750 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1753 if ( pParentObjectInfo != NULL)
1756 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1758 if( Reason == AFS_INVALIDATE_CREDS)
1760 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1763 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1764 Reason == AFS_INVALIDATE_FLUSHED)
1766 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1770 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1773 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1776 FILE_ACTION_MODIFIED);
1779 try_return( ntStatus);
1783 // Depending on the reason for invalidation then perform work on the node
1789 case AFS_INVALIDATE_DELETED:
1793 // Mark this node as invalid
1796 (*ppObjectInfo)->Links = 0;
1798 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1800 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1801 AFS_TRACE_LEVEL_VERBOSE,
1802 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1803 (*ppObjectInfo)->FileId.Cell,
1804 (*ppObjectInfo)->FileId.Volume,
1805 (*ppObjectInfo)->FileId.Vnode,
1806 (*ppObjectInfo)->FileId.Unique));
1808 if( pParentObjectInfo != NULL)
1811 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1812 AFS_TRACE_LEVEL_VERBOSE,
1813 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1814 pParentObjectInfo->FileId.Cell,
1815 pParentObjectInfo->FileId.Volume,
1816 pParentObjectInfo->FileId.Vnode,
1817 pParentObjectInfo->FileId.Unique));
1819 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1821 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1823 pParentObjectInfo->Expiration.QuadPart = 0;
1825 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1827 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1831 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1834 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1837 FILE_ACTION_REMOVED);
1840 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1843 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1849 case AFS_INVALIDATE_FLUSHED:
1852 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1853 (*ppObjectInfo)->Fcb != NULL)
1856 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1857 AFS_TRACE_LEVEL_VERBOSE,
1858 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1859 (*ppObjectInfo)->FileId.Cell,
1860 (*ppObjectInfo)->FileId.Volume,
1861 (*ppObjectInfo)->FileId.Vnode,
1862 (*ppObjectInfo)->FileId.Unique));
1864 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1870 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1875 if( !NT_SUCCESS( stIoStatus.Status))
1878 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1879 AFS_TRACE_LEVEL_ERROR,
1880 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1881 (*ppObjectInfo)->FileId.Cell,
1882 (*ppObjectInfo)->FileId.Volume,
1883 (*ppObjectInfo)->FileId.Vnode,
1884 (*ppObjectInfo)->FileId.Unique,
1886 stIoStatus.Information));
1888 ntStatus = stIoStatus.Status;
1892 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1895 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1901 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1902 AFS_TRACE_LEVEL_WARNING,
1903 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1904 (*ppObjectInfo)->FileId.Cell,
1905 (*ppObjectInfo)->FileId.Volume,
1906 (*ppObjectInfo)->FileId.Vnode,
1907 (*ppObjectInfo)->FileId.Unique));
1909 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1913 __except( EXCEPTION_EXECUTE_HANDLER)
1916 ntStatus = GetExceptionCode();
1920 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1921 (*ppObjectInfo)->FileId.Cell,
1922 (*ppObjectInfo)->FileId.Volume,
1923 (*ppObjectInfo)->FileId.Vnode,
1924 (*ppObjectInfo)->FileId.Unique,
1927 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1930 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1933 // Clear out the extents
1934 // Get rid of them (note this involves waiting
1935 // for any writes or reads to the cache to complete)
1938 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1942 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1945 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1948 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1949 AFS_TRACE_LEVEL_VERBOSE,
1950 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1951 (*ppObjectInfo)->FileId.Cell,
1952 (*ppObjectInfo)->FileId.Volume,
1953 (*ppObjectInfo)->FileId.Vnode,
1954 (*ppObjectInfo)->FileId.Unique));
1956 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1959 // Fall through to the default processing
1965 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1967 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1971 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1974 if( Reason == AFS_INVALIDATE_CREDS)
1976 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1979 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1981 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1985 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1988 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1991 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1994 FILE_ACTION_MODIFIED);
1996 else if ( pParentObjectInfo != NULL)
1999 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2002 FILE_ACTION_MODIFIED);
2006 // Indicate this node requires re-evaluation for the remaining reasons
2009 (*ppObjectInfo)->Expiration.QuadPart = 0;
2011 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2012 AFS_TRACE_LEVEL_VERBOSE,
2013 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2014 (*ppObjectInfo)->FileId.Cell,
2015 (*ppObjectInfo)->FileId.Volume,
2016 (*ppObjectInfo)->FileId.Vnode,
2017 (*ppObjectInfo)->FileId.Unique));
2019 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
2021 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2022 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
2023 ( Reason == AFS_INVALIDATE_CALLBACK ||
2024 Reason == AFS_INVALIDATE_EXPIRED))
2026 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
2027 AFS_INVALIDATE_DATA_VERSION)))
2030 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
2040 if ( pParentObjectInfo != NULL)
2043 AFSReleaseObjectInfo( &pParentObjectInfo);
2050 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
2053 NTSTATUS ntStatus = STATUS_SUCCESS;
2054 AFSVolumeCB *pVolumeCB = NULL;
2055 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2056 ULONGLONG ullIndex = 0;
2057 AFSObjectInfoCB *pObjectInfo = NULL;
2063 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2064 AFS_TRACE_LEVEL_VERBOSE,
2065 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
2066 InvalidateCB->FileID.Cell,
2067 InvalidateCB->FileID.Volume,
2068 InvalidateCB->FileID.Vnode,
2069 InvalidateCB->FileID.Unique,
2070 InvalidateCB->FileType,
2071 InvalidateCB->WholeVolume,
2072 InvalidateCB->Reason));
2075 // Need to locate the Fcb for the directory to purge
2078 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2079 AFS_TRACE_LEVEL_VERBOSE,
2080 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2081 &pDevExt->Specific.RDR.VolumeTreeLock,
2082 PsGetCurrentThread()));
2085 // Starve any exclusive waiters on this paticular call
2088 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2091 // Locate the volume node
2094 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2096 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2098 (AFSBTreeEntry **)&pVolumeCB);
2100 if( pVolumeCB != NULL)
2103 lCount = AFSVolumeIncrement( pVolumeCB,
2104 AFS_VOLUME_REFERENCE_INVALIDATE);
2106 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2107 AFS_TRACE_LEVEL_VERBOSE,
2108 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2113 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2115 if( !NT_SUCCESS( ntStatus) ||
2119 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2120 AFS_TRACE_LEVEL_WARNING,
2121 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2122 InvalidateCB->FileID.Cell,
2123 InvalidateCB->FileID.Volume,
2124 InvalidateCB->FileID.Vnode,
2125 InvalidateCB->FileID.Unique,
2128 try_return( ntStatus = STATUS_SUCCESS);
2132 // If this is a whole volume invalidation then go do it now
2135 if( InvalidateCB->WholeVolume)
2138 ntStatus = AFSInvalidateVolume( pVolumeCB,
2139 InvalidateCB->Reason);
2141 try_return( ntStatus);
2144 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
2147 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2150 pObjectInfo = &pVolumeCB->ObjectInformation;
2155 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2157 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2159 (AFSBTreeEntry **)&pObjectInfo);
2162 if( pObjectInfo != NULL)
2166 // Reference the node so it won't be torn down
2169 lCount = AFSObjectInfoIncrement( pObjectInfo,
2170 AFS_OBJECT_REFERENCE_INVALIDATION);
2172 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2173 AFS_TRACE_LEVEL_VERBOSE,
2174 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2179 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2181 if( !NT_SUCCESS( ntStatus) ||
2182 pObjectInfo == NULL)
2185 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2186 AFS_TRACE_LEVEL_VERBOSE,
2187 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2188 InvalidateCB->FileID.Cell,
2189 InvalidateCB->FileID.Volume,
2190 InvalidateCB->FileID.Vnode,
2191 InvalidateCB->FileID.Unique,
2194 try_return( ntStatus = STATUS_SUCCESS);
2197 AFSInvalidateObject( &pObjectInfo,
2198 InvalidateCB->Reason);
2202 if( pObjectInfo != NULL)
2205 lCount = AFSObjectInfoDecrement( pObjectInfo,
2206 AFS_OBJECT_REFERENCE_INVALIDATION);
2208 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2209 AFS_TRACE_LEVEL_VERBOSE,
2210 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2215 if ( pVolumeCB != NULL)
2218 lCount = AFSVolumeDecrement( pVolumeCB,
2219 AFS_VOLUME_REFERENCE_INVALIDATE);
2221 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2222 AFS_TRACE_LEVEL_VERBOSE,
2223 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2233 AFSIsChildOfParent( IN AFSFcb *Dcb,
2237 BOOLEAN bIsChild = FALSE;
2238 AFSFcb *pCurrentFcb = Fcb;
2239 AFSObjectInfoCB * pParentObjectInfo = NULL;
2241 while( pCurrentFcb != NULL)
2244 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2245 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2253 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2254 &pCurrentFcb->ObjectInformation->ParentFileId);
2256 if ( pParentObjectInfo != NULL)
2259 pCurrentFcb = pParentObjectInfo->Fcb;
2261 AFSReleaseObjectInfo( &pParentObjectInfo);
2275 AFSCreateHighIndex( IN AFSFileID *FileID)
2278 ULONGLONG ullIndex = 0;
2280 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2287 AFSCreateLowIndex( IN AFSFileID *FileID)
2290 ULONGLONG ullIndex = 0;
2292 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2298 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2299 IN ACCESS_MASK GrantedAccess,
2300 IN BOOLEAN DirectoryEntry)
2303 BOOLEAN bAccessGranted = TRUE;
2306 // Check if we are asking for read/write and granted only read only
2307 // NOTE: There will be more checks here
2310 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2312 AFSCheckForReadOnlyAccess( GrantedAccess,
2316 bAccessGranted = FALSE;
2319 return bAccessGranted;
2323 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2326 NTSTATUS ntStatus = STATUS_SUCCESS;
2327 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2333 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2335 if( AFSGlobalRoot == NULL)
2342 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2345 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2352 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2359 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2360 IN UNICODE_STRING *SubstituteName,
2361 IN ULONG StringIndex)
2364 NTSTATUS ntStatus = STATUS_SUCCESS;
2365 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2366 AFSSysNameCB *pSysName = NULL;
2367 ERESOURCE *pSysNameLock = NULL;
2370 UNICODE_STRING uniSysName;
2377 if( IoIs32bitProcess( NULL))
2380 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2382 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2387 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2389 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2393 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2395 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2399 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2400 AFS_TRACE_LEVEL_VERBOSE,
2401 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2403 PsGetCurrentThread()));
2405 AFSAcquireShared( pSysNameLock,
2409 // Find where we are in the list
2412 while( pSysName != NULL &&
2413 ulIndex < StringIndex)
2416 pSysName = pSysName->fLink;
2421 if( pSysName == NULL)
2424 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2425 AFS_TRACE_LEVEL_VERBOSE_2,
2426 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2428 STATUS_OBJECT_NAME_NOT_FOUND));
2430 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2433 RtlInitUnicodeString( &uniSysName,
2436 // If it is a full component of @SYS then just substitue the
2440 if( RtlCompareUnicodeString( &uniSysName,
2445 SubstituteName->Length = pSysName->SysName.Length;
2446 SubstituteName->MaximumLength = SubstituteName->Length;
2448 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2449 SubstituteName->Length,
2450 AFS_SUBST_BUFFER_TAG);
2452 if( SubstituteName->Buffer == NULL)
2455 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2458 RtlCopyMemory( SubstituteName->Buffer,
2459 pSysName->SysName.Buffer,
2460 pSysName->SysName.Length);
2467 while( ComponentName->Buffer[ usIndex] != L'@')
2473 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2474 SubstituteName->MaximumLength = SubstituteName->Length;
2476 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2477 SubstituteName->Length,
2478 AFS_SUBST_BUFFER_TAG);
2480 if( SubstituteName->Buffer == NULL)
2483 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2486 RtlCopyMemory( SubstituteName->Buffer,
2487 ComponentName->Buffer,
2488 usIndex * sizeof( WCHAR));
2490 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2491 pSysName->SysName.Buffer,
2492 pSysName->SysName.Length);
2497 AFSReleaseResource( pSysNameLock);
2504 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2505 IN OUT UNICODE_STRING *ComponentName,
2506 IN UNICODE_STRING *SubstituteName,
2507 IN OUT UNICODE_STRING *RemainingPath,
2508 IN BOOLEAN FreePathName)
2511 NTSTATUS ntStatus = STATUS_SUCCESS;
2512 UNICODE_STRING uniPathName;
2513 USHORT usPrefixNameLen = 0;
2514 SHORT sNameLenDelta = 0;
2520 // If the passed in name can handle the additional length
2521 // then just moves things around
2524 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2526 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2528 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2531 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2534 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2535 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2536 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2539 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2540 SubstituteName->Buffer,
2541 SubstituteName->Length);
2543 FullPathName->Length += sNameLenDelta;
2545 ComponentName->Length += sNameLenDelta;
2547 ComponentName->MaximumLength = ComponentName->Length;
2549 if ( RemainingPath->Buffer)
2552 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2555 try_return( ntStatus);
2559 // Need to re-allocate the buffer
2562 uniPathName.Length = FullPathName->Length -
2563 ComponentName->Length +
2564 SubstituteName->Length;
2566 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2568 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2569 uniPathName.MaximumLength,
2570 AFS_NAME_BUFFER_FOUR_TAG);
2572 if( uniPathName.Buffer == NULL)
2575 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2578 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2580 usPrefixNameLen *= sizeof( WCHAR);
2582 RtlZeroMemory( uniPathName.Buffer,
2583 uniPathName.MaximumLength);
2585 RtlCopyMemory( uniPathName.Buffer,
2586 FullPathName->Buffer,
2589 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2590 SubstituteName->Buffer,
2591 SubstituteName->Length);
2593 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2596 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2597 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2598 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2601 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2603 ComponentName->Length += sNameLenDelta;
2605 ComponentName->MaximumLength = ComponentName->Length;
2607 if ( RemainingPath->Buffer)
2610 RemainingPath->Buffer = uniPathName.Buffer
2611 + (RemainingPath->Buffer - FullPathName->Buffer)
2612 + sNameLenDelta/sizeof( WCHAR);
2617 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2620 *FullPathName = uniPathName;
2631 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2635 NTSTATUS ntStatus = STATUS_SUCCESS;
2636 AFSObjectInfoCB *pCurrentObject = NULL;
2637 AFSObjectInfoCB *pNextObject = NULL;
2643 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2644 AFS_TRACE_LEVEL_VERBOSE,
2645 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2646 VolumeCB->ObjectInformation.FileId.Cell,
2647 VolumeCB->ObjectInformation.FileId.Volume,
2648 VolumeCB->ObjectInformation.FileId.Vnode,
2649 VolumeCB->ObjectInformation.FileId.Unique,
2653 // Depending on the reason for invalidation then perform work on the node
2659 case AFS_INVALIDATE_DELETED:
2663 // Mark this volume as invalid
2666 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2668 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2675 // Invalidate the volume root directory
2678 pCurrentObject = &VolumeCB->ObjectInformation;
2680 if ( pCurrentObject )
2683 lCount = AFSObjectInfoIncrement( pCurrentObject,
2684 AFS_OBJECT_REFERENCE_INVALIDATION);
2686 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2687 AFS_TRACE_LEVEL_VERBOSE,
2688 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2692 AFSInvalidateObject( &pCurrentObject,
2695 if ( pCurrentObject)
2698 lCount = AFSObjectInfoDecrement( pCurrentObject,
2699 AFS_OBJECT_REFERENCE_INVALIDATION);
2701 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2702 AFS_TRACE_LEVEL_VERBOSE,
2703 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2710 // Apply invalidation to all other volume objects
2713 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2716 pCurrentObject = VolumeCB->ObjectInfoListHead;
2718 if ( pCurrentObject)
2722 // Reference the node so it won't be torn down
2725 lCount = AFSObjectInfoIncrement( pCurrentObject,
2726 AFS_OBJECT_REFERENCE_INVALIDATION);
2728 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2729 AFS_TRACE_LEVEL_VERBOSE,
2730 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2735 while( pCurrentObject != NULL)
2738 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2744 // Reference the node so it won't be torn down
2747 lCount = AFSObjectInfoIncrement( pNextObject,
2748 AFS_OBJECT_REFERENCE_INVALIDATION);
2750 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2751 AFS_TRACE_LEVEL_VERBOSE,
2752 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2757 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2759 AFSInvalidateObject( &pCurrentObject,
2762 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2765 if ( pCurrentObject )
2768 lCount = AFSObjectInfoDecrement( pCurrentObject,
2769 AFS_OBJECT_REFERENCE_INVALIDATION);
2771 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2772 AFS_TRACE_LEVEL_VERBOSE,
2773 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2778 pCurrentObject = pNextObject;
2781 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2788 AFSInvalidateAllVolumes( VOID)
2790 AFSVolumeCB *pVolumeCB = NULL;
2791 AFSVolumeCB *pNextVolumeCB = NULL;
2792 AFSDeviceExt *pRDRDeviceExt = NULL;
2795 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2797 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2798 AFS_TRACE_LEVEL_VERBOSE,
2799 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2800 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2801 PsGetCurrentThread()));
2803 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2806 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2811 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2812 AFS_TRACE_LEVEL_VERBOSE,
2813 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2814 pVolumeCB->ObjectInfoTree.TreeLock,
2815 PsGetCurrentThread()));
2817 lCount = AFSVolumeIncrement( pVolumeCB,
2818 AFS_VOLUME_REFERENCE_INVALIDATE);
2820 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2821 AFS_TRACE_LEVEL_VERBOSE,
2822 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2827 while( pVolumeCB != NULL)
2830 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2835 lCount = AFSVolumeIncrement( pNextVolumeCB,
2836 AFS_VOLUME_REFERENCE_INVALIDATE);
2838 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2839 AFS_TRACE_LEVEL_VERBOSE,
2840 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2845 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2847 // do I need to hold the volume lock here?
2849 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2851 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2854 lCount = AFSVolumeDecrement( pVolumeCB,
2855 AFS_VOLUME_REFERENCE_INVALIDATE);
2857 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2858 AFS_TRACE_LEVEL_VERBOSE,
2859 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2863 pVolumeCB = pNextVolumeCB;
2866 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2870 AFSVerifyEntry( IN GUID *AuthGroup,
2871 IN AFSDirectoryCB *DirEntry)
2874 NTSTATUS ntStatus = STATUS_SUCCESS;
2875 AFSDirEnumEntry *pDirEnumEntry = NULL;
2876 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2877 IO_STATUS_BLOCK stIoStatus;
2882 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2883 AFS_TRACE_LEVEL_VERBOSE_2,
2884 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2885 &DirEntry->NameInformation.FileName,
2886 pObjectInfo->FileId.Cell,
2887 pObjectInfo->FileId.Volume,
2888 pObjectInfo->FileId.Vnode,
2889 pObjectInfo->FileId.Unique));
2891 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2896 if( !NT_SUCCESS( ntStatus))
2899 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2900 AFS_TRACE_LEVEL_ERROR,
2901 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2902 &DirEntry->NameInformation.FileName,
2903 pObjectInfo->FileId.Cell,
2904 pObjectInfo->FileId.Volume,
2905 pObjectInfo->FileId.Vnode,
2906 pObjectInfo->FileId.Unique,
2909 try_return( ntStatus);
2913 // Check the data version of the file
2916 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2918 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2921 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2922 AFS_TRACE_LEVEL_VERBOSE,
2923 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2924 pObjectInfo->DataVersion.QuadPart,
2925 &DirEntry->NameInformation.FileName,
2926 pObjectInfo->FileId.Cell,
2927 pObjectInfo->FileId.Volume,
2928 pObjectInfo->FileId.Vnode,
2929 pObjectInfo->FileId.Unique));
2932 // We are ok, just get out
2935 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2937 try_return( ntStatus = STATUS_SUCCESS);
2942 // New data version so we will need to process the node based on the type
2945 switch( pDirEnumEntry->FileType)
2948 case AFS_FILE_TYPE_MOUNTPOINT:
2952 // For a mount point we need to ensure the target is the same
2955 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2956 &pDirEnumEntry->TargetFileId))
2962 // Update the metadata for the entry
2965 ntStatus = AFSUpdateMetaData( DirEntry,
2968 if( NT_SUCCESS( ntStatus))
2971 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2977 case AFS_FILE_TYPE_SYMLINK:
2981 // Update the metadata for the entry
2984 ntStatus = AFSUpdateMetaData( DirEntry,
2987 if( NT_SUCCESS( ntStatus))
2990 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2996 case AFS_FILE_TYPE_FILE:
2998 FILE_OBJECT * pCCFileObject = NULL;
2999 BOOLEAN bPurgeExtents = FALSE;
3001 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3004 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3005 AFS_TRACE_LEVEL_VERBOSE,
3006 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
3007 &DirEntry->NameInformation.FileName,
3008 pObjectInfo->FileId.Cell,
3009 pObjectInfo->FileId.Volume,
3010 pObjectInfo->FileId.Vnode,
3011 pObjectInfo->FileId.Unique,
3012 pObjectInfo->DataVersion.LowPart,
3013 pDirEnumEntry->DataVersion.LowPart));
3015 bPurgeExtents = TRUE;
3018 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3021 bPurgeExtents = TRUE;
3023 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3024 AFS_TRACE_LEVEL_VERBOSE,
3025 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3026 &DirEntry->NameInformation.FileName,
3027 pObjectInfo->FileId.Cell,
3028 pObjectInfo->FileId.Volume,
3029 pObjectInfo->FileId.Vnode,
3030 pObjectInfo->FileId.Unique));
3032 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3035 if( pObjectInfo->Fcb != NULL)
3038 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3039 AFS_TRACE_LEVEL_VERBOSE,
3040 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3041 &DirEntry->NameInformation.FileName,
3042 pObjectInfo->FileId.Cell,
3043 pObjectInfo->FileId.Volume,
3044 pObjectInfo->FileId.Vnode,
3045 pObjectInfo->FileId.Unique));
3047 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3053 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3058 if( !NT_SUCCESS( stIoStatus.Status))
3061 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3062 AFS_TRACE_LEVEL_ERROR,
3063 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3064 &DirEntry->NameInformation.FileName,
3065 pObjectInfo->FileId.Cell,
3066 pObjectInfo->FileId.Volume,
3067 pObjectInfo->FileId.Vnode,
3068 pObjectInfo->FileId.Unique,
3070 stIoStatus.Information));
3072 ntStatus = stIoStatus.Status;
3075 if ( bPurgeExtents &&
3076 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3079 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3085 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3086 AFS_TRACE_LEVEL_WARNING,
3087 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3088 &DirEntry->NameInformation.FileName,
3089 pObjectInfo->FileId.Cell,
3090 pObjectInfo->FileId.Volume,
3091 pObjectInfo->FileId.Vnode,
3092 pObjectInfo->FileId.Unique));
3094 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3098 __except( EXCEPTION_EXECUTE_HANDLER)
3100 ntStatus = GetExceptionCode();
3104 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3105 &DirEntry->NameInformation.FileName,
3106 pObjectInfo->FileId.Cell,
3107 pObjectInfo->FileId.Volume,
3108 pObjectInfo->FileId.Vnode,
3109 pObjectInfo->FileId.Unique,
3112 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3115 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3119 AFSFlushExtents( pObjectInfo->Fcb,
3124 // Reacquire the Fcb to purge the cache
3127 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3128 AFS_TRACE_LEVEL_VERBOSE,
3129 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3130 &pObjectInfo->Fcb->NPFcb->Resource,
3131 PsGetCurrentThread()));
3133 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3137 // Update the metadata for the entry
3140 ntStatus = AFSUpdateMetaData( DirEntry,
3143 if( !NT_SUCCESS( ntStatus))
3146 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3147 AFS_TRACE_LEVEL_ERROR,
3148 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3149 &DirEntry->NameInformation.FileName,
3150 pObjectInfo->FileId.Cell,
3151 pObjectInfo->FileId.Volume,
3152 pObjectInfo->FileId.Vnode,
3153 pObjectInfo->FileId.Unique,
3160 // Update file sizes
3163 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3164 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3165 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3167 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3168 AFS_TRACE_LEVEL_VERBOSE,
3169 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3170 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3171 PsGetCurrentThread()));
3173 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3176 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3178 if ( pCCFileObject != NULL)
3180 CcSetFileSizes( pCCFileObject,
3181 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3184 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3185 AFS_TRACE_LEVEL_VERBOSE,
3186 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3187 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3188 PsGetCurrentThread()));
3190 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3192 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3198 // Update the metadata for the entry
3201 ntStatus = AFSUpdateMetaData( DirEntry,
3204 if( !NT_SUCCESS( ntStatus))
3207 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3208 AFS_TRACE_LEVEL_ERROR,
3209 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3210 &DirEntry->NameInformation.FileName,
3211 pObjectInfo->FileId.Cell,
3212 pObjectInfo->FileId.Volume,
3213 pObjectInfo->FileId.Vnode,
3214 pObjectInfo->FileId.Unique,
3220 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3221 AFS_TRACE_LEVEL_WARNING,
3222 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3223 &DirEntry->NameInformation.FileName,
3224 pObjectInfo->FileId.Cell,
3225 pObjectInfo->FileId.Volume,
3226 pObjectInfo->FileId.Vnode,
3227 pObjectInfo->FileId.Unique));
3230 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3235 case AFS_FILE_TYPE_DIRECTORY:
3239 // For a directory or root entry flush the content of
3240 // the directory enumeration.
3243 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3246 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3247 AFS_TRACE_LEVEL_VERBOSE_2,
3248 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3249 &DirEntry->NameInformation.FileName,
3250 pObjectInfo->FileId.Cell,
3251 pObjectInfo->FileId.Volume,
3252 pObjectInfo->FileId.Vnode,
3253 pObjectInfo->FileId.Unique));
3255 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3258 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3261 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3263 if ( !NT_SUCCESS( ntStatus))
3266 try_return( ntStatus);
3271 // Update the metadata for the entry
3274 ntStatus = AFSUpdateMetaData( DirEntry,
3277 if( NT_SUCCESS( ntStatus))
3280 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3286 case AFS_FILE_TYPE_DFSLINK:
3289 UNICODE_STRING uniTargetName;
3292 // For a DFS link need to check the target name has not changed
3295 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3297 uniTargetName.MaximumLength = uniTargetName.Length;
3299 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3301 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3304 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3305 RtlCompareUnicodeString( &uniTargetName,
3306 &DirEntry->NameInformation.TargetName,
3311 // Update the target name
3314 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3316 uniTargetName.Buffer,
3317 uniTargetName.Length);
3319 if( !NT_SUCCESS( ntStatus))
3322 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3328 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3331 // Update the metadata for the entry
3334 ntStatus = AFSUpdateMetaData( DirEntry,
3337 if( NT_SUCCESS( ntStatus))
3340 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3348 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3349 AFS_TRACE_LEVEL_WARNING,
3350 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3351 pObjectInfo->FileType,
3352 &DirEntry->NameInformation.FileName,
3353 pObjectInfo->FileId.Cell,
3354 pObjectInfo->FileId.Volume,
3355 pObjectInfo->FileId.Vnode,
3356 pObjectInfo->FileId.Unique));
3363 if( pDirEnumEntry != NULL)
3366 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3374 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3377 NTSTATUS ntStatus = STATUS_SUCCESS;
3378 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3379 ULONGLONG ullIndex = 0;
3380 AFSVolumeCB *pVolumeCB = NULL;
3386 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3387 AFS_TRACE_LEVEL_VERBOSE,
3388 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3389 VolumeStatus->Online,
3390 VolumeStatus->FileID.Cell,
3391 VolumeStatus->FileID.Volume));
3394 // Need to locate the Fcb for the directory to purge
3397 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3398 AFS_TRACE_LEVEL_VERBOSE,
3399 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3400 &pDevExt->Specific.RDR.VolumeTreeLock,
3401 PsGetCurrentThread()));
3403 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3406 // Locate the volume node
3409 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3411 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3413 (AFSBTreeEntry **)&pVolumeCB);
3415 if( pVolumeCB != NULL)
3418 lCount = AFSVolumeIncrement( pVolumeCB,
3419 AFS_VOLUME_REFERENCE_INVALIDATE);
3421 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3422 AFS_TRACE_LEVEL_VERBOSE,
3423 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3427 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3430 // Set the volume state accordingly
3433 if( VolumeStatus->Online)
3436 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3441 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3450 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3453 NTSTATUS ntStatus = STATUS_SUCCESS;
3458 if( AFSGlobalRoot == NULL)
3461 try_return( ntStatus);
3464 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3468 // Set the network state according to the information
3471 if( NetworkStatus->Online)
3474 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3479 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3482 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3493 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3497 NTSTATUS ntStatus = STATUS_SUCCESS;
3498 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3499 BOOLEAN bAcquiredLock = FALSE;
3500 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3505 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3506 AFS_TRACE_LEVEL_VERBOSE,
3507 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3508 ObjectInfo->FileId.Cell,
3509 ObjectInfo->FileId.Volume,
3510 ObjectInfo->FileId.Vnode,
3511 ObjectInfo->FileId.Unique));
3513 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3516 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3517 AFS_TRACE_LEVEL_VERBOSE,
3518 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3519 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3520 PsGetCurrentThread()));
3522 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3525 bAcquiredLock = TRUE;
3529 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3532 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3533 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3536 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3537 AFS_TRACE_LEVEL_ERROR,
3538 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3539 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3540 ObjectInfo->FileId.Cell,
3541 ObjectInfo->FileId.Volume,
3542 ObjectInfo->FileId.Vnode,
3543 ObjectInfo->FileId.Unique));
3547 // Reset the directory list information by clearing all valid entries
3550 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3552 while( pCurrentDirEntry != NULL)
3555 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3557 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3561 // If this entry has been deleted then process it here
3564 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3565 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3566 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3569 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3570 AFS_TRACE_LEVEL_VERBOSE,
3571 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3573 &pCurrentDirEntry->NameInformation.FileName));
3575 AFSDeleteDirEntry( ObjectInfo,
3581 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3583 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3584 AFS_TRACE_LEVEL_VERBOSE,
3585 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3587 pCurrentDirEntry->DirOpenReferenceCount));
3590 // We pull the short name from the parent tree since it could change below
3593 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3596 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3597 AFS_TRACE_LEVEL_VERBOSE,
3598 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3600 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3601 &pCurrentDirEntry->NameInformation.FileName));
3603 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3606 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3611 pCurrentDirEntry = pNextDirEntry;
3615 // Reget the directory contents
3618 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3621 if ( !NT_SUCCESS( ntStatus))
3623 try_return( ntStatus);
3627 // Now start again and tear down any entries not valid
3630 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3632 while( pCurrentDirEntry != NULL)
3635 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3637 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3640 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3641 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3642 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3645 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3648 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3650 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3651 AFS_TRACE_LEVEL_VERBOSE,
3652 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3654 &pCurrentDirEntry->NameInformation.FileName));
3656 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3661 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3664 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3665 AFS_TRACE_LEVEL_VERBOSE,
3666 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3668 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3669 &pCurrentDirEntry->NameInformation.FileName));
3673 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3675 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3676 AFS_TRACE_LEVEL_VERBOSE,
3677 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3679 &pCurrentDirEntry->NameInformation.FileName));
3684 pCurrentDirEntry = pNextDirEntry;
3689 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3690 AFS_TRACE_LEVEL_VERBOSE,
3691 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3693 pCurrentDirEntry->DirOpenReferenceCount));
3695 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3696 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3699 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3700 AFS_TRACE_LEVEL_VERBOSE,
3701 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3702 &pCurrentDirEntry->NameInformation.FileName,
3703 ObjectInfo->FileId.Cell,
3704 ObjectInfo->FileId.Volume,
3705 ObjectInfo->FileId.Vnode,
3706 ObjectInfo->FileId.Unique));
3708 AFSDeleteDirEntry( ObjectInfo,
3714 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3715 AFS_TRACE_LEVEL_VERBOSE,
3716 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3718 &pCurrentDirEntry->NameInformation.FileName,
3719 ObjectInfo->FileId.Cell,
3720 ObjectInfo->FileId.Volume,
3721 ObjectInfo->FileId.Vnode,
3722 ObjectInfo->FileId.Unique));
3724 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3726 AFSRemoveNameEntry( ObjectInfo,
3730 pCurrentDirEntry = pNextDirEntry;
3734 if( !AFSValidateDirList( ObjectInfo))
3737 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3746 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3754 AFSIsVolumeFID( IN AFSFileID *FileID)
3757 BOOLEAN bIsVolume = FALSE;
3759 if( FileID->Vnode == 1 &&
3760 FileID->Unique == 1)
3770 AFSIsFinalNode( IN AFSFcb *Fcb)
3773 BOOLEAN bIsFinalNode = FALSE;
3775 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3776 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3777 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3778 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3779 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3782 bIsFinalNode = TRUE;
3787 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3788 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3791 return bIsFinalNode;
3795 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3796 IN AFSDirEnumEntry *DirEnumEntry)
3799 NTSTATUS ntStatus = STATUS_SUCCESS;
3800 UNICODE_STRING uniTargetName;
3801 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3806 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3808 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3810 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3812 pObjectInfo->FileType = DirEnumEntry->FileType;
3814 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3816 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3818 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3820 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3822 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3824 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3826 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3828 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3829 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3832 pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3835 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
3838 if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
3841 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3846 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3850 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3852 pObjectInfo->Links = DirEnumEntry->Links;
3854 if( DirEnumEntry->TargetNameLength > 0 &&
3855 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3856 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3860 // Update the target name information if needed
3863 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3865 uniTargetName.MaximumLength = uniTargetName.Length;
3867 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3869 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3872 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3873 RtlCompareUnicodeString( &uniTargetName,
3874 &DirEntry->NameInformation.TargetName,
3879 // Update the target name
3882 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3884 uniTargetName.Buffer,
3885 uniTargetName.Length);
3887 if( !NT_SUCCESS( ntStatus))
3890 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3892 try_return( ntStatus);
3896 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3898 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3899 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3902 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3905 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3906 DirEntry->NameInformation.TargetName.Buffer != NULL)
3908 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3911 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3913 DirEntry->NameInformation.TargetName.Length = 0;
3914 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3915 DirEntry->NameInformation.TargetName.Buffer = NULL;
3917 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3929 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3931 IN BOOLEAN FastCall,
3932 IN BOOLEAN bSafeToPurge)
3935 NTSTATUS ntStatus = STATUS_SUCCESS;
3936 LARGE_INTEGER liSystemTime;
3937 AFSDirEnumEntry *pDirEnumEntry = NULL;
3938 AFSFcb *pCurrentFcb = NULL;
3939 BOOLEAN bReleaseFcb = FALSE;
3940 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3946 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3950 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3951 AFS_TRACE_LEVEL_VERBOSE_2,
3952 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3953 &DirEntry->NameInformation.FileName,
3954 pObjectInfo->FileId.Cell,
3955 pObjectInfo->FileId.Volume,
3956 pObjectInfo->FileId.Vnode,
3957 pObjectInfo->FileId.Unique,
3961 // If this is a fake node then bail since the service knows nothing about it
3964 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3967 try_return( ntStatus);
3971 // This routine ensures that the current entry is valid by:
3973 // 1) Checking that the expiration time is non-zero and after where we
3977 KeQuerySystemTime( &liSystemTime);
3979 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3980 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3981 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3982 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3985 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3986 AFS_TRACE_LEVEL_VERBOSE_2,
3987 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3988 &DirEntry->NameInformation.FileName,
3989 pObjectInfo->FileId.Cell,
3990 pObjectInfo->FileId.Volume,
3991 pObjectInfo->FileId.Vnode,
3992 pObjectInfo->FileId.Unique));
3994 try_return( ntStatus);
3998 // This node requires updating
4001 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
4006 if( !NT_SUCCESS( ntStatus))
4009 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4010 AFS_TRACE_LEVEL_ERROR,
4011 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4013 &DirEntry->NameInformation.FileName,
4014 pObjectInfo->FileId.Cell,
4015 pObjectInfo->FileId.Volume,
4016 pObjectInfo->FileId.Vnode,
4017 pObjectInfo->FileId.Unique,
4021 // Failed validation of node so return access-denied
4024 try_return( ntStatus);
4027 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4028 AFS_TRACE_LEVEL_VERBOSE,
4029 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
4031 &DirEntry->NameInformation.FileName,
4032 pObjectInfo->FileId.Cell,
4033 pObjectInfo->FileId.Volume,
4034 pObjectInfo->FileId.Vnode,
4035 pObjectInfo->FileId.Unique,
4036 pObjectInfo->DataVersion.QuadPart,
4037 pDirEnumEntry->DataVersion.QuadPart,
4038 pDirEnumEntry->FileType));
4042 // Based on the file type, process the node
4045 switch( pDirEnumEntry->FileType)
4048 case AFS_FILE_TYPE_MOUNTPOINT:
4052 // Update the metadata for the entry
4055 ntStatus = AFSUpdateMetaData( DirEntry,
4058 if( NT_SUCCESS( ntStatus))
4061 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4067 case AFS_FILE_TYPE_SYMLINK:
4068 case AFS_FILE_TYPE_DFSLINK:
4072 // Update the metadata for the entry
4075 ntStatus = AFSUpdateMetaData( DirEntry,
4078 if( NT_SUCCESS( ntStatus))
4081 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4087 case AFS_FILE_TYPE_FILE:
4090 BOOLEAN bPurgeExtents = FALSE;
4093 // For a file where the data version has become invalid we need to
4094 // fail any current extent requests and purge the cache for the file
4095 // Can't hold the Fcb resource while doing this
4098 if( pObjectInfo->Fcb != NULL &&
4099 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4100 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4103 pCurrentFcb = pObjectInfo->Fcb;
4105 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4108 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4109 AFS_TRACE_LEVEL_VERBOSE,
4110 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4111 &pCurrentFcb->NPFcb->Resource,
4112 PsGetCurrentThread()));
4114 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4120 if( pCurrentFcb != NULL)
4123 IO_STATUS_BLOCK stIoStatus;
4125 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4126 AFS_TRACE_LEVEL_VERBOSE_2,
4127 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4128 &DirEntry->NameInformation.FileName,
4129 pObjectInfo->FileId.Cell,
4130 pObjectInfo->FileId.Volume,
4131 pObjectInfo->FileId.Vnode,
4132 pObjectInfo->FileId.Unique));
4134 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4137 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4138 AFS_TRACE_LEVEL_VERBOSE,
4139 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4140 &DirEntry->NameInformation.FileName,
4141 pObjectInfo->FileId.Cell,
4142 pObjectInfo->FileId.Volume,
4143 pObjectInfo->FileId.Vnode,
4144 pObjectInfo->FileId.Unique,
4145 pObjectInfo->DataVersion.LowPart,
4146 pDirEnumEntry->DataVersion.LowPart));
4148 bPurgeExtents = TRUE;
4154 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4156 bPurgeExtents = TRUE;
4158 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4159 AFS_TRACE_LEVEL_VERBOSE,
4160 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4161 &DirEntry->NameInformation.FileName,
4162 pObjectInfo->FileId.Cell,
4163 pObjectInfo->FileId.Volume,
4164 pObjectInfo->FileId.Vnode,
4165 pObjectInfo->FileId.Unique));
4167 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4170 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4171 AFS_TRACE_LEVEL_VERBOSE,
4172 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4173 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4174 PsGetCurrentThread()));
4176 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4180 // Release Fcb->Resource to avoid Trend Micro deadlock
4183 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
4188 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4193 if( !NT_SUCCESS( stIoStatus.Status))
4196 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4197 AFS_TRACE_LEVEL_ERROR,
4198 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4199 &DirEntry->NameInformation.FileName,
4200 pObjectInfo->FileId.Cell,
4201 pObjectInfo->FileId.Volume,
4202 pObjectInfo->FileId.Vnode,
4203 pObjectInfo->FileId.Unique,
4205 stIoStatus.Information));
4207 ntStatus = stIoStatus.Status;
4210 if ( bPurgeExtents &&
4211 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4214 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4220 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4221 AFS_TRACE_LEVEL_WARNING,
4222 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4223 &DirEntry->NameInformation.FileName,
4224 pObjectInfo->FileId.Cell,
4225 pObjectInfo->FileId.Volume,
4226 pObjectInfo->FileId.Vnode,
4227 pObjectInfo->FileId.Unique));
4229 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4233 __except( EXCEPTION_EXECUTE_HANDLER)
4235 ntStatus = GetExceptionCode();
4239 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4240 &DirEntry->NameInformation.FileName,
4241 pObjectInfo->FileId.Cell,
4242 pObjectInfo->FileId.Volume,
4243 pObjectInfo->FileId.Vnode,
4244 pObjectInfo->FileId.Unique,
4247 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4250 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4251 AFS_TRACE_LEVEL_VERBOSE,
4252 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4253 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4254 PsGetCurrentThread()));
4256 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4258 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4267 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4272 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4274 bReleaseFcb = FALSE;
4276 if ( bPurgeExtents &&
4279 AFSFlushExtents( pCurrentFcb,
4286 // Update the metadata for the entry but only if it is safe to do so.
4287 // If it was determined that a data version change has occurred or
4288 // that a pending data verification was required, do not update the
4289 // ObjectInfo meta data or the FileObject size information. That
4290 // way it is consistent for the next time that the data is verified
4294 if ( !(bPurgeExtents && bSafeToPurge))
4297 ntStatus = AFSUpdateMetaData( DirEntry,
4300 if( !NT_SUCCESS( ntStatus))
4303 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4304 AFS_TRACE_LEVEL_ERROR,
4305 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4306 &DirEntry->NameInformation.FileName,
4307 pObjectInfo->FileId.Cell,
4308 pObjectInfo->FileId.Volume,
4309 pObjectInfo->FileId.Vnode,
4310 pObjectInfo->FileId.Unique,
4316 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4319 // Update file sizes
4322 if( pObjectInfo->Fcb != NULL)
4324 FILE_OBJECT *pCCFileObject;
4326 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4327 AFS_TRACE_LEVEL_VERBOSE,
4328 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4329 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4330 PsGetCurrentThread()));
4332 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4335 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4337 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4338 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4339 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4341 if ( pCCFileObject != NULL)
4343 CcSetFileSizes( pCCFileObject,
4344 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4347 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4348 AFS_TRACE_LEVEL_VERBOSE,
4349 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4350 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4351 PsGetCurrentThread()));
4353 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4359 case AFS_FILE_TYPE_DIRECTORY:
4362 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4366 // For a directory or root entry flush the content of
4367 // the directory enumeration.
4370 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4371 AFS_TRACE_LEVEL_VERBOSE,
4372 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4373 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4374 PsGetCurrentThread()));
4376 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4379 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4380 AFS_TRACE_LEVEL_VERBOSE_2,
4381 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4382 &DirEntry->NameInformation.FileName,
4383 pObjectInfo->FileId.Cell,
4384 pObjectInfo->FileId.Volume,
4385 pObjectInfo->FileId.Vnode,
4386 pObjectInfo->FileId.Unique));
4388 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4391 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4394 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4397 if( !NT_SUCCESS( ntStatus))
4400 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4401 AFS_TRACE_LEVEL_ERROR,
4402 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4403 &DirEntry->NameInformation.FileName,
4404 pObjectInfo->FileId.Cell,
4405 pObjectInfo->FileId.Volume,
4406 pObjectInfo->FileId.Vnode,
4407 pObjectInfo->FileId.Unique,
4415 // Update the metadata for the entry
4418 ntStatus = AFSUpdateMetaData( DirEntry,
4421 if( NT_SUCCESS( ntStatus))
4424 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4432 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4433 AFS_TRACE_LEVEL_WARNING,
4434 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4435 pObjectInfo->FileType,
4437 &DirEntry->NameInformation.FileName,
4438 pObjectInfo->FileId.Cell,
4439 pObjectInfo->FileId.Volume,
4440 pObjectInfo->FileId.Vnode,
4441 pObjectInfo->FileId.Unique));
4451 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4454 if( pDirEnumEntry != NULL)
4457 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4465 AFSInitializeSpecialShareNameList()
4468 NTSTATUS ntStatus = STATUS_SUCCESS;
4469 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4470 AFSObjectInfoCB *pObjectInfoCB = NULL;
4471 UNICODE_STRING uniShareName;
4472 ULONG ulEntryLength = 0;
4473 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4479 RtlInitUnicodeString( &uniShareName,
4482 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4485 if( pObjectInfoCB == NULL)
4488 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4491 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4492 AFS_OBJECT_REFERENCE_GLOBAL);
4494 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4495 AFS_TRACE_LEVEL_VERBOSE,
4496 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4500 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4502 ulEntryLength = sizeof( AFSDirectoryCB) +
4503 uniShareName.Length;
4505 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4509 if( pDirNode == NULL)
4512 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4513 AFS_OBJECT_REFERENCE_GLOBAL);
4515 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4516 AFS_TRACE_LEVEL_VERBOSE,
4517 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4524 AFSDeleteObjectInfo( &pObjectInfoCB);
4527 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4530 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4531 AFS_TRACE_LEVEL_VERBOSE,
4532 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4535 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4536 sizeof( AFSNonPagedDirectoryCB),
4537 AFS_DIR_ENTRY_NP_TAG);
4539 if( pNonPagedDirEntry == NULL)
4542 ExFreePool( pDirNode);
4544 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4545 AFS_OBJECT_REFERENCE_GLOBAL);
4547 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4548 AFS_TRACE_LEVEL_VERBOSE,
4549 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4556 AFSDeleteObjectInfo( &pObjectInfoCB);
4559 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4562 RtlZeroMemory( pDirNode,
4565 RtlZeroMemory( pNonPagedDirEntry,
4566 sizeof( AFSNonPagedDirectoryCB));
4568 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4570 pDirNode->NonPaged = pNonPagedDirEntry;
4572 pDirNode->ObjectInformation = pObjectInfoCB;
4578 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4580 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4582 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4584 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4586 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4587 uniShareName.Buffer,
4588 pDirNode->NameInformation.FileName.Length);
4590 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4593 AFSSpecialShareNames = pDirNode;
4595 pLastDirNode = pDirNode;
4598 RtlInitUnicodeString( &uniShareName,
4601 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4604 if( pObjectInfoCB == NULL)
4607 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4610 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4611 AFS_OBJECT_REFERENCE_GLOBAL);
4613 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4614 AFS_TRACE_LEVEL_VERBOSE,
4615 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4619 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4621 ulEntryLength = sizeof( AFSDirectoryCB) +
4622 uniShareName.Length;
4624 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4628 if( pDirNode == NULL)
4631 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4632 AFS_OBJECT_REFERENCE_GLOBAL);
4634 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4635 AFS_TRACE_LEVEL_VERBOSE,
4636 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4643 AFSDeleteObjectInfo( &pObjectInfoCB);
4646 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4649 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4650 AFS_TRACE_LEVEL_VERBOSE,
4651 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4654 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4655 sizeof( AFSNonPagedDirectoryCB),
4656 AFS_DIR_ENTRY_NP_TAG);
4658 if( pNonPagedDirEntry == NULL)
4661 ExFreePool( pDirNode);
4663 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4664 AFS_OBJECT_REFERENCE_GLOBAL);
4666 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4667 AFS_TRACE_LEVEL_VERBOSE,
4668 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4675 AFSDeleteObjectInfo( &pObjectInfoCB);
4678 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4681 RtlZeroMemory( pDirNode,
4684 RtlZeroMemory( pNonPagedDirEntry,
4685 sizeof( AFSNonPagedDirectoryCB));
4687 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4689 pDirNode->NonPaged = pNonPagedDirEntry;
4691 pDirNode->ObjectInformation = pObjectInfoCB;
4697 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4699 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4701 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4703 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4705 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4706 uniShareName.Buffer,
4707 pDirNode->NameInformation.FileName.Length);
4709 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4712 pLastDirNode->ListEntry.fLink = pDirNode;
4714 pDirNode->ListEntry.bLink = pLastDirNode;
4718 if( !NT_SUCCESS( ntStatus))
4721 if( AFSSpecialShareNames != NULL)
4724 pDirNode = AFSSpecialShareNames;
4726 while( pDirNode != NULL)
4729 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4731 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
4732 AFS_OBJECT_REFERENCE_GLOBAL);
4734 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4735 AFS_TRACE_LEVEL_VERBOSE,
4736 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4737 pDirNode->ObjectInformation,
4743 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4746 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4748 ExFreePool( pDirNode->NonPaged);
4750 ExFreePool( pDirNode);
4752 pDirNode = pLastDirNode;
4755 AFSSpecialShareNames = NULL;
4764 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4765 IN UNICODE_STRING *SecondaryName)
4768 AFSDirectoryCB *pDirectoryCB = NULL;
4769 ULONGLONG ullHash = 0;
4770 UNICODE_STRING uniFullShareName;
4776 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4777 AFS_TRACE_LEVEL_VERBOSE_2,
4778 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4782 uniFullShareName = *ShareName;
4785 // Generate our hash value
4788 ullHash = AFSGenerateCRC( &uniFullShareName,
4792 // Loop through our special share names to see if this is one of them
4795 pDirectoryCB = AFSSpecialShareNames;
4797 while( pDirectoryCB != NULL)
4800 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4806 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4810 return pDirectoryCB;
4814 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4818 // Block on the queue flush event
4821 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4831 AFSWaitOnQueuedReleases()
4834 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4837 // Block on the queue flush event
4840 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4850 AFSIsEqualFID( IN AFSFileID *FileId1,
4851 IN AFSFileID *FileId2)
4854 BOOLEAN bIsEqual = FALSE;
4856 if( FileId1->Hash == FileId2->Hash &&
4857 FileId1->Unique == FileId2->Unique &&
4858 FileId1->Vnode == FileId2->Vnode &&
4859 FileId1->Volume == FileId2->Volume &&
4860 FileId1->Cell == FileId2->Cell)
4870 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4873 NTSTATUS ntStatus = STATUS_SUCCESS;
4874 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4879 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4882 // Reset the directory list information
4885 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4887 while( pCurrentDirEntry != NULL)
4890 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4892 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
4893 pCurrentDirEntry->NameArrayReferenceCount <= 0)
4896 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4897 AFS_TRACE_LEVEL_VERBOSE,
4898 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4900 &pCurrentDirEntry->NameInformation.FileName));
4902 AFSDeleteDirEntry( ObjectInfoCB,
4908 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4909 AFS_TRACE_LEVEL_VERBOSE,
4910 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4912 &pCurrentDirEntry->NameInformation.FileName));
4914 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4916 AFSRemoveNameEntry( ObjectInfoCB,
4920 pCurrentDirEntry = pNextDirEntry;
4923 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4925 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4927 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4929 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4931 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4933 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4935 AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4936 AFS_TRACE_LEVEL_VERBOSE,
4937 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4938 ObjectInfoCB->FileId.Cell,
4939 ObjectInfoCB->FileId.Volume,
4940 ObjectInfoCB->FileId.Vnode,
4941 ObjectInfoCB->FileId.Unique));
4948 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4951 NTSTATUS ntStatus = STATUS_SUCCESS;
4952 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4953 UNICODE_STRING uniFullName;
4958 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4959 AFS_TRACE_LEVEL_VERBOSE,
4960 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4961 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4962 PsGetCurrentThread()));
4964 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4967 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4970 try_return( ntStatus);
4974 // Initialize the root information
4977 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4980 // Enumerate the shares in the volume
4983 ntStatus = AFSEnumerateDirectory( AuthGroup,
4984 &AFSGlobalRoot->ObjectInformation,
4987 if( !NT_SUCCESS( ntStatus))
4990 try_return( ntStatus);
4993 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4995 uniFullName.MaximumLength = PAGE_SIZE;
4996 uniFullName.Length = 0;
4998 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4999 uniFullName.MaximumLength,
5000 AFS_GENERIC_MEMORY_12_TAG);
5002 if( uniFullName.Buffer == NULL)
5006 // Reset the directory content
5009 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
5011 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
5013 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5017 // Populate our list of entries in the NP enumeration list
5020 while( pDirGlobalDirNode != NULL)
5023 uniFullName.Buffer[ 0] = L'\\';
5024 uniFullName.Buffer[ 1] = L'\\';
5026 uniFullName.Length = 2 * sizeof( WCHAR);
5028 RtlCopyMemory( &uniFullName.Buffer[ 2],
5029 AFSServerName.Buffer,
5030 AFSServerName.Length);
5032 uniFullName.Length += AFSServerName.Length;
5034 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
5036 uniFullName.Length += sizeof( WCHAR);
5038 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
5039 pDirGlobalDirNode->NameInformation.FileName.Buffer,
5040 pDirGlobalDirNode->NameInformation.FileName.Length);
5042 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
5044 AFSAddConnectionEx( &uniFullName,
5045 RESOURCEDISPLAYTYPE_SHARE,
5048 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
5051 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
5055 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
5062 AFSIsRelativeName( IN UNICODE_STRING *Name)
5065 BOOLEAN bIsRelative = FALSE;
5067 if( Name->Length > 0 &&
5068 Name->Buffer[ 0] != L'\\')
5078 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
5080 UNICODE_STRING uniTempName;
5081 BOOLEAN bIsAbsolute = FALSE;
5084 // An absolute AFS path must begin with \afs\... or equivalent
5087 if ( Name->Length == 0 ||
5088 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
5089 Name->Buffer[ 0] != L'\\' ||
5090 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
5096 uniTempName.Length = AFSMountRootName.Length;
5097 uniTempName.MaximumLength = AFSMountRootName.Length;
5099 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5100 uniTempName.MaximumLength,
5101 AFS_NAME_BUFFER_TWO_TAG);
5103 if( uniTempName.Buffer == NULL)
5109 RtlCopyMemory( uniTempName.Buffer,
5111 AFSMountRootName.Length);
5113 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
5117 AFSExFreePoolWithTag( uniTempName.Buffer,
5118 AFS_NAME_BUFFER_TWO_TAG);
5125 AFSUpdateName( IN UNICODE_STRING *Name)
5130 while( usIndex < Name->Length/sizeof( WCHAR))
5133 if( Name->Buffer[ usIndex] == L'/')
5136 Name->Buffer[ usIndex] = L'\\';
5146 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
5147 IN OUT ULONG *Flags,
5148 IN WCHAR *NameBuffer,
5149 IN USHORT NameLength)
5152 NTSTATUS ntStatus = STATUS_SUCCESS;
5153 WCHAR *pTmpBuffer = NULL;
5159 // If we have enough space then just move in the name otherwise
5160 // allocate a new buffer
5163 if( TargetName->Length < NameLength)
5166 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5168 AFS_NAME_BUFFER_FIVE_TAG);
5170 if( pTmpBuffer == NULL)
5173 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5176 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5179 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5182 TargetName->MaximumLength = NameLength;
5184 TargetName->Buffer = pTmpBuffer;
5186 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5189 TargetName->Length = NameLength;
5191 RtlCopyMemory( TargetName->Buffer,
5193 TargetName->Length);
5196 // Update the name in the buffer
5199 AFSUpdateName( TargetName);
5210 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5215 // Depending on the type of node, set the event
5218 switch( Fcb->Header.NodeTypeCode)
5221 case AFS_DIRECTORY_FCB:
5226 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5236 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5242 // Depending on the type of node, set the event
5245 switch( Fcb->Header.NodeTypeCode)
5248 case AFS_DIRECTORY_FCB:
5253 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5255 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5265 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5268 BOOLEAN bIsInProcess = FALSE;
5273 if( ObjectInfo->Fcb == NULL)
5276 try_return( bIsInProcess);
5279 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5282 case AFS_DIRECTORY_FCB:
5287 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5290 bIsInProcess = TRUE;
5302 return bIsInProcess;
5306 AFSVerifyVolume( IN ULONGLONG ProcessId,
5307 IN AFSVolumeCB *VolumeCB)
5310 UNREFERENCED_PARAMETER(ProcessId);
5311 UNREFERENCED_PARAMETER(VolumeCB);
5312 NTSTATUS ntStatus = STATUS_SUCCESS;
5319 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5322 NTSTATUS ntStatus = STATUS_SUCCESS;
5323 AFSObjectInfoCB *pObjectInfoCB = NULL;
5324 AFSDirectoryCB *pDirNode = NULL;
5325 ULONG ulEntryLength = 0;
5326 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5332 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
5335 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5338 if( pObjectInfoCB == NULL)
5341 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5343 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5346 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5347 AFS_OBJECT_REFERENCE_PIOCTL);
5349 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5350 AFS_TRACE_LEVEL_VERBOSE,
5351 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5355 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5357 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5359 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5361 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5363 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5367 if( pDirNode == NULL)
5370 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5373 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5374 AFS_TRACE_LEVEL_VERBOSE,
5375 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5378 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5379 sizeof( AFSNonPagedDirectoryCB),
5380 AFS_DIR_ENTRY_NP_TAG);
5382 if( pNonPagedDirEntry == NULL)
5385 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5388 RtlZeroMemory( pDirNode,
5391 RtlZeroMemory( pNonPagedDirEntry,
5392 sizeof( AFSNonPagedDirectoryCB));
5394 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5396 pDirNode->NonPaged = pNonPagedDirEntry;
5398 pDirNode->ObjectInformation = pObjectInfoCB;
5400 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5406 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5408 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5410 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5412 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5414 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5415 AFSPIOCtlName.Buffer,
5416 pDirNode->NameInformation.FileName.Length);
5418 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5421 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5424 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5425 AFS_TRACE_LEVEL_WARNING,
5426 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5427 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5430 try_return( ntStatus = STATUS_REPARSE);
5435 if ( ntStatus != STATUS_SUCCESS)
5438 if ( pDirNode != NULL)
5441 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5442 AFS_TRACE_LEVEL_VERBOSE,
5443 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
5446 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5449 if( pNonPagedDirEntry != NULL)
5452 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5454 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5457 if ( pObjectInfoCB != NULL)
5460 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
5461 AFS_OBJECT_REFERENCE_PIOCTL);
5463 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5464 AFS_TRACE_LEVEL_VERBOSE,
5465 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
5472 AFSDeleteObjectInfo( &pObjectInfoCB);
5482 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5483 IN AFSDirectoryCB *DirectoryCB,
5484 IN UNICODE_STRING *ParentPathName,
5485 IN AFSNameArrayHdr *RelatedNameArray,
5487 OUT AFSFileInfoCB *FileInfo)
5490 NTSTATUS ntStatus = STATUS_SUCCESS;
5491 AFSDirEnumEntry *pDirEntry = NULL;
5492 UNICODE_STRING uniFullPathName = {0};
5493 AFSNameArrayHdr *pNameArray = NULL;
5494 AFSVolumeCB *pVolumeCB = NULL;
5495 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5496 AFSVolumeCB *pNewVolumeCB = NULL;
5497 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5498 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5499 AFSDirectoryCB *pNewParentDirEntry = NULL;
5500 WCHAR *pwchBuffer = NULL;
5501 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5502 ULONG ulNameDifference = 0;
5509 // Retrieve a target name for the entry
5512 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5515 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5518 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5520 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5525 if( !NT_SUCCESS( ntStatus) ||
5526 pDirEntry->TargetNameLength == 0)
5529 if( pDirEntry != NULL)
5532 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5535 try_return( ntStatus);
5538 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5541 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5545 // Update the target name
5548 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5549 &DirectoryCB->Flags,
5550 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5551 (USHORT)pDirEntry->TargetNameLength);
5553 if( !NT_SUCCESS( ntStatus))
5556 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5558 try_return( ntStatus);
5562 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5566 // Need to pass the full path in for parsing.
5569 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5572 uniFullPathName.Length = 0;
5573 uniFullPathName.MaximumLength = ParentPathName->Length +
5575 DirectoryCB->NameInformation.TargetName.Length;
5577 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5578 uniFullPathName.MaximumLength,
5579 AFS_NAME_BUFFER_SIX_TAG);
5581 if( uniFullPathName.Buffer == NULL)
5584 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5586 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5589 pwchBuffer = uniFullPathName.Buffer;
5591 RtlZeroMemory( uniFullPathName.Buffer,
5592 uniFullPathName.MaximumLength);
5594 RtlCopyMemory( uniFullPathName.Buffer,
5595 ParentPathName->Buffer,
5596 ParentPathName->Length);
5598 uniFullPathName.Length = ParentPathName->Length;
5600 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5601 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5604 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5606 uniFullPathName.Length += sizeof( WCHAR);
5609 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5610 DirectoryCB->NameInformation.TargetName.Buffer,
5611 DirectoryCB->NameInformation.TargetName.Length);
5613 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5615 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5616 uniParsedName.MaximumLength = uniParsedName.Length;
5618 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5620 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5623 // We populate up to the current parent
5626 if( RelatedNameArray != NULL)
5629 pNameArray = AFSInitNameArray( NULL,
5630 RelatedNameArray->MaxElementCount);
5632 if( pNameArray == NULL)
5635 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5638 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5645 pNameArray = AFSInitNameArray( NULL,
5648 if( pNameArray == NULL)
5651 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5654 ntStatus = AFSPopulateNameArray( pNameArray,
5659 if( !NT_SUCCESS( ntStatus))
5662 try_return( ntStatus);
5665 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5667 pParentDirEntry = ParentDirectoryCB;
5672 uniFullPathName.Length = 0;
5673 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5675 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5676 uniFullPathName.MaximumLength,
5677 AFS_NAME_BUFFER_SEVEN_TAG);
5679 if( uniFullPathName.Buffer == NULL)
5682 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5684 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5687 pwchBuffer = uniFullPathName.Buffer;
5689 RtlZeroMemory( uniFullPathName.Buffer,
5690 uniFullPathName.MaximumLength);
5692 RtlCopyMemory( uniFullPathName.Buffer,
5693 DirectoryCB->NameInformation.TargetName.Buffer,
5694 DirectoryCB->NameInformation.TargetName.Length);
5696 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5699 // This name should begin with the \afs server so parse it off and check it
5702 FsRtlDissectName( uniFullPathName,
5706 if( RtlCompareUnicodeString( &uniComponentName,
5711 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5713 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5714 AFS_TRACE_LEVEL_ERROR,
5715 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5718 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5721 uniFullPathName = uniRemainingPath;
5723 uniParsedName = uniFullPathName;
5725 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5727 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5733 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5736 if( pNameArray == NULL)
5739 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5742 pVolumeCB = AFSGlobalRoot;
5744 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5748 // Increment the ref count on the volume and dir entry for correct processing below
5751 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
5753 lCount = AFSVolumeIncrement( pVolumeCB,
5754 VolumeReferenceReason);
5756 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5757 AFS_TRACE_LEVEL_VERBOSE,
5758 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
5760 VolumeReferenceReason,
5763 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
5765 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5766 AFS_TRACE_LEVEL_VERBOSE,
5767 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5768 &pParentDirEntry->NameInformation.FileName,
5773 ntStatus = AFSLocateNameEntry( NULL,
5778 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5782 &NewVolumeReferenceReason,
5783 &pNewParentDirEntry,
5787 if ( pNewVolumeCB != NULL)
5790 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
5791 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
5792 // the reference on pVolumeCB that was held prior to the call.
5793 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
5794 // will be released second.
5797 lCount = AFSVolumeDecrement( pVolumeCB,
5798 VolumeReferenceReason);
5800 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5801 AFS_TRACE_LEVEL_VERBOSE,
5802 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
5804 VolumeReferenceReason,
5807 pVolumeCB = pNewVolumeCB;
5809 pNewVolumeCB = NULL;
5811 VolumeReferenceReason = NewVolumeReferenceReason;
5813 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5817 // AFSLocateNameEntry does not alter the reference count of
5818 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
5819 // a reference held.
5822 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5824 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5825 AFS_TRACE_LEVEL_VERBOSE,
5826 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
5827 &pParentDirEntry->NameInformation.FileName,
5831 pParentDirEntry = pNewParentDirEntry;
5833 pNewParentDirEntry = NULL;
5835 if( !NT_SUCCESS( ntStatus) ||
5836 ntStatus == STATUS_REPARSE)
5839 try_return( ntStatus);
5843 // Store off the information
5846 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5849 // Check for the mount point being returned
5852 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
5853 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5856 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5858 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
5861 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
5864 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
5869 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5873 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5875 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5877 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5879 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5881 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5883 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5887 if( pDirEntry != NULL)
5890 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
5893 if( pDirectoryEntry != NULL)
5896 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
5898 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5899 AFS_TRACE_LEVEL_VERBOSE,
5900 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5901 &pDirectoryEntry->NameInformation.FileName,
5906 ASSERT( lCount >= 0);
5909 if ( pParentDirEntry != NULL)
5912 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5914 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5915 AFS_TRACE_LEVEL_VERBOSE,
5916 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5917 &pParentDirEntry->NameInformation.FileName,
5922 ASSERT( lCount >= 0);
5925 if( pVolumeCB != NULL)
5928 lCount = AFSVolumeDecrement( pVolumeCB,
5929 VolumeReferenceReason);
5931 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5932 AFS_TRACE_LEVEL_VERBOSE,
5933 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
5935 VolumeReferenceReason,
5939 if( pNameArray != NULL)
5942 AFSFreeNameArray( pNameArray);
5945 if( pwchBuffer != NULL)
5949 // Always free the buffer that we allocated as AFSLocateNameEntry
5950 // will not free it. If uniFullPathName.Buffer was allocated by
5951 // AFSLocateNameEntry, then we must free that as well.
5952 // Check that the uniFullPathName.Buffer in the string is not the same
5953 // offset by the length of the server name
5956 if( uniFullPathName.Length > 0 &&
5957 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
5960 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
5963 AFSExFreePoolWithTag( pwchBuffer, 0);
5971 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
5972 IN ULONGLONG HashIndex)
5975 NTSTATUS ntStatus = STATUS_SUCCESS;
5976 AFSObjectInfoCB *pObjectInfo = NULL;
5982 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
5983 sizeof( AFSObjectInfoCB),
5984 AFS_OBJECT_INFO_TAG);
5986 if( pObjectInfo == NULL)
5989 try_return( pObjectInfo);
5992 RtlZeroMemory( pObjectInfo,
5993 sizeof( AFSObjectInfoCB));
5995 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5996 sizeof( AFSNonPagedObjectInfoCB),
5997 AFS_NP_OBJECT_INFO_TAG);
5999 if( pObjectInfo->NonPagedInfo == NULL)
6002 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6004 try_return( pObjectInfo = NULL);
6007 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6009 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6011 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6013 if( ParentObjectInfo != NULL)
6016 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6018 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6020 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6022 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6023 AFS_OBJECT_REFERENCE_CHILD);
6025 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6026 AFS_TRACE_LEVEL_VERBOSE,
6027 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6033 // Initialize the access time
6036 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6041 ASSERT( ParentObjectInfo);
6044 // Insert the entry into the object tree and list
6047 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6049 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6052 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6057 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6058 &pObjectInfo->TreeEntry);
6060 ASSERT( NT_SUCCESS( ntStatus));
6064 // And the object list in the volume
6067 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6070 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6075 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6077 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6080 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6083 // Indicate the object is in the hash tree and linked list in the volume
6086 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6098 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6104 if ( ObjectInfo->ObjectReferenceCount == 0)
6107 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6110 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6115 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6118 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6123 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6125 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6130 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6132 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6138 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6142 LONG lCount, lCount2;
6144 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6147 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6152 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6154 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6156 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6159 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6162 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6164 ASSERT( lCount2 >= 0);
6166 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6172 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6173 IN AFSFileID *FileId)
6175 DWORD ntStatus = STATUS_SUCCESS;
6177 AFSObjectInfoCB *pObjectInfo = NULL;
6180 ullIndex = AFSCreateLowIndex( FileId);
6182 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
6185 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6188 pObjectInfo = &VolumeCB->ObjectInformation;
6193 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6195 (AFSBTreeEntry **)&pObjectInfo);
6198 if ( NT_SUCCESS( ntStatus)) {
6200 lCount = AFSObjectInfoIncrement( pObjectInfo,
6201 AFS_OBJECT_REFERENCE_FIND);
6203 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6204 AFS_TRACE_LEVEL_VERBOSE,
6205 "AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
6210 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6216 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6220 lCount = AFSObjectInfoDecrement( *ppObjectInfo,
6221 AFS_OBJECT_REFERENCE_FIND);
6223 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6224 AFS_TRACE_LEVEL_VERBOSE,
6225 "AFSReleaseObjectInfo Decrement count on object %p Cnt %d\n",
6229 *ppObjectInfo = NULL;
6233 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6235 BOOLEAN bAcquiredTreeLock = FALSE;
6236 AFSObjectInfoCB *pObjectInfo = NULL;
6237 AFSVolumeCB * pVolume = NULL;
6238 BOOLEAN bHeldInService;
6239 AFSObjectInfoCB * pParentObjectInfo = NULL;
6245 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
6249 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6250 // embedded in the VolumeCB.
6258 pVolume = (*ppObjectInfo)->VolumeCB;
6260 if( !ExIsResourceAcquiredExclusiveLite( pVolume->ObjectInfoTree.TreeLock))
6263 ASSERT( !ExIsResourceAcquiredLite( pVolume->ObjectInfoTree.TreeLock));
6265 AFSAcquireExcl( pVolume->ObjectInfoTree.TreeLock,
6268 bAcquiredTreeLock = TRUE;
6271 for ( lCount = 0; lCount < AFS_OBJECT_REFERENCE_MAX; lCount++)
6274 ASSERT( (*ppObjectInfo)->ObjectReferences[ lCount] >= 0);
6277 ASSERT( (*ppObjectInfo)->ObjectReferenceCount == 0);
6279 pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
6283 if ( pObjectInfo == NULL)
6286 try_return( NOTHING);
6289 ASSERT( *ppObjectInfo == NULL);
6291 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6294 pParentObjectInfo = AFSFindObjectInfo( pVolume,
6295 &pObjectInfo->ParentFileId);
6296 if( pParentObjectInfo != NULL)
6299 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6301 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6302 AFS_OBJECT_REFERENCE_CHILD);
6304 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6305 AFS_TRACE_LEVEL_VERBOSE,
6306 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6310 AFSReleaseObjectInfo( &pParentObjectInfo);
6315 // Remove it from the tree and list if it was inserted
6318 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6321 AFSRemoveHashEntry( &pVolume->ObjectInfoTree.TreeHead,
6322 &pObjectInfo->TreeEntry);
6325 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6328 if( pObjectInfo->ListEntry.fLink == NULL)
6331 pVolume->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6333 if( pVolume->ObjectInfoListTail != NULL)
6336 pVolume->ObjectInfoListTail->ListEntry.fLink = NULL;
6342 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6345 if( pObjectInfo->ListEntry.bLink == NULL)
6348 pVolume->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6350 if( pVolume->ObjectInfoListHead != NULL)
6353 pVolume->ObjectInfoListHead->ListEntry.bLink = NULL;
6359 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6363 bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6368 FileId = pObjectInfo->FileId;
6371 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6373 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6375 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6377 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6379 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6383 if( bAcquiredTreeLock)
6386 AFSReleaseResource( pVolume->ObjectInfoTree.TreeLock);
6390 // Release the fid in the service
6396 AFSReleaseFid( &FileId);
6404 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6405 OUT AFSDirectoryCB **TargetDirEntry)
6408 NTSTATUS ntStatus = STATUS_SUCCESS;
6409 AFSDirEnumEntry *pDirEntry = NULL;
6410 UNICODE_STRING uniFullPathName = {0};
6411 AFSNameArrayHdr *pNameArray = NULL;
6412 AFSVolumeCB *pVolumeCB = NULL;
6413 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6414 AFSVolumeCB *pNewVolumeCB = NULL;
6415 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6416 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6417 AFSDirectoryCB *pNewParentDirEntry = NULL;
6418 WCHAR *pwchBuffer = NULL;
6419 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6420 ULONG ulNameDifference = 0;
6427 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6428 DirectoryCB->ObjectInformation,
6432 if( !NT_SUCCESS( ntStatus))
6434 try_return( ntStatus);
6438 // Retrieve a target name for the entry
6441 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6444 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6447 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6449 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6454 if( !NT_SUCCESS( ntStatus) ||
6455 pDirEntry->TargetNameLength == 0)
6458 if( pDirEntry != NULL)
6461 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6464 try_return( ntStatus);
6467 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6470 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6474 // Update the target name
6477 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6478 &DirectoryCB->Flags,
6479 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6480 (USHORT)pDirEntry->TargetNameLength);
6482 if( !NT_SUCCESS( ntStatus))
6485 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6487 try_return( ntStatus);
6491 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6495 // Need to pass the full path in for parsing.
6498 uniFullPathName.Length = 0;
6499 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6501 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6502 uniFullPathName.MaximumLength,
6503 AFS_NAME_BUFFER_EIGHT_TAG);
6505 if( uniFullPathName.Buffer == NULL)
6508 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6510 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6513 pwchBuffer = uniFullPathName.Buffer;
6515 RtlZeroMemory( uniFullPathName.Buffer,
6516 uniFullPathName.MaximumLength);
6518 RtlCopyMemory( uniFullPathName.Buffer,
6519 DirectoryCB->NameInformation.TargetName.Buffer,
6520 DirectoryCB->NameInformation.TargetName.Length);
6522 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6525 // This name should begin with the \afs server so parse it off and chech it
6528 FsRtlDissectName( uniFullPathName,
6532 if( RtlCompareUnicodeString( &uniComponentName,
6538 // Try evaluating the full path
6541 uniFullPathName.Buffer = pwchBuffer;
6543 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6545 uniFullPathName.MaximumLength = uniFullPathName.Length;
6550 uniFullPathName = uniRemainingPath;
6553 uniParsedName = uniFullPathName;
6555 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6557 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6563 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6566 if( pNameArray == NULL)
6569 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6572 pVolumeCB = AFSGlobalRoot;
6574 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6576 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
6578 lCount = AFSVolumeIncrement( pVolumeCB,
6579 VolumeReferenceReason);
6581 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6582 AFS_TRACE_LEVEL_VERBOSE,
6583 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
6585 VolumeReferenceReason,
6588 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6590 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6591 AFS_TRACE_LEVEL_VERBOSE,
6592 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6593 &pParentDirEntry->NameInformation.FileName,
6598 ntStatus = AFSLocateNameEntry( NULL,
6607 &VolumeReferenceReason,
6608 &pNewParentDirEntry,
6612 if ( pNewVolumeCB != NULL)
6615 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6616 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6617 // the reference on pVolumeCB that was held prior to the call.
6618 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6619 // will be released second.
6622 lCount = AFSVolumeDecrement( pVolumeCB,
6623 VolumeReferenceReason);
6625 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6626 AFS_TRACE_LEVEL_VERBOSE,
6627 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
6629 VolumeReferenceReason,
6632 pVolumeCB = pNewVolumeCB;
6634 pNewVolumeCB = NULL;
6636 VolumeReferenceReason = NewVolumeReferenceReason;
6638 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6642 // AFSLocateNameEntry does not alter the reference count of
6643 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6644 // a reference held.
6647 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6649 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6650 AFS_TRACE_LEVEL_VERBOSE,
6651 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
6652 &pParentDirEntry->NameInformation.FileName,
6656 pParentDirEntry = pNewParentDirEntry;
6658 pNewParentDirEntry = NULL;
6660 if( !NT_SUCCESS( ntStatus) ||
6661 ntStatus == STATUS_REPARSE)
6666 try_return( ntStatus);
6670 // Pass back the target dir entry for this request
6671 // The caller must release the DirOpenReferenceCount
6674 *TargetDirEntry = pDirectoryEntry;
6676 pDirectoryEntry = NULL;
6680 if( pDirectoryEntry != NULL)
6683 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6685 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6686 AFS_TRACE_LEVEL_VERBOSE,
6687 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6688 &pDirectoryEntry->NameInformation.FileName,
6693 ASSERT( lCount >= 0);
6696 if ( pParentDirEntry != NULL)
6699 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6701 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6702 AFS_TRACE_LEVEL_VERBOSE,
6703 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6704 &pParentDirEntry->NameInformation.FileName,
6709 ASSERT( lCount >= 0);
6712 if( pDirEntry != NULL)
6715 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6718 if( pVolumeCB != NULL)
6721 lCount = AFSVolumeDecrement( pVolumeCB,
6722 VolumeReferenceReason);
6724 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6725 AFS_TRACE_LEVEL_VERBOSE,
6726 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
6728 VolumeReferenceReason,
6732 if( pNameArray != NULL)
6735 AFSFreeNameArray( pNameArray);
6738 if( pwchBuffer != NULL)
6742 // Always free the buffer that we allocated as AFSLocateNameEntry
6743 // will not free it. If uniFullPathName.Buffer was allocated by
6744 // AFSLocateNameEntry, then we must free that as well.
6745 // Check that the uniFullPathName.Buffer in the string is not the same
6746 // offset by the length of the server name
6749 if( uniFullPathName.Length > 0 &&
6750 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6753 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6756 AFSExFreePoolWithTag( pwchBuffer, 0);
6764 AFSCleanupFcb( IN AFSFcb *Fcb,
6765 IN BOOLEAN ForceFlush)
6768 NTSTATUS ntStatus = STATUS_SUCCESS;
6769 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6770 LARGE_INTEGER liTime;
6771 IO_STATUS_BLOCK stIoStatus;
6776 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6778 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6780 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6783 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6784 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6787 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6788 AFS_TRACE_LEVEL_VERBOSE,
6789 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
6790 &Fcb->NPFcb->Resource,
6791 PsGetCurrentThread()));
6793 AFSAcquireShared( &Fcb->NPFcb->Resource,
6796 if( Fcb->OpenReferenceCount > 0)
6799 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6800 AFS_TRACE_LEVEL_VERBOSE,
6801 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
6802 &Fcb->NPFcb->SectionObjectResource,
6803 PsGetCurrentThread()));
6805 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
6811 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6816 if( !NT_SUCCESS( stIoStatus.Status))
6819 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6820 AFS_TRACE_LEVEL_ERROR,
6821 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6822 Fcb->ObjectInformation->FileId.Cell,
6823 Fcb->ObjectInformation->FileId.Volume,
6824 Fcb->ObjectInformation->FileId.Vnode,
6825 Fcb->ObjectInformation->FileId.Unique,
6827 stIoStatus.Information));
6829 ntStatus = stIoStatus.Status;
6832 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
6835 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6841 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6842 AFS_TRACE_LEVEL_WARNING,
6843 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
6844 Fcb->ObjectInformation->FileId.Cell,
6845 Fcb->ObjectInformation->FileId.Volume,
6846 Fcb->ObjectInformation->FileId.Vnode,
6847 Fcb->ObjectInformation->FileId.Unique));
6849 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6853 __except( EXCEPTION_EXECUTE_HANDLER)
6856 ntStatus = GetExceptionCode();
6860 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
6861 Fcb->ObjectInformation->FileId.Cell,
6862 Fcb->ObjectInformation->FileId.Volume,
6863 Fcb->ObjectInformation->FileId.Vnode,
6864 Fcb->ObjectInformation->FileId.Unique,
6867 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6870 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6871 AFS_TRACE_LEVEL_VERBOSE,
6872 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
6873 &Fcb->NPFcb->SectionObjectResource,
6874 PsGetCurrentThread()));
6876 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
6879 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6880 AFS_TRACE_LEVEL_VERBOSE,
6881 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
6882 &Fcb->NPFcb->Resource,
6883 PsGetCurrentThread()));
6885 AFSReleaseResource( &Fcb->NPFcb->Resource);
6888 // Wait for any currently running flush or release requests to complete
6891 AFSWaitOnQueuedFlushes( Fcb);
6894 // Now perform another flush on the file
6897 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6901 AFSReleaseExtentsWithFlush( Fcb,
6907 if( Fcb->OpenReferenceCount == 0 ||
6908 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6909 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6912 AFSTearDownFcbExtents( Fcb,
6916 try_return( ntStatus);
6919 KeQueryTickCount( &liTime);
6922 // First up are there dirty extents in the cache to flush?
6925 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6926 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6930 // The file has been marked as invalid. Dump it
6933 AFSTearDownFcbExtents( Fcb,
6936 else if( ForceFlush ||
6937 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
6938 Fcb->Specific.File.ExtentCount) &&
6939 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6940 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6942 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6944 Fcb->OpenReferenceCount == 0)
6947 AFSReleaseExtentsWithFlush( Fcb,
6954 // If there are extents and they haven't been used recently *and*
6955 // are not being used
6959 ( 0 != Fcb->Specific.File.ExtentCount &&
6960 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6961 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6962 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
6965 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6966 AFS_TRACE_LEVEL_VERBOSE,
6967 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
6968 &Fcb->NPFcb->SectionObjectResource,
6969 PsGetCurrentThread()));
6971 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
6977 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6982 if( !NT_SUCCESS( stIoStatus.Status))
6985 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6986 AFS_TRACE_LEVEL_ERROR,
6987 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6988 Fcb->ObjectInformation->FileId.Cell,
6989 Fcb->ObjectInformation->FileId.Volume,
6990 Fcb->ObjectInformation->FileId.Vnode,
6991 Fcb->ObjectInformation->FileId.Unique,
6993 stIoStatus.Information));
6995 ntStatus = stIoStatus.Status;
6999 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7002 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7008 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7009 AFS_TRACE_LEVEL_WARNING,
7010 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7011 Fcb->ObjectInformation->FileId.Cell,
7012 Fcb->ObjectInformation->FileId.Volume,
7013 Fcb->ObjectInformation->FileId.Vnode,
7014 Fcb->ObjectInformation->FileId.Unique));
7016 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7020 __except( EXCEPTION_EXECUTE_HANDLER)
7023 ntStatus = GetExceptionCode();
7027 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7028 Fcb->ObjectInformation->FileId.Cell,
7029 Fcb->ObjectInformation->FileId.Volume,
7030 Fcb->ObjectInformation->FileId.Vnode,
7031 Fcb->ObjectInformation->FileId.Unique,
7035 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7036 AFS_TRACE_LEVEL_VERBOSE,
7037 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7038 &Fcb->NPFcb->SectionObjectResource,
7039 PsGetCurrentThread()));
7041 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7043 if( Fcb->OpenReferenceCount <= 0)
7047 // Tear em down we'll not be needing them again
7050 AFSTearDownFcbExtents( Fcb,
7057 ntStatus = STATUS_RETRY;
7070 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7071 IN UNICODE_STRING *NewFileName)
7074 NTSTATUS ntStatus = STATUS_SUCCESS;
7075 WCHAR *pTmpBuffer = NULL;
7080 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7083 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7086 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7088 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7090 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7094 // OK, we need to allocate a new name buffer
7097 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7098 NewFileName->Length,
7099 AFS_NAME_BUFFER_NINE_TAG);
7101 if( pTmpBuffer == NULL)
7104 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7107 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7109 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7111 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7114 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7116 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7117 NewFileName->Buffer,
7118 NewFileName->Length);
7129 AFSReadCacheFile( IN void *ReadBuffer,
7130 IN LARGE_INTEGER *ReadOffset,
7131 IN ULONG RequestedDataLength,
7132 IN OUT PULONG BytesRead)
7135 NTSTATUS ntStatus = STATUS_SUCCESS;
7138 PIO_STACK_LOCATION pIoStackLocation = NULL;
7139 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7140 FILE_OBJECT *pCacheFileObject = NULL;
7145 pCacheFileObject = AFSReferenceCacheFileObject();
7147 if( pCacheFileObject == NULL)
7149 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7152 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7155 // Initialize the event
7158 KeInitializeEvent( &kEvent,
7159 SynchronizationEvent,
7163 // Allocate an irp for this request. This could also come from a
7164 // private pool, for instance.
7167 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7173 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7177 // Build the IRP's main body
7180 pIrp->UserBuffer = ReadBuffer;
7182 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7183 pIrp->RequestorMode = KernelMode;
7184 pIrp->Flags |= IRP_READ_OPERATION;
7187 // Set up the I/O stack location.
7190 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7191 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7192 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7193 pIoStackLocation->FileObject = pCacheFileObject;
7194 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7196 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7199 // Set the completion routine.
7202 IoSetCompletionRoutine( pIrp,
7210 // Send it to the FSD
7213 ntStatus = IoCallDriver( pTargetDeviceObject,
7216 if( NT_SUCCESS( ntStatus))
7223 ntStatus = KeWaitForSingleObject( &kEvent,
7229 if( NT_SUCCESS( ntStatus))
7232 ntStatus = pIrp->IoStatus.Status;
7234 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7240 if( pCacheFileObject != NULL)
7242 AFSReleaseCacheFileObject( pCacheFileObject);
7248 if( pIrp->MdlAddress != NULL)
7251 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7254 MmUnlockPages( pIrp->MdlAddress);
7257 IoFreeMdl( pIrp->MdlAddress);
7260 pIrp->MdlAddress = NULL;
7274 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7279 UNREFERENCED_PARAMETER(Irp);
7280 UNREFERENCED_PARAMETER(DeviceObject);
7281 KEVENT *pEvent = (KEVENT *)Context;
7287 return STATUS_MORE_PROCESSING_REQUIRED;
7291 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7294 BOOLEAN bIsEmpty = FALSE;
7295 AFSDirectoryCB *pDirEntry = NULL;
7300 ASSERT( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY);
7302 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7307 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7310 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7312 while( pDirEntry != NULL)
7315 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7316 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7324 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7329 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7336 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7337 IN AFSDirectoryCB *DirEntry)
7340 NTSTATUS ntStatus = STATUS_SUCCESS;
7345 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7348 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7349 AFS_TRACE_LEVEL_VERBOSE,
7350 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7352 &DirEntry->NameInformation.FileName));
7354 try_return( ntStatus);
7357 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7360 // Remove the entry from the parent tree
7363 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7364 AFS_TRACE_LEVEL_VERBOSE,
7365 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7367 &DirEntry->NameInformation.FileName));
7369 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7372 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7373 AFS_TRACE_LEVEL_VERBOSE,
7374 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7376 &DirEntry->NameInformation.FileName));
7378 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7381 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7385 // From the short name tree
7388 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7389 AFS_TRACE_LEVEL_VERBOSE,
7390 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7392 &DirEntry->NameInformation.FileName));
7394 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7397 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7400 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7401 AFS_TRACE_LEVEL_VERBOSE,
7402 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7404 &DirEntry->NameInformation.FileName));
7406 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7408 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7419 AFSGetAuthenticationId()
7422 LARGE_INTEGER liAuthId = {0,0};
7423 NTSTATUS ntStatus = STATUS_SUCCESS;
7424 PACCESS_TOKEN hToken = NULL;
7425 PTOKEN_STATISTICS pTokenInfo = NULL;
7426 BOOLEAN bCopyOnOpen = FALSE;
7427 BOOLEAN bEffectiveOnly = FALSE;
7428 BOOLEAN bPrimaryToken = FALSE;
7429 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7434 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7437 &stImpersonationLevel);
7442 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7447 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7448 AFS_TRACE_LEVEL_ERROR,
7449 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
7451 try_return( ntStatus);
7454 bPrimaryToken = TRUE;
7457 ntStatus = SeQueryInformationToken( hToken,
7459 (PVOID *)&pTokenInfo);
7461 if( !NT_SUCCESS( ntStatus))
7464 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7465 AFS_TRACE_LEVEL_ERROR,
7466 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
7469 try_return( ntStatus);
7472 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7473 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7475 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7476 AFS_TRACE_LEVEL_VERBOSE,
7477 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7478 liAuthId.QuadPart));
7488 PsDereferenceImpersonationToken( hToken);
7493 PsDereferencePrimaryToken( hToken);
7497 if( pTokenInfo != NULL)
7500 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7508 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7512 UNREFERENCED_PARAMETER(Fcb);
7513 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7515 Fcb->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7518 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7520 Fcb->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7523 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7525 Fcb->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7528 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7530 Fcb->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7533 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7535 Fcb->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7542 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7545 BOOLEAN bIsValid = TRUE;
7547 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7549 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7551 while( pCurrentDirEntry != NULL)
7554 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7558 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7563 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7564 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7567 if( pDirEntry == NULL)
7574 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7577 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
7580 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7582 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7584 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7593 AFSReferenceCacheFileObject()
7596 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7597 FILE_OBJECT *pCacheFileObject = NULL;
7599 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7602 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7604 if( pCacheFileObject != NULL)
7606 ObReferenceObject( pCacheFileObject);
7609 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7611 return pCacheFileObject;
7615 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7618 ASSERT( CacheFileObject != NULL);
7620 ObDereferenceObject( CacheFileObject);
7626 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7629 NTSTATUS ntStatus = STATUS_SUCCESS;
7630 AFSDeviceExt *pControlDevExt = NULL;
7631 ULONG ulTimeIncrement = 0;
7637 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7639 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7641 AFSServerName = LibraryInit->AFSServerName;
7643 AFSMountRootName = LibraryInit->AFSMountRootName;
7645 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7648 // Callbacks in the framework
7651 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7653 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7655 AFSDebugTraceFnc = AFSDbgLogMsg;
7657 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7659 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7661 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
7663 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7665 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7667 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7669 if( LibraryInit->AFSCacheBaseAddress != NULL)
7672 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7674 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7676 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7680 // Initialize some flush parameters
7683 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7685 ulTimeIncrement = KeQueryTimeIncrement();
7687 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7688 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7689 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7690 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7691 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7694 // Initialize the global root entry
7697 ntStatus = AFSInitVolume( NULL,
7698 &LibraryInit->GlobalRootFid,
7699 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
7702 if( !NT_SUCCESS( ntStatus))
7705 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7706 AFS_TRACE_LEVEL_ERROR,
7707 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7710 try_return( ntStatus);
7713 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7716 if( !NT_SUCCESS( ntStatus))
7719 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7720 AFS_TRACE_LEVEL_ERROR,
7721 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7724 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7725 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7727 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7728 AFS_TRACE_LEVEL_VERBOSE,
7729 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7733 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7735 try_return( ntStatus);
7739 // Update the node type code to AFS_ROOT_ALL
7742 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7744 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7747 // Invalidate all known volumes since contact with the service and therefore
7748 // the file server was lost.
7751 AFSInvalidateAllVolumes();
7754 // Drop the locks acquired above
7757 AFSInitVolumeWorker( AFSGlobalRoot);
7759 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7760 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7762 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7763 AFS_TRACE_LEVEL_VERBOSE,
7764 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7768 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7770 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7784 NTSTATUS ntStatus = STATUS_SUCCESS;
7785 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7791 if( AFSGlobalDotDirEntry != NULL)
7794 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
7795 AFS_OBJECT_REFERENCE_GLOBAL);
7797 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7798 AFS_TRACE_LEVEL_VERBOSE,
7799 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7800 AFSGlobalDotDirEntry->ObjectInformation,
7806 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
7809 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7811 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7813 ExFreePool( AFSGlobalDotDirEntry);
7815 AFSGlobalDotDirEntry = NULL;
7818 if( AFSGlobalDotDotDirEntry != NULL)
7821 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
7822 AFS_OBJECT_REFERENCE_GLOBAL);
7824 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7825 AFS_TRACE_LEVEL_VERBOSE,
7826 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7827 AFSGlobalDotDotDirEntry->ObjectInformation,
7833 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
7836 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7838 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7840 ExFreePool( AFSGlobalDotDotDirEntry);
7842 AFSGlobalDotDotDirEntry = NULL;
7845 if( AFSSpecialShareNames != NULL)
7848 pDirNode = AFSSpecialShareNames;
7850 while( pDirNode != NULL)
7853 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7855 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
7856 AFS_OBJECT_REFERENCE_GLOBAL);
7858 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7859 AFS_TRACE_LEVEL_VERBOSE,
7860 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7861 pDirNode->ObjectInformation,
7867 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
7870 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7872 ExFreePool( pDirNode->NonPaged);
7874 ExFreePool( pDirNode);
7876 pDirNode = pLastDirNode;
7879 AFSSpecialShareNames = NULL;
7887 AFSDefaultLogMsg( IN ULONG Subsystem,
7893 UNREFERENCED_PARAMETER(Subsystem);
7894 UNREFERENCED_PARAMETER(Level);
7895 NTSTATUS ntStatus = STATUS_SUCCESS;
7897 char chDebugBuffer[ 256];
7902 va_start( va_args, Format);
7904 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7909 if( NT_SUCCESS( ntStatus))
7911 DbgPrint( chDebugBuffer);
7921 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7922 IN ULONG InputBufferLength,
7923 IN AFSStatusInfoCB *StatusInfo,
7924 OUT ULONG *ReturnLength)
7927 NTSTATUS ntStatus = STATUS_SUCCESS;
7928 AFSVolumeCB *pVolumeCB = NULL;
7929 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7930 AFSVolumeCB *pNewVolumeCB = NULL;
7931 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7932 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7933 AFSObjectInfoCB *pObjectInfo = NULL;
7934 ULONGLONG ullIndex = 0;
7935 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7936 AFSNameArrayHdr *pNameArray = NULL;
7937 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7938 AFSDirectoryCB *pNewParentDirEntry = NULL;
7945 // If we are given a FID then look up the entry by that, otherwise
7949 if( GetStatusInfo->FileID.Cell != 0 &&
7950 GetStatusInfo->FileID.Volume != 0 &&
7951 GetStatusInfo->FileID.Vnode != 0 &&
7952 GetStatusInfo->FileID.Unique != 0)
7955 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7958 // Locate the volume node
7961 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7963 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7965 (AFSBTreeEntry **)&pVolumeCB);
7967 if( pVolumeCB != NULL)
7970 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
7972 lCount = AFSVolumeIncrement( pVolumeCB,
7973 VolumeReferenceReason);
7975 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7976 AFS_TRACE_LEVEL_VERBOSE,
7977 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
7979 VolumeReferenceReason,
7983 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7985 if( !NT_SUCCESS( ntStatus) ||
7988 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7991 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
7994 pObjectInfo = &pVolumeCB->ObjectInformation;
7996 lCount = AFSObjectInfoIncrement( pObjectInfo,
7997 AFS_OBJECT_REFERENCE_STATUS);
7999 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8000 AFS_TRACE_LEVEL_VERBOSE,
8001 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8008 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8011 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8013 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8015 (AFSBTreeEntry **)&pObjectInfo);
8017 if( pObjectInfo != NULL)
8021 // Reference the node so it won't be torn down
8024 lCount = AFSObjectInfoIncrement( pObjectInfo,
8025 AFS_OBJECT_REFERENCE_STATUS);
8027 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8028 AFS_TRACE_LEVEL_VERBOSE,
8029 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8034 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8036 if( !NT_SUCCESS( ntStatus) ||
8037 pObjectInfo == NULL)
8039 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8046 if( GetStatusInfo->FileNameLength == 0 ||
8047 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8049 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8052 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8053 uniFullPathName.MaximumLength = uniFullPathName.Length;
8055 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8058 // This name should begin with the \afs server so parse it off and check it
8061 FsRtlDissectName( uniFullPathName,
8065 if( RtlCompareUnicodeString( &uniComponentName,
8069 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8070 AFS_TRACE_LEVEL_ERROR,
8071 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8074 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8077 uniFullPathName = uniRemainingPath;
8079 uniParsedName = uniFullPathName;
8085 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8088 if( pNameArray == NULL)
8090 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8093 pVolumeCB = AFSGlobalRoot;
8095 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8098 // Increment the ref count on the volume and dir entry for correct processing below
8101 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8103 lCount = AFSVolumeIncrement( pVolumeCB,
8104 VolumeReferenceReason);
8106 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8107 AFS_TRACE_LEVEL_VERBOSE,
8108 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8110 VolumeReferenceReason,
8113 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8115 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8116 AFS_TRACE_LEVEL_VERBOSE,
8117 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8118 &pParentDirEntry->NameInformation.FileName,
8123 ntStatus = AFSLocateNameEntry( NULL,
8128 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8129 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8133 &NewVolumeReferenceReason,
8134 &pNewParentDirEntry,
8138 if ( pNewVolumeCB != NULL)
8142 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8143 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8144 // the reference on pVolumeCB that was held prior to the call.
8145 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8146 // will be released second.
8149 lCount = AFSVolumeDecrement( pVolumeCB,
8150 VolumeReferenceReason);
8152 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8153 AFS_TRACE_LEVEL_VERBOSE,
8154 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8156 VolumeReferenceReason,
8159 pVolumeCB = pNewVolumeCB;
8161 pNewVolumeCB = NULL;
8163 VolumeReferenceReason = NewVolumeReferenceReason;
8165 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8169 // AFSLocateNameEntry does not alter the reference count of
8170 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8171 // a reference held.
8174 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8176 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8177 AFS_TRACE_LEVEL_VERBOSE,
8178 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8179 &pParentDirEntry->NameInformation.FileName,
8183 pParentDirEntry = pNewParentDirEntry;
8185 pNewParentDirEntry = NULL;
8187 if( !NT_SUCCESS( ntStatus) ||
8188 ntStatus == STATUS_REPARSE)
8193 try_return( ntStatus);
8196 pObjectInfo = pDirectoryEntry->ObjectInformation;
8198 lCount = AFSObjectInfoIncrement( pObjectInfo,
8199 AFS_OBJECT_REFERENCE_STATUS);
8201 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8202 AFS_TRACE_LEVEL_VERBOSE,
8203 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8209 // At this point we have an object info block, return the information
8212 StatusInfo->FileId = pObjectInfo->FileId;
8214 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8216 StatusInfo->Expiration = pObjectInfo->Expiration;
8218 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8220 StatusInfo->FileType = pObjectInfo->FileType;
8222 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8224 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8226 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8228 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8230 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8232 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8234 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8236 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8238 StatusInfo->EaSize = pObjectInfo->EaSize;
8240 StatusInfo->Links = pObjectInfo->Links;
8243 // Return the information length
8246 *ReturnLength = sizeof( AFSStatusInfoCB);
8250 if( pDirectoryEntry != NULL)
8253 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8255 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8256 AFS_TRACE_LEVEL_VERBOSE,
8257 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8258 &pDirectoryEntry->NameInformation.FileName,
8263 ASSERT( lCount >= 0);
8266 if ( pParentDirEntry != NULL)
8269 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8271 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8272 AFS_TRACE_LEVEL_VERBOSE,
8273 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8274 &pParentDirEntry->NameInformation.FileName,
8279 ASSERT( lCount >= 0);
8282 if( pObjectInfo != NULL)
8285 lCount = AFSObjectInfoDecrement( pObjectInfo,
8286 AFS_OBJECT_REFERENCE_STATUS);
8288 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8289 AFS_TRACE_LEVEL_VERBOSE,
8290 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8295 if( pVolumeCB != NULL)
8298 lCount = AFSVolumeDecrement( pVolumeCB,
8299 VolumeReferenceReason);
8301 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8302 AFS_TRACE_LEVEL_VERBOSE,
8303 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8305 VolumeReferenceReason,
8309 if( pNameArray != NULL)
8312 AFSFreeNameArray( pNameArray);
8320 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8321 IN UNICODE_STRING *ComponentName)
8324 NTSTATUS ntStatus = STATUS_SUCCESS;
8325 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8326 AFSDirectoryCB *pDirEntry = NULL;
8334 // Search for the entry in the parent
8337 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8338 AFS_TRACE_LEVEL_VERBOSE_2,
8339 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8342 ulCRC = AFSGenerateCRC( ComponentName,
8345 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8348 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8352 if( pDirEntry == NULL)
8356 // Missed so perform a case insensitive lookup
8359 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8360 AFS_TRACE_LEVEL_VERBOSE_2,
8361 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8364 ulCRC = AFSGenerateCRC( ComponentName,
8367 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8371 if( pDirEntry == NULL)
8375 // OK, if this component is a valid short name then try
8376 // a lookup in the short name tree
8379 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8380 RtlIsNameLegalDOS8Dot3( ComponentName,
8385 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8386 AFS_TRACE_LEVEL_VERBOSE_2,
8387 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8390 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8397 if( pDirEntry != NULL)
8399 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8401 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8402 AFS_TRACE_LEVEL_VERBOSE,
8403 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8404 &pDirEntry->NameInformation.FileName,
8409 ASSERT( lCount >= 0);
8412 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8414 if( pDirEntry == NULL)
8417 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8418 AFS_TRACE_LEVEL_VERBOSE_2,
8419 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8421 STATUS_OBJECT_NAME_NOT_FOUND));
8423 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8427 // We have the symlink object but previously failed to process it so return access
8431 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8432 AFS_TRACE_LEVEL_VERBOSE_2,
8433 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8436 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8438 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8440 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8441 AFS_TRACE_LEVEL_VERBOSE,
8442 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8443 &pDirEntry->NameInformation.FileName,
8448 ASSERT( lCount >= 0);
8459 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8460 OUT UNICODE_STRING *ComponentName)
8463 NTSTATUS ntStatus = STATUS_SUCCESS;
8464 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8466 uniFullPathName = *FullPathName;
8471 FsRtlDissectName( uniFullPathName,
8475 if( uniRemainingPath.Length == 0)
8480 uniFullPathName = uniRemainingPath;
8483 if( uniComponentName.Length > 0)
8485 *ComponentName = uniComponentName;
8492 AFSDumpTraceFiles_Default()
8498 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8501 BOOLEAN bIsValidName = TRUE;
8507 while( usIndex < FileName->Length/sizeof( WCHAR))
8510 if( FileName->Buffer[ usIndex] == L':' ||
8511 FileName->Buffer[ usIndex] == L'*' ||
8512 FileName->Buffer[ usIndex] == L'?' ||
8513 FileName->Buffer[ usIndex] == L'"' ||
8514 FileName->Buffer[ usIndex] == L'<' ||
8515 FileName->Buffer[ usIndex] == L'>')
8517 bIsValidName = FALSE;
8525 return bIsValidName;
8529 AFSCreateDefaultSecurityDescriptor()
8532 NTSTATUS ntStatus = STATUS_SUCCESS;
8534 ULONG ulSACLSize = 0;
8535 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8536 ULONG ulACESize = 0;
8537 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8538 ULONG ulSDLength = 0;
8539 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8540 PSID pWorldSID = NULL;
8541 ULONG *pulSubAuthority = NULL;
8542 ULONG ulWorldSIDLEngth = 0;
8547 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8549 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8551 AFS_GENERIC_MEMORY_29_TAG);
8553 if( pWorldSID == NULL)
8555 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8557 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8560 RtlZeroMemory( pWorldSID,
8563 RtlInitializeSid( pWorldSID,
8564 &SeWorldSidAuthority,
8567 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8568 *pulSubAuthority = SECURITY_WORLD_RID;
8570 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8573 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8578 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8580 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8582 AFS_GENERIC_MEMORY_29_TAG);
8587 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8589 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8592 RtlZeroMemory( pACE,
8595 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8596 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8597 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8598 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8600 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8602 SeExports->SeLowMandatorySid);
8604 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8605 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8607 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8609 AFS_GENERIC_MEMORY_29_TAG);
8614 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8616 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8619 ntStatus = RtlCreateAcl( pSACL,
8623 if( !NT_SUCCESS( ntStatus))
8626 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8629 try_return( ntStatus);
8632 ntStatus = RtlAddAce( pSACL,
8636 pACE->Header.AceSize);
8638 if( !NT_SUCCESS( ntStatus))
8641 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8644 try_return( ntStatus);
8648 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8649 sizeof( SECURITY_DESCRIPTOR),
8650 AFS_GENERIC_MEMORY_27_TAG);
8652 if( pSecurityDescr == NULL)
8655 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8657 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8660 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8661 SECURITY_DESCRIPTOR_REVISION);
8663 if( !NT_SUCCESS( ntStatus))
8666 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8669 try_return( ntStatus);
8672 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8674 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8679 if( !NT_SUCCESS( ntStatus))
8682 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8685 try_return( ntStatus);
8690 // Add in the group and owner to the SD
8693 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8695 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8699 if( !NT_SUCCESS( ntStatus))
8702 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8705 try_return( ntStatus);
8709 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8713 if( !NT_SUCCESS( ntStatus))
8716 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8719 try_return( ntStatus);
8722 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8725 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8727 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8730 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8732 AFS_GENERIC_MEMORY_27_TAG);
8734 if( pRelativeSecurityDescr == NULL)
8737 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8739 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8742 ulSDLength = PAGE_SIZE;
8744 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8745 pRelativeSecurityDescr,
8748 if( !NT_SUCCESS( ntStatus))
8751 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8754 try_return( ntStatus);
8757 AFSDefaultSD = pRelativeSecurityDescr;
8761 if( !NT_SUCCESS( ntStatus))
8764 if( pRelativeSecurityDescr != NULL)
8766 ExFreePool( pRelativeSecurityDescr);
8770 if( pSecurityDescr != NULL)
8772 ExFreePool( pSecurityDescr);
8785 if( pWorldSID != NULL)
8787 ExFreePool( pWorldSID);
8795 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8796 OUT UNICODE_STRING *ParentPath)
8799 *ParentPath = *FullFileName;
8802 // If the final character is a \, jump over it
8805 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8807 ParentPath->Length -= sizeof( WCHAR);
8810 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8812 ParentPath->Length -= sizeof( WCHAR);
8816 // And the separator
8819 ParentPath->Length -= sizeof( WCHAR);
8825 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8826 IN AFSObjectInfoCB *ObjectInfo,
8827 IN BOOLEAN WriteAccess,
8828 OUT GUID *AuthGroup)
8831 NTSTATUS ntStatus = STATUS_SUCCESS;
8832 GUID stAuthGroup, stZeroAuthGroup;
8833 BOOLEAN bFoundAuthGroup = FALSE;
8834 AFSCcb *pCcb = NULL;
8840 RtlZeroMemory( &stAuthGroup,
8843 RtlZeroMemory( &stZeroAuthGroup,
8849 if( ObjectInfo != NULL &&
8850 ObjectInfo->Fcb != NULL)
8852 pFcb = ObjectInfo->Fcb;
8859 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8862 pCcb = Fcb->CcbListHead;
8864 while( pCcb != NULL)
8868 pCcb->GrantedAccess & FILE_WRITE_DATA)
8870 RtlCopyMemory( &stAuthGroup,
8874 bFoundAuthGroup = TRUE;
8878 else if( pCcb->GrantedAccess & FILE_READ_DATA)
8881 // At least get the read-only access
8884 RtlCopyMemory( &stAuthGroup,
8888 bFoundAuthGroup = TRUE;
8891 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
8894 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
8897 if( !bFoundAuthGroup)
8900 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
8901 (ULONGLONG)PsGetCurrentThreadId(),
8904 if( RtlCompareMemory( &stZeroAuthGroup,
8906 sizeof( GUID)) == sizeof( GUID))
8909 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
8911 try_return( ntStatus = STATUS_ACCESS_DENIED);
8915 RtlCopyMemory( AuthGroup,
8928 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
8929 IN ULONG InvalidateReason)
8932 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8933 NTSTATUS ntStatus = STATUS_SUCCESS;
8936 ULONG ulProcessCount = 0;
8943 switch( InvalidateReason)
8946 case AFS_INVALIDATE_DELETED:
8949 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8950 ObjectInfo->Fcb != NULL)
8953 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
8956 ObjectInfo->Links = 0;
8958 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
8960 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
8965 // Clear out the extents
8966 // And get rid of them (note this involves waiting
8967 // for any writes or reads to the cache to complete)
8970 AFSTearDownFcbExtents( ObjectInfo->Fcb,
8973 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
8979 case AFS_INVALIDATE_DATA_VERSION:
8982 LARGE_INTEGER liCurrentOffset = {0,0};
8983 LARGE_INTEGER liFlushLength = {0,0};
8984 ULONG ulFlushLength = 0;
8985 BOOLEAN bLocked = FALSE;
8986 BOOLEAN bExtentsLocked = FALSE;
8987 BOOLEAN bCleanExtents = FALSE;
8989 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8990 ObjectInfo->Fcb != NULL)
8993 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
8998 if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
9001 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9002 AFS_TRACE_LEVEL_VERBOSE,
9003 "AFSPerformObjectInvalidation DirectIO Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9004 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9005 PsGetCurrentThread()));
9007 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9010 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9017 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9018 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9024 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9025 AFS_TRACE_LEVEL_WARNING,
9026 "AFSPerformObjectInvalidation DirectIO CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9027 ObjectInfo->FileId.Cell,
9028 ObjectInfo->FileId.Volume,
9029 ObjectInfo->FileId.Vnode,
9030 ObjectInfo->FileId.Unique));
9032 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9037 bCleanExtents = TRUE;
9040 __except( EXCEPTION_EXECUTE_HANDLER)
9043 ntStatus = GetExceptionCode();
9047 "EXCEPTION - AFSPerformObjectInvalidation DirectIO FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9048 ObjectInfo->FileId.Cell,
9049 ObjectInfo->FileId.Volume,
9050 ObjectInfo->FileId.Vnode,
9051 ObjectInfo->FileId.Unique,
9054 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9057 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9058 AFS_TRACE_LEVEL_VERBOSE,
9059 "AFSPerformObjectInvalidation DirectIO Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9060 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9061 PsGetCurrentThread()));
9063 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9068 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9069 AFS_TRACE_LEVEL_VERBOSE,
9070 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9071 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9072 PsGetCurrentThread()));
9074 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9077 bExtentsLocked = TRUE;
9080 // There are several possibilities here:
9082 // 0. If there are no extents or all of the extents are dirty, do nothing.
9084 // 1. There could be nothing dirty and an open reference count of zero
9085 // in which case we can just tear down all of the extents without
9086 // holding any resources.
9088 // 2. There could be nothing dirty and a non-zero open reference count
9089 // in which case we can issue a CcPurge against the entire file
9090 // while holding just the Fcb Resource.
9092 // 3. There can be dirty extents in which case we need to identify
9093 // the non-dirty ranges and then perform a CcPurge on just the
9094 // non-dirty ranges while holding just the Fcb Resource.
9097 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9100 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9103 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9105 bExtentsLocked = FALSE;
9107 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9110 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9114 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9120 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9121 AFS_TRACE_LEVEL_VERBOSE,
9122 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9123 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9124 PsGetCurrentThread()));
9126 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9129 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9136 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9137 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9143 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9144 AFS_TRACE_LEVEL_WARNING,
9145 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9146 ObjectInfo->FileId.Cell,
9147 ObjectInfo->FileId.Volume,
9148 ObjectInfo->FileId.Vnode,
9149 ObjectInfo->FileId.Unique));
9151 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9156 bCleanExtents = TRUE;
9159 __except( EXCEPTION_EXECUTE_HANDLER)
9162 ntStatus = GetExceptionCode();
9166 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9167 ObjectInfo->FileId.Cell,
9168 ObjectInfo->FileId.Volume,
9169 ObjectInfo->FileId.Vnode,
9170 ObjectInfo->FileId.Unique,
9173 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9176 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9177 AFS_TRACE_LEVEL_VERBOSE,
9178 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9179 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9180 PsGetCurrentThread()));
9182 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9188 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9190 bExtentsLocked = FALSE;
9192 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9193 AFS_TRACE_LEVEL_VERBOSE,
9194 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9195 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9196 PsGetCurrentThread()));
9198 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9201 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9206 // Must build a list of non-dirty ranges from the beginning of the file
9207 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9208 // ranges. In all but the most extreme random data write scenario there will
9209 // be significantly fewer.
9211 // For each range we need offset and size.
9214 AFSByteRange * ByteRangeList = NULL;
9215 ULONG ulByteRangeCount = 0;
9217 BOOLEAN bPurgeOnClose = FALSE;
9222 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9225 if ( ByteRangeList != NULL ||
9226 ulByteRangeCount == 0)
9229 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9236 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9238 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9239 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9240 &ByteRangeList[ulIndex].FileOffset,
9245 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9246 AFS_TRACE_LEVEL_WARNING,
9247 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9248 ObjectInfo->FileId.Cell,
9249 ObjectInfo->FileId.Volume,
9250 ObjectInfo->FileId.Vnode,
9251 ObjectInfo->FileId.Unique));
9253 bPurgeOnClose = TRUE;
9258 bCleanExtents = TRUE;
9261 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9263 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9265 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9272 // We couldn't allocate the memory to build the purge list
9273 // so just walk the extent list while holding the ExtentsList Resource.
9274 // This could deadlock but we do not have much choice.
9277 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9279 bExtentsLocked = TRUE;
9281 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9285 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9289 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9291 while( ulProcessCount < ulCount)
9293 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9295 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9297 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9298 &pEntry->FileOffset,
9303 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9304 AFS_TRACE_LEVEL_WARNING,
9305 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9306 ObjectInfo->FileId.Cell,
9307 ObjectInfo->FileId.Volume,
9308 ObjectInfo->FileId.Vnode,
9309 ObjectInfo->FileId.Unique));
9311 bPurgeOnClose = TRUE;
9316 bCleanExtents = TRUE;
9320 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9323 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9325 while( liFlushLength.QuadPart > 0)
9328 if( liFlushLength.QuadPart > 512 * 1024000)
9330 ulFlushLength = 512 * 1024000;
9334 ulFlushLength = liFlushLength.LowPart;
9337 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9343 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9344 AFS_TRACE_LEVEL_WARNING,
9345 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9346 ObjectInfo->FileId.Cell,
9347 ObjectInfo->FileId.Volume,
9348 ObjectInfo->FileId.Vnode,
9349 ObjectInfo->FileId.Unique));
9351 bPurgeOnClose = TRUE;
9356 bCleanExtents = TRUE;
9359 liFlushLength.QuadPart -= ulFlushLength;
9363 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9371 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9377 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9378 AFS_TRACE_LEVEL_WARNING,
9379 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9380 ObjectInfo->FileId.Cell,
9381 ObjectInfo->FileId.Volume,
9382 ObjectInfo->FileId.Vnode,
9383 ObjectInfo->FileId.Unique));
9385 bPurgeOnClose = TRUE;
9390 bCleanExtents = TRUE;
9397 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9401 __except( EXCEPTION_EXECUTE_HANDLER)
9404 ntStatus = GetExceptionCode();
9408 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9409 ObjectInfo->FileId.Cell,
9410 ObjectInfo->FileId.Volume,
9411 ObjectInfo->FileId.Vnode,
9412 ObjectInfo->FileId.Unique,
9416 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9417 AFS_TRACE_LEVEL_VERBOSE,
9418 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9419 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9420 PsGetCurrentThread()));
9422 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9426 if ( bExtentsLocked)
9429 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9436 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9442 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9452 // Destroy the reference passed in by the caller to AFSInvalidateObject
9453 // or AFSQueueInvalidateObject
9456 lCount = AFSObjectInfoDecrement( ObjectInfo,
9457 AFS_OBJECT_REFERENCE_INVALIDATION);
9459 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9460 AFS_TRACE_LEVEL_VERBOSE,
9461 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",