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 AFSDeleteObjectInfo( &pObjectInfoCB);
694 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
695 AFS_TRACE_LEVEL_ERROR,
696 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n"));
698 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
701 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
702 AFS_TRACE_LEVEL_VERBOSE,
703 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocated %p\n",
706 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
707 sizeof( AFSNonPagedDirectoryCB),
708 AFS_DIR_ENTRY_NP_TAG);
710 if( pNonPagedDirEntry == NULL)
713 ExFreePool( pDirNode);
715 AFSDeleteObjectInfo( &pObjectInfoCB);
717 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
718 AFS_TRACE_LEVEL_ERROR,
719 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n"));
721 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
724 RtlZeroMemory( pDirNode,
727 RtlZeroMemory( pNonPagedDirEntry,
728 sizeof( AFSNonPagedDirectoryCB));
730 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
732 pDirNode->NonPaged = pNonPagedDirEntry;
734 pDirNode->ObjectInformation = pObjectInfoCB;
740 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
742 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
745 // Setup the names in the entry
748 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
750 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
752 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
754 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
757 // Populate the rest of the data
760 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
762 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
764 AFSGlobalDotDirEntry = pDirNode;
770 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
773 if( pObjectInfoCB == NULL)
776 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
777 AFS_TRACE_LEVEL_ERROR,
778 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
781 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
784 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
785 AFS_OBJECT_REFERENCE_GLOBAL);
787 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
788 AFS_TRACE_LEVEL_VERBOSE,
789 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
793 ntStatus = STATUS_SUCCESS;
795 ulEntryLength = sizeof( AFSDirectoryCB) +
796 ( 2 * sizeof( WCHAR));
798 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
802 if( pDirNode == NULL)
805 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
806 AFS_TRACE_LEVEL_ERROR,
807 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocation failure\n"));
809 AFSDeleteObjectInfo( &pObjectInfoCB);
811 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
814 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
815 AFS_TRACE_LEVEL_VERBOSE,
816 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocated %p\n",
819 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
820 sizeof( AFSNonPagedDirectoryCB),
821 AFS_DIR_ENTRY_NP_TAG);
823 if( pNonPagedDirEntry == NULL)
826 ExFreePool( pDirNode);
828 AFSDeleteObjectInfo( &pObjectInfoCB);
830 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
833 RtlZeroMemory( pDirNode,
836 RtlZeroMemory( pNonPagedDirEntry,
837 sizeof( AFSNonPagedDirectoryCB));
839 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
841 pDirNode->NonPaged = pNonPagedDirEntry;
843 pDirNode->ObjectInformation = pObjectInfoCB;
849 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
851 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
854 // Setup the names in the entry
857 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
859 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
861 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
863 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
865 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
868 // Populate the rest of the data
871 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
873 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
875 AFSGlobalDotDotDirEntry = pDirNode;
879 if( !NT_SUCCESS( ntStatus))
882 if( AFSGlobalDotDirEntry != NULL)
885 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
887 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
889 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
891 ExFreePool( AFSGlobalDotDirEntry);
893 AFSGlobalDotDirEntry = NULL;
896 if( AFSGlobalDotDotDirEntry != NULL)
899 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
901 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
903 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
905 ExFreePool( AFSGlobalDotDotDirEntry);
907 AFSGlobalDotDotDirEntry = NULL;
916 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
917 IN PUNICODE_STRING FileName,
918 IN PUNICODE_STRING TargetName,
919 IN AFSDirEnumEntry *DirEnumEntry,
923 AFSDirectoryCB *pDirNode = NULL;
924 NTSTATUS ntStatus = STATUS_SUCCESS;
925 ULONG ulEntryLength = 0;
926 AFSObjectInfoCB *pObjectInfoCB = NULL;
927 BOOLEAN bAllocatedObjectCB = FALSE;
928 ULONGLONG ullIndex = 0;
929 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
935 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
936 AFS_TRACE_LEVEL_VERBOSE,
937 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
939 ParentObjectInfo->FileId.Cell,
940 ParentObjectInfo->FileId.Volume,
941 ParentObjectInfo->FileId.Vnode,
942 ParentObjectInfo->FileId.Unique));
945 // First thing is to locate/create our object information block
949 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
952 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
954 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
956 (AFSBTreeEntry **)&pObjectInfoCB);
958 if( !NT_SUCCESS( ntStatus) ||
959 pObjectInfoCB == NULL)
963 // Allocate our object info cb
966 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
969 if( pObjectInfoCB == NULL)
972 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
974 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
977 bAllocatedObjectCB = TRUE;
979 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
980 AFS_TRACE_LEVEL_VERBOSE,
981 "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
987 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
988 AFS_OBJECT_REFERENCE_DIRENTRY);
990 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
991 AFS_TRACE_LEVEL_VERBOSE,
992 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
996 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
998 ntStatus = STATUS_SUCCESS;
1000 ulEntryLength = sizeof( AFSDirectoryCB) +
1003 if( TargetName != NULL)
1006 ulEntryLength += TargetName->Length;
1009 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1013 if( pDirNode == NULL)
1016 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1019 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1020 AFS_TRACE_LEVEL_VERBOSE,
1021 "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
1024 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1025 sizeof( AFSNonPagedDirectoryCB),
1026 AFS_DIR_ENTRY_NP_TAG);
1028 if( pNonPagedDirEntry == NULL)
1031 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1034 RtlZeroMemory( pDirNode,
1037 RtlZeroMemory( pNonPagedDirEntry,
1038 sizeof( AFSNonPagedDirectoryCB));
1040 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1042 pDirNode->NonPaged = pNonPagedDirEntry;
1044 pDirNode->ObjectInformation = pObjectInfoCB;
1047 // Set valid entry and NOT_IN_PARENT flag
1050 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1052 pDirNode->FileIndex = FileIndex;
1055 // Setup the names in the entry
1058 if( FileName->Length > 0)
1061 pDirNode->NameInformation.FileName.Length = FileName->Length;
1063 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1065 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1067 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1069 pDirNode->NameInformation.FileName.Length);
1072 // Create a CRC for the file
1075 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1078 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1082 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1083 AFS_TRACE_LEVEL_VERBOSE,
1084 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1087 ParentObjectInfo->FileId.Cell,
1088 ParentObjectInfo->FileId.Volume,
1089 ParentObjectInfo->FileId.Vnode,
1090 ParentObjectInfo->FileId.Unique));
1092 if( TargetName != NULL &&
1093 TargetName->Length > 0)
1096 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1098 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1100 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1101 sizeof( AFSDirectoryCB) +
1102 pDirNode->NameInformation.FileName.Length);
1104 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1106 pDirNode->NameInformation.TargetName.Length);
1110 // If we allocated the object information cb then update the information
1113 if( bAllocatedObjectCB)
1117 // Populate the rest of the data
1120 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1122 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1124 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1126 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1128 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1130 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1132 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1134 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1136 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1138 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1140 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1141 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1144 pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1147 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
1150 if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1153 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1158 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1162 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1165 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1166 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1170 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1171 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1172 pObjectInfoCB->TargetFileId.Unique == 0 &&
1173 pDirNode->NameInformation.TargetName.Length == 0)
1177 // This will ensure we perform a validation on the node
1180 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1183 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1186 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1191 // Object specific information
1194 pObjectInfoCB->Links = DirEnumEntry->Links;
1196 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1198 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1202 if( !NT_SUCCESS( ntStatus))
1205 if( pNonPagedDirEntry != NULL)
1208 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1210 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1213 if( pDirNode != NULL)
1216 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1217 AFS_TRACE_LEVEL_VERBOSE,
1218 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1221 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1227 // Dereference our object info block if we have one
1230 if( pObjectInfoCB != NULL)
1233 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1234 AFS_OBJECT_REFERENCE_DIRENTRY);
1236 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1237 AFS_TRACE_LEVEL_VERBOSE,
1238 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1242 if( bAllocatedObjectCB)
1245 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1247 AFSDeleteObjectInfo( &pObjectInfoCB);
1257 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1258 IN BOOLEAN DirectoryEntry)
1261 BOOLEAN bReturn = TRUE;
1262 ACCESS_MASK stAccessMask = 0;
1265 // Get rid of anything we don't know about
1268 DesiredAccess = (DesiredAccess &
1274 ACCESS_SYSTEM_SECURITY |
1278 FILE_READ_ATTRIBUTES |
1279 FILE_WRITE_ATTRIBUTES |
1280 FILE_LIST_DIRECTORY |
1286 // Our 'read only' access mask. These are the accesses we will
1287 // allow for a read only file
1290 stAccessMask = DELETE |
1295 ACCESS_SYSTEM_SECURITY |
1299 FILE_READ_ATTRIBUTES |
1300 FILE_WRITE_ATTRIBUTES |
1302 FILE_LIST_DIRECTORY |
1306 // For a directory, add in the directory specific accesses
1312 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1317 if( FlagOn( DesiredAccess, ~stAccessMask))
1321 // A write access is set ...
1331 AFSEvaluateNode( IN GUID *AuthGroup,
1332 IN AFSDirectoryCB *DirEntry)
1335 NTSTATUS ntStatus = STATUS_SUCCESS;
1336 AFSDirEnumEntry *pDirEntry = NULL;
1337 UNICODE_STRING uniTargetName;
1342 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1347 if( !NT_SUCCESS( ntStatus))
1350 try_return( ntStatus);
1353 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1355 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1357 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1359 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1361 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1363 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1365 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1367 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1369 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1371 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1373 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1375 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1376 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1379 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1382 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1385 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1388 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1393 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1397 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1399 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1402 // If we have a target name then see if it needs updating ...
1405 if( pDirEntry->TargetNameLength > 0)
1409 // Update the target name information if needed
1412 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1414 uniTargetName.MaximumLength = uniTargetName.Length;
1416 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1418 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1421 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1422 RtlCompareUnicodeString( &uniTargetName,
1423 &DirEntry->NameInformation.TargetName,
1428 // Update the target name
1431 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1433 uniTargetName.Buffer,
1434 uniTargetName.Length);
1436 if( !NT_SUCCESS( ntStatus))
1439 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1441 try_return( ntStatus);
1445 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1450 if( pDirEntry != NULL)
1453 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1461 AFSValidateSymLink( IN GUID *AuthGroup,
1462 IN AFSDirectoryCB *DirEntry)
1465 NTSTATUS ntStatus = STATUS_SUCCESS;
1466 AFSDirEnumEntry *pDirEntry = NULL;
1467 UNICODE_STRING uniTargetName;
1472 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1477 if( !NT_SUCCESS( ntStatus))
1480 try_return( ntStatus);
1483 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1484 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1487 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1488 AFS_TRACE_LEVEL_VERBOSE_2,
1489 "AFSValidateSymLink Invalid type Status %08lX\n",
1490 STATUS_OBJECT_NAME_NOT_FOUND));
1492 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1495 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1497 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1499 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1502 // Update the target name information if needed
1505 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1507 uniTargetName.MaximumLength = uniTargetName.Length;
1509 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1511 if( uniTargetName.Length > 0)
1514 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1517 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1518 RtlCompareUnicodeString( &uniTargetName,
1519 &DirEntry->NameInformation.TargetName,
1524 // Update the target name
1527 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1529 uniTargetName.Buffer,
1530 uniTargetName.Length);
1532 if( !NT_SUCCESS( ntStatus))
1535 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1537 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1541 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1545 // If the FileType is the same then nothing to do since it IS
1549 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1552 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1554 try_return( ntStatus = STATUS_SUCCESS);
1557 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1559 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1561 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1563 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1565 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1567 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1569 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1571 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1573 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1574 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1577 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1580 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1583 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1586 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1591 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1595 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1597 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1601 if( pDirEntry != NULL)
1604 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1612 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1616 NTSTATUS ntStatus = STATUS_SUCCESS;
1617 IO_STATUS_BLOCK stIoStatus;
1619 AFSObjectInfoCB * pParentObjectInfo = NULL;
1621 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1622 AFS_TRACE_LEVEL_VERBOSE,
1623 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1624 (*ppObjectInfo)->FileType,
1625 (*ppObjectInfo)->FileId.Cell,
1626 (*ppObjectInfo)->FileId.Volume,
1627 (*ppObjectInfo)->FileId.Vnode,
1628 (*ppObjectInfo)->FileId.Unique,
1631 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1634 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1635 &(*ppObjectInfo)->ParentFileId);
1638 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1639 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1640 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1643 // We only act on the mount point itself, not the target. If the
1644 // node has been deleted then mark it as such otherwise indicate
1645 // it requires verification
1648 if( Reason == AFS_INVALIDATE_DELETED)
1650 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1655 if( Reason == AFS_INVALIDATE_FLUSHED)
1658 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1660 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1663 (*ppObjectInfo)->Expiration.QuadPart = 0;
1665 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1667 (*ppObjectInfo)->TargetFileId.Unique = 0;
1669 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1670 AFS_TRACE_LEVEL_VERBOSE,
1671 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1672 (*ppObjectInfo)->FileId.Cell,
1673 (*ppObjectInfo)->FileId.Volume,
1674 (*ppObjectInfo)->FileId.Vnode,
1675 (*ppObjectInfo)->FileId.Unique));
1677 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1680 if ( pParentObjectInfo != NULL)
1683 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1685 if( Reason == AFS_INVALIDATE_CREDS)
1687 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1690 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1691 Reason == AFS_INVALIDATE_FLUSHED)
1693 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1697 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1700 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1703 FILE_ACTION_MODIFIED);
1706 try_return( ntStatus);
1710 // Depending on the reason for invalidation then perform work on the node
1716 case AFS_INVALIDATE_DELETED:
1720 // Mark this node as invalid
1723 (*ppObjectInfo)->Links = 0;
1725 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1727 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1728 AFS_TRACE_LEVEL_VERBOSE,
1729 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1730 (*ppObjectInfo)->FileId.Cell,
1731 (*ppObjectInfo)->FileId.Volume,
1732 (*ppObjectInfo)->FileId.Vnode,
1733 (*ppObjectInfo)->FileId.Unique));
1735 if( pParentObjectInfo != NULL)
1738 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1739 AFS_TRACE_LEVEL_VERBOSE,
1740 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1741 pParentObjectInfo->FileId.Cell,
1742 pParentObjectInfo->FileId.Volume,
1743 pParentObjectInfo->FileId.Vnode,
1744 pParentObjectInfo->FileId.Unique));
1746 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1748 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1750 pParentObjectInfo->Expiration.QuadPart = 0;
1752 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1754 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1758 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1761 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1764 FILE_ACTION_REMOVED);
1767 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1770 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1776 case AFS_INVALIDATE_FLUSHED:
1779 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1780 (*ppObjectInfo)->Fcb != NULL)
1783 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1784 AFS_TRACE_LEVEL_VERBOSE,
1785 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1786 (*ppObjectInfo)->FileId.Cell,
1787 (*ppObjectInfo)->FileId.Volume,
1788 (*ppObjectInfo)->FileId.Vnode,
1789 (*ppObjectInfo)->FileId.Unique));
1791 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1797 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1802 if( !NT_SUCCESS( stIoStatus.Status))
1805 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1806 AFS_TRACE_LEVEL_ERROR,
1807 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1808 (*ppObjectInfo)->FileId.Cell,
1809 (*ppObjectInfo)->FileId.Volume,
1810 (*ppObjectInfo)->FileId.Vnode,
1811 (*ppObjectInfo)->FileId.Unique,
1813 stIoStatus.Information));
1815 ntStatus = stIoStatus.Status;
1819 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1822 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1828 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1829 AFS_TRACE_LEVEL_WARNING,
1830 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1831 (*ppObjectInfo)->FileId.Cell,
1832 (*ppObjectInfo)->FileId.Volume,
1833 (*ppObjectInfo)->FileId.Vnode,
1834 (*ppObjectInfo)->FileId.Unique));
1836 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1840 __except( EXCEPTION_EXECUTE_HANDLER)
1843 ntStatus = GetExceptionCode();
1847 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1848 (*ppObjectInfo)->FileId.Cell,
1849 (*ppObjectInfo)->FileId.Volume,
1850 (*ppObjectInfo)->FileId.Vnode,
1851 (*ppObjectInfo)->FileId.Unique,
1854 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1857 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1860 // Clear out the extents
1861 // Get rid of them (note this involves waiting
1862 // for any writes or reads to the cache to complete)
1865 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1869 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1872 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1875 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1876 AFS_TRACE_LEVEL_VERBOSE,
1877 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1878 (*ppObjectInfo)->FileId.Cell,
1879 (*ppObjectInfo)->FileId.Volume,
1880 (*ppObjectInfo)->FileId.Vnode,
1881 (*ppObjectInfo)->FileId.Unique));
1883 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1886 // Fall through to the default processing
1892 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1894 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1898 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1901 if( Reason == AFS_INVALIDATE_CREDS)
1903 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1906 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1908 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1912 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1915 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1918 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1921 FILE_ACTION_MODIFIED);
1923 else if ( pParentObjectInfo != NULL)
1926 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1929 FILE_ACTION_MODIFIED);
1933 // Indicate this node requires re-evaluation for the remaining reasons
1936 (*ppObjectInfo)->Expiration.QuadPart = 0;
1938 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1939 AFS_TRACE_LEVEL_VERBOSE,
1940 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1941 (*ppObjectInfo)->FileId.Cell,
1942 (*ppObjectInfo)->FileId.Volume,
1943 (*ppObjectInfo)->FileId.Vnode,
1944 (*ppObjectInfo)->FileId.Unique));
1946 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1948 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1949 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1950 ( Reason == AFS_INVALIDATE_CALLBACK ||
1951 Reason == AFS_INVALIDATE_EXPIRED))
1953 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1954 AFS_INVALIDATE_DATA_VERSION)))
1957 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1967 if ( pParentObjectInfo != NULL)
1970 AFSReleaseObjectInfo( &pParentObjectInfo);
1977 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1980 NTSTATUS ntStatus = STATUS_SUCCESS;
1981 AFSVolumeCB *pVolumeCB = NULL;
1982 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1983 ULONGLONG ullIndex = 0;
1984 AFSObjectInfoCB *pObjectInfo = NULL;
1990 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1991 AFS_TRACE_LEVEL_VERBOSE,
1992 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1993 InvalidateCB->FileID.Cell,
1994 InvalidateCB->FileID.Volume,
1995 InvalidateCB->FileID.Vnode,
1996 InvalidateCB->FileID.Unique,
1997 InvalidateCB->FileType,
1998 InvalidateCB->WholeVolume,
1999 InvalidateCB->Reason));
2002 // Need to locate the Fcb for the directory to purge
2005 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2006 AFS_TRACE_LEVEL_VERBOSE,
2007 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2008 &pDevExt->Specific.RDR.VolumeTreeLock,
2009 PsGetCurrentThread()));
2012 // Starve any exclusive waiters on this paticular call
2015 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2018 // Locate the volume node
2021 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2023 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2025 (AFSBTreeEntry **)&pVolumeCB);
2027 if( pVolumeCB != NULL)
2030 lCount = AFSVolumeIncrement( pVolumeCB,
2031 AFS_VOLUME_REFERENCE_INVALIDATE);
2033 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2034 AFS_TRACE_LEVEL_VERBOSE,
2035 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2040 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2042 if( !NT_SUCCESS( ntStatus) ||
2046 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2047 AFS_TRACE_LEVEL_WARNING,
2048 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2049 InvalidateCB->FileID.Cell,
2050 InvalidateCB->FileID.Volume,
2051 InvalidateCB->FileID.Vnode,
2052 InvalidateCB->FileID.Unique,
2055 try_return( ntStatus = STATUS_SUCCESS);
2059 // If this is a whole volume invalidation then go do it now
2062 if( InvalidateCB->WholeVolume)
2065 ntStatus = AFSInvalidateVolume( pVolumeCB,
2066 InvalidateCB->Reason);
2068 try_return( ntStatus);
2071 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
2074 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2077 pObjectInfo = &pVolumeCB->ObjectInformation;
2082 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2084 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2086 (AFSBTreeEntry **)&pObjectInfo);
2089 if( pObjectInfo != NULL)
2093 // Reference the node so it won't be torn down
2096 lCount = AFSObjectInfoIncrement( pObjectInfo,
2097 AFS_OBJECT_REFERENCE_INVALIDATION);
2099 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2100 AFS_TRACE_LEVEL_VERBOSE,
2101 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2106 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2108 if( !NT_SUCCESS( ntStatus) ||
2109 pObjectInfo == NULL)
2112 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2113 AFS_TRACE_LEVEL_VERBOSE,
2114 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2115 InvalidateCB->FileID.Cell,
2116 InvalidateCB->FileID.Volume,
2117 InvalidateCB->FileID.Vnode,
2118 InvalidateCB->FileID.Unique,
2121 try_return( ntStatus = STATUS_SUCCESS);
2124 AFSInvalidateObject( &pObjectInfo,
2125 InvalidateCB->Reason);
2129 if( pObjectInfo != NULL)
2132 lCount = AFSObjectInfoDecrement( pObjectInfo,
2133 AFS_OBJECT_REFERENCE_INVALIDATION);
2135 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2136 AFS_TRACE_LEVEL_VERBOSE,
2137 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2142 if ( pVolumeCB != NULL)
2145 lCount = AFSVolumeDecrement( pVolumeCB,
2146 AFS_VOLUME_REFERENCE_INVALIDATE);
2148 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2149 AFS_TRACE_LEVEL_VERBOSE,
2150 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2160 AFSIsChildOfParent( IN AFSFcb *Dcb,
2164 BOOLEAN bIsChild = FALSE;
2165 AFSFcb *pCurrentFcb = Fcb;
2166 AFSObjectInfoCB * pParentObjectInfo = NULL;
2168 while( pCurrentFcb != NULL)
2171 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2172 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2180 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2181 &pCurrentFcb->ObjectInformation->ParentFileId);
2183 if ( pParentObjectInfo != NULL)
2186 pCurrentFcb = pParentObjectInfo->Fcb;
2188 AFSReleaseObjectInfo( &pParentObjectInfo);
2202 AFSCreateHighIndex( IN AFSFileID *FileID)
2205 ULONGLONG ullIndex = 0;
2207 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2214 AFSCreateLowIndex( IN AFSFileID *FileID)
2217 ULONGLONG ullIndex = 0;
2219 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2225 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2226 IN ACCESS_MASK GrantedAccess,
2227 IN BOOLEAN DirectoryEntry)
2230 BOOLEAN bAccessGranted = TRUE;
2233 // Check if we are asking for read/write and granted only read only
2234 // NOTE: There will be more checks here
2237 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2239 AFSCheckForReadOnlyAccess( GrantedAccess,
2243 bAccessGranted = FALSE;
2246 return bAccessGranted;
2250 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2253 NTSTATUS ntStatus = STATUS_SUCCESS;
2254 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2260 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2262 if( AFSGlobalRoot == NULL)
2269 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2272 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2279 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2286 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2287 IN UNICODE_STRING *SubstituteName,
2288 IN ULONG StringIndex)
2291 NTSTATUS ntStatus = STATUS_SUCCESS;
2292 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2293 AFSSysNameCB *pSysName = NULL;
2294 ERESOURCE *pSysNameLock = NULL;
2297 UNICODE_STRING uniSysName;
2304 if( IoIs32bitProcess( NULL))
2307 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2309 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2314 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2316 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2320 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2322 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2326 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2327 AFS_TRACE_LEVEL_VERBOSE,
2328 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2330 PsGetCurrentThread()));
2332 AFSAcquireShared( pSysNameLock,
2336 // Find where we are in the list
2339 while( pSysName != NULL &&
2340 ulIndex < StringIndex)
2343 pSysName = pSysName->fLink;
2348 if( pSysName == NULL)
2351 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2352 AFS_TRACE_LEVEL_VERBOSE_2,
2353 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2355 STATUS_OBJECT_NAME_NOT_FOUND));
2357 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2360 RtlInitUnicodeString( &uniSysName,
2363 // If it is a full component of @SYS then just substitue the
2367 if( RtlCompareUnicodeString( &uniSysName,
2372 SubstituteName->Length = pSysName->SysName.Length;
2373 SubstituteName->MaximumLength = SubstituteName->Length;
2375 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2376 SubstituteName->Length,
2377 AFS_SUBST_BUFFER_TAG);
2379 if( SubstituteName->Buffer == NULL)
2382 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2385 RtlCopyMemory( SubstituteName->Buffer,
2386 pSysName->SysName.Buffer,
2387 pSysName->SysName.Length);
2394 while( ComponentName->Buffer[ usIndex] != L'@')
2400 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2401 SubstituteName->MaximumLength = SubstituteName->Length;
2403 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2404 SubstituteName->Length,
2405 AFS_SUBST_BUFFER_TAG);
2407 if( SubstituteName->Buffer == NULL)
2410 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2413 RtlCopyMemory( SubstituteName->Buffer,
2414 ComponentName->Buffer,
2415 usIndex * sizeof( WCHAR));
2417 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2418 pSysName->SysName.Buffer,
2419 pSysName->SysName.Length);
2424 AFSReleaseResource( pSysNameLock);
2431 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2432 IN OUT UNICODE_STRING *ComponentName,
2433 IN UNICODE_STRING *SubstituteName,
2434 IN OUT UNICODE_STRING *RemainingPath,
2435 IN BOOLEAN FreePathName)
2438 NTSTATUS ntStatus = STATUS_SUCCESS;
2439 UNICODE_STRING uniPathName;
2440 USHORT usPrefixNameLen = 0;
2441 SHORT sNameLenDelta = 0;
2447 // If the passed in name can handle the additional length
2448 // then just moves things around
2451 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2453 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2455 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2458 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2461 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2462 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2463 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2466 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2467 SubstituteName->Buffer,
2468 SubstituteName->Length);
2470 FullPathName->Length += sNameLenDelta;
2472 ComponentName->Length += sNameLenDelta;
2474 ComponentName->MaximumLength = ComponentName->Length;
2476 if ( RemainingPath->Buffer)
2479 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2482 try_return( ntStatus);
2486 // Need to re-allocate the buffer
2489 uniPathName.Length = FullPathName->Length -
2490 ComponentName->Length +
2491 SubstituteName->Length;
2493 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2495 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2496 uniPathName.MaximumLength,
2497 AFS_NAME_BUFFER_FOUR_TAG);
2499 if( uniPathName.Buffer == NULL)
2502 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2505 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2507 usPrefixNameLen *= sizeof( WCHAR);
2509 RtlZeroMemory( uniPathName.Buffer,
2510 uniPathName.MaximumLength);
2512 RtlCopyMemory( uniPathName.Buffer,
2513 FullPathName->Buffer,
2516 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2517 SubstituteName->Buffer,
2518 SubstituteName->Length);
2520 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2523 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2524 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2525 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2528 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2530 ComponentName->Length += sNameLenDelta;
2532 ComponentName->MaximumLength = ComponentName->Length;
2534 if ( RemainingPath->Buffer)
2537 RemainingPath->Buffer = uniPathName.Buffer
2538 + (RemainingPath->Buffer - FullPathName->Buffer)
2539 + sNameLenDelta/sizeof( WCHAR);
2544 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2547 *FullPathName = uniPathName;
2558 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2562 NTSTATUS ntStatus = STATUS_SUCCESS;
2563 AFSObjectInfoCB *pCurrentObject = NULL;
2564 AFSObjectInfoCB *pNextObject = NULL;
2570 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2571 AFS_TRACE_LEVEL_VERBOSE,
2572 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2573 VolumeCB->ObjectInformation.FileId.Cell,
2574 VolumeCB->ObjectInformation.FileId.Volume,
2575 VolumeCB->ObjectInformation.FileId.Vnode,
2576 VolumeCB->ObjectInformation.FileId.Unique,
2580 // Depending on the reason for invalidation then perform work on the node
2586 case AFS_INVALIDATE_DELETED:
2590 // Mark this volume as invalid
2593 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2595 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2602 // Invalidate the volume root directory
2605 pCurrentObject = &VolumeCB->ObjectInformation;
2607 if ( pCurrentObject )
2610 lCount = AFSObjectInfoIncrement( pCurrentObject,
2611 AFS_OBJECT_REFERENCE_INVALIDATION);
2613 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2614 AFS_TRACE_LEVEL_VERBOSE,
2615 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2619 AFSInvalidateObject( &pCurrentObject,
2622 if ( pCurrentObject)
2625 lCount = AFSObjectInfoDecrement( pCurrentObject,
2626 AFS_OBJECT_REFERENCE_INVALIDATION);
2628 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2629 AFS_TRACE_LEVEL_VERBOSE,
2630 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2637 // Apply invalidation to all other volume objects
2640 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2643 pCurrentObject = VolumeCB->ObjectInfoListHead;
2645 if ( pCurrentObject)
2649 // Reference the node so it won't be torn down
2652 lCount = AFSObjectInfoIncrement( pCurrentObject,
2653 AFS_OBJECT_REFERENCE_INVALIDATION);
2655 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2656 AFS_TRACE_LEVEL_VERBOSE,
2657 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2662 while( pCurrentObject != NULL)
2665 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2671 // Reference the node so it won't be torn down
2674 lCount = AFSObjectInfoIncrement( pNextObject,
2675 AFS_OBJECT_REFERENCE_INVALIDATION);
2677 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2678 AFS_TRACE_LEVEL_VERBOSE,
2679 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2684 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2686 AFSInvalidateObject( &pCurrentObject,
2689 if ( pCurrentObject )
2692 lCount = AFSObjectInfoDecrement( pCurrentObject,
2693 AFS_OBJECT_REFERENCE_INVALIDATION);
2695 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2696 AFS_TRACE_LEVEL_VERBOSE,
2697 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2702 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2705 pCurrentObject = pNextObject;
2708 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2715 AFSInvalidateAllVolumes( VOID)
2717 AFSVolumeCB *pVolumeCB = NULL;
2718 AFSVolumeCB *pNextVolumeCB = NULL;
2719 AFSDeviceExt *pRDRDeviceExt = NULL;
2722 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2724 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2725 AFS_TRACE_LEVEL_VERBOSE,
2726 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2727 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2728 PsGetCurrentThread()));
2730 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2733 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2738 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2739 AFS_TRACE_LEVEL_VERBOSE,
2740 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2741 pVolumeCB->ObjectInfoTree.TreeLock,
2742 PsGetCurrentThread()));
2744 lCount = AFSVolumeIncrement( pVolumeCB,
2745 AFS_VOLUME_REFERENCE_INVALIDATE);
2747 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2748 AFS_TRACE_LEVEL_VERBOSE,
2749 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2754 while( pVolumeCB != NULL)
2757 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2762 lCount = AFSVolumeIncrement( pNextVolumeCB,
2763 AFS_VOLUME_REFERENCE_INVALIDATE);
2765 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2766 AFS_TRACE_LEVEL_VERBOSE,
2767 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2772 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2774 // do I need to hold the volume lock here?
2776 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2778 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2781 lCount = AFSVolumeDecrement( pVolumeCB,
2782 AFS_VOLUME_REFERENCE_INVALIDATE);
2784 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2785 AFS_TRACE_LEVEL_VERBOSE,
2786 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2790 pVolumeCB = pNextVolumeCB;
2793 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2797 AFSVerifyEntry( IN GUID *AuthGroup,
2798 IN AFSDirectoryCB *DirEntry)
2801 NTSTATUS ntStatus = STATUS_SUCCESS;
2802 AFSDirEnumEntry *pDirEnumEntry = NULL;
2803 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2804 IO_STATUS_BLOCK stIoStatus;
2809 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2810 AFS_TRACE_LEVEL_VERBOSE_2,
2811 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2812 &DirEntry->NameInformation.FileName,
2813 pObjectInfo->FileId.Cell,
2814 pObjectInfo->FileId.Volume,
2815 pObjectInfo->FileId.Vnode,
2816 pObjectInfo->FileId.Unique));
2818 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2823 if( !NT_SUCCESS( ntStatus))
2826 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2827 AFS_TRACE_LEVEL_ERROR,
2828 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2829 &DirEntry->NameInformation.FileName,
2830 pObjectInfo->FileId.Cell,
2831 pObjectInfo->FileId.Volume,
2832 pObjectInfo->FileId.Vnode,
2833 pObjectInfo->FileId.Unique,
2836 try_return( ntStatus);
2840 // Check the data version of the file
2843 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2845 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2848 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2849 AFS_TRACE_LEVEL_VERBOSE,
2850 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2851 pObjectInfo->DataVersion.QuadPart,
2852 &DirEntry->NameInformation.FileName,
2853 pObjectInfo->FileId.Cell,
2854 pObjectInfo->FileId.Volume,
2855 pObjectInfo->FileId.Vnode,
2856 pObjectInfo->FileId.Unique));
2859 // We are ok, just get out
2862 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2864 try_return( ntStatus = STATUS_SUCCESS);
2869 // New data version so we will need to process the node based on the type
2872 switch( pDirEnumEntry->FileType)
2875 case AFS_FILE_TYPE_MOUNTPOINT:
2879 // For a mount point we need to ensure the target is the same
2882 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2883 &pDirEnumEntry->TargetFileId))
2889 // Update the metadata for the entry
2892 ntStatus = AFSUpdateMetaData( DirEntry,
2895 if( NT_SUCCESS( ntStatus))
2898 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2904 case AFS_FILE_TYPE_SYMLINK:
2908 // Update the metadata for the entry
2911 ntStatus = AFSUpdateMetaData( DirEntry,
2914 if( NT_SUCCESS( ntStatus))
2917 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2923 case AFS_FILE_TYPE_FILE:
2925 FILE_OBJECT * pCCFileObject = NULL;
2926 BOOLEAN bPurgeExtents = FALSE;
2928 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
2931 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2932 AFS_TRACE_LEVEL_VERBOSE,
2933 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
2934 &DirEntry->NameInformation.FileName,
2935 pObjectInfo->FileId.Cell,
2936 pObjectInfo->FileId.Volume,
2937 pObjectInfo->FileId.Vnode,
2938 pObjectInfo->FileId.Unique,
2939 pObjectInfo->DataVersion.LowPart,
2940 pDirEnumEntry->DataVersion.LowPart));
2942 bPurgeExtents = TRUE;
2945 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2948 bPurgeExtents = TRUE;
2950 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2951 AFS_TRACE_LEVEL_VERBOSE,
2952 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2953 &DirEntry->NameInformation.FileName,
2954 pObjectInfo->FileId.Cell,
2955 pObjectInfo->FileId.Volume,
2956 pObjectInfo->FileId.Vnode,
2957 pObjectInfo->FileId.Unique));
2959 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2962 if( pObjectInfo->Fcb != NULL)
2965 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2966 AFS_TRACE_LEVEL_VERBOSE,
2967 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2968 &DirEntry->NameInformation.FileName,
2969 pObjectInfo->FileId.Cell,
2970 pObjectInfo->FileId.Volume,
2971 pObjectInfo->FileId.Vnode,
2972 pObjectInfo->FileId.Unique));
2974 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2980 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2985 if( !NT_SUCCESS( stIoStatus.Status))
2988 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
2989 AFS_TRACE_LEVEL_ERROR,
2990 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2991 &DirEntry->NameInformation.FileName,
2992 pObjectInfo->FileId.Cell,
2993 pObjectInfo->FileId.Volume,
2994 pObjectInfo->FileId.Vnode,
2995 pObjectInfo->FileId.Unique,
2997 stIoStatus.Information));
2999 ntStatus = stIoStatus.Status;
3002 if ( bPurgeExtents &&
3003 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3006 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3012 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3013 AFS_TRACE_LEVEL_WARNING,
3014 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3015 &DirEntry->NameInformation.FileName,
3016 pObjectInfo->FileId.Cell,
3017 pObjectInfo->FileId.Volume,
3018 pObjectInfo->FileId.Vnode,
3019 pObjectInfo->FileId.Unique));
3021 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3025 __except( EXCEPTION_EXECUTE_HANDLER)
3027 ntStatus = GetExceptionCode();
3031 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3032 &DirEntry->NameInformation.FileName,
3033 pObjectInfo->FileId.Cell,
3034 pObjectInfo->FileId.Volume,
3035 pObjectInfo->FileId.Vnode,
3036 pObjectInfo->FileId.Unique,
3039 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3042 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3046 AFSFlushExtents( pObjectInfo->Fcb,
3051 // Reacquire the Fcb to purge the cache
3054 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3055 AFS_TRACE_LEVEL_VERBOSE,
3056 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3057 &pObjectInfo->Fcb->NPFcb->Resource,
3058 PsGetCurrentThread()));
3060 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3064 // Update the metadata for the entry
3067 ntStatus = AFSUpdateMetaData( DirEntry,
3070 if( !NT_SUCCESS( ntStatus))
3073 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3074 AFS_TRACE_LEVEL_ERROR,
3075 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3076 &DirEntry->NameInformation.FileName,
3077 pObjectInfo->FileId.Cell,
3078 pObjectInfo->FileId.Volume,
3079 pObjectInfo->FileId.Vnode,
3080 pObjectInfo->FileId.Unique,
3087 // Update file sizes
3090 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3091 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3092 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3094 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3095 AFS_TRACE_LEVEL_VERBOSE,
3096 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3097 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3098 PsGetCurrentThread()));
3100 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3103 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3105 if ( pCCFileObject != NULL)
3107 CcSetFileSizes( pCCFileObject,
3108 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3111 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3112 AFS_TRACE_LEVEL_VERBOSE,
3113 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3114 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3115 PsGetCurrentThread()));
3117 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3119 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3125 // Update the metadata for the entry
3128 ntStatus = AFSUpdateMetaData( DirEntry,
3131 if( !NT_SUCCESS( ntStatus))
3134 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3135 AFS_TRACE_LEVEL_ERROR,
3136 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3137 &DirEntry->NameInformation.FileName,
3138 pObjectInfo->FileId.Cell,
3139 pObjectInfo->FileId.Volume,
3140 pObjectInfo->FileId.Vnode,
3141 pObjectInfo->FileId.Unique,
3147 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3148 AFS_TRACE_LEVEL_WARNING,
3149 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3150 &DirEntry->NameInformation.FileName,
3151 pObjectInfo->FileId.Cell,
3152 pObjectInfo->FileId.Volume,
3153 pObjectInfo->FileId.Vnode,
3154 pObjectInfo->FileId.Unique));
3157 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3162 case AFS_FILE_TYPE_DIRECTORY:
3166 // For a directory or root entry flush the content of
3167 // the directory enumeration.
3170 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3173 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3174 AFS_TRACE_LEVEL_VERBOSE_2,
3175 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3176 &DirEntry->NameInformation.FileName,
3177 pObjectInfo->FileId.Cell,
3178 pObjectInfo->FileId.Volume,
3179 pObjectInfo->FileId.Vnode,
3180 pObjectInfo->FileId.Unique));
3182 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3185 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3188 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3190 if ( !NT_SUCCESS( ntStatus))
3193 try_return( ntStatus);
3198 // Update the metadata for the entry
3201 ntStatus = AFSUpdateMetaData( DirEntry,
3204 if( NT_SUCCESS( ntStatus))
3207 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3213 case AFS_FILE_TYPE_DFSLINK:
3216 UNICODE_STRING uniTargetName;
3219 // For a DFS link need to check the target name has not changed
3222 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3224 uniTargetName.MaximumLength = uniTargetName.Length;
3226 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3228 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3231 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3232 RtlCompareUnicodeString( &uniTargetName,
3233 &DirEntry->NameInformation.TargetName,
3238 // Update the target name
3241 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3243 uniTargetName.Buffer,
3244 uniTargetName.Length);
3246 if( !NT_SUCCESS( ntStatus))
3249 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3255 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3258 // Update the metadata for the entry
3261 ntStatus = AFSUpdateMetaData( DirEntry,
3264 if( NT_SUCCESS( ntStatus))
3267 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3275 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3276 AFS_TRACE_LEVEL_WARNING,
3277 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3278 pObjectInfo->FileType,
3279 &DirEntry->NameInformation.FileName,
3280 pObjectInfo->FileId.Cell,
3281 pObjectInfo->FileId.Volume,
3282 pObjectInfo->FileId.Vnode,
3283 pObjectInfo->FileId.Unique));
3290 if( pDirEnumEntry != NULL)
3293 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3301 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3304 NTSTATUS ntStatus = STATUS_SUCCESS;
3305 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3306 ULONGLONG ullIndex = 0;
3307 AFSVolumeCB *pVolumeCB = NULL;
3313 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3314 AFS_TRACE_LEVEL_VERBOSE,
3315 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3316 VolumeStatus->Online,
3317 VolumeStatus->FileID.Cell,
3318 VolumeStatus->FileID.Volume));
3321 // Need to locate the Fcb for the directory to purge
3324 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3325 AFS_TRACE_LEVEL_VERBOSE,
3326 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3327 &pDevExt->Specific.RDR.VolumeTreeLock,
3328 PsGetCurrentThread()));
3330 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3333 // Locate the volume node
3336 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3338 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3340 (AFSBTreeEntry **)&pVolumeCB);
3342 if( pVolumeCB != NULL)
3345 lCount = AFSVolumeIncrement( pVolumeCB,
3346 AFS_VOLUME_REFERENCE_INVALIDATE);
3348 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3349 AFS_TRACE_LEVEL_VERBOSE,
3350 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3354 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3357 // Set the volume state accordingly
3360 if( VolumeStatus->Online)
3363 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3368 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3377 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3380 NTSTATUS ntStatus = STATUS_SUCCESS;
3385 if( AFSGlobalRoot == NULL)
3388 try_return( ntStatus);
3391 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3395 // Set the network state according to the information
3398 if( NetworkStatus->Online)
3401 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3406 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3409 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3420 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3424 NTSTATUS ntStatus = STATUS_SUCCESS;
3425 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3426 BOOLEAN bAcquiredLock = FALSE;
3427 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3432 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3433 AFS_TRACE_LEVEL_VERBOSE,
3434 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3435 ObjectInfo->FileId.Cell,
3436 ObjectInfo->FileId.Volume,
3437 ObjectInfo->FileId.Vnode,
3438 ObjectInfo->FileId.Unique));
3440 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3443 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3444 AFS_TRACE_LEVEL_VERBOSE,
3445 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3446 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3447 PsGetCurrentThread()));
3449 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3452 bAcquiredLock = TRUE;
3456 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3459 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3460 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3463 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3464 AFS_TRACE_LEVEL_ERROR,
3465 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3466 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3467 ObjectInfo->FileId.Cell,
3468 ObjectInfo->FileId.Volume,
3469 ObjectInfo->FileId.Vnode,
3470 ObjectInfo->FileId.Unique));
3474 // Reset the directory list information by clearing all valid entries
3477 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3479 while( pCurrentDirEntry != NULL)
3482 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3484 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3488 // If this entry has been deleted then process it here
3491 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3492 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3493 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3496 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3497 AFS_TRACE_LEVEL_VERBOSE,
3498 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3500 &pCurrentDirEntry->NameInformation.FileName));
3502 AFSDeleteDirEntry( ObjectInfo,
3508 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3510 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3511 AFS_TRACE_LEVEL_VERBOSE,
3512 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3514 pCurrentDirEntry->DirOpenReferenceCount));
3517 // We pull the short name from the parent tree since it could change below
3520 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3523 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3524 AFS_TRACE_LEVEL_VERBOSE,
3525 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3527 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3528 &pCurrentDirEntry->NameInformation.FileName));
3530 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3533 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3538 pCurrentDirEntry = pNextDirEntry;
3542 // Reget the directory contents
3545 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3548 if ( !NT_SUCCESS( ntStatus))
3550 try_return( ntStatus);
3554 // Now start again and tear down any entries not valid
3557 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3559 while( pCurrentDirEntry != NULL)
3562 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3564 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3567 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3568 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3569 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3572 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3575 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3577 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3578 AFS_TRACE_LEVEL_VERBOSE,
3579 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3581 &pCurrentDirEntry->NameInformation.FileName));
3583 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3588 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3591 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3592 AFS_TRACE_LEVEL_VERBOSE,
3593 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3595 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3596 &pCurrentDirEntry->NameInformation.FileName));
3600 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3602 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3603 AFS_TRACE_LEVEL_VERBOSE,
3604 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3606 &pCurrentDirEntry->NameInformation.FileName));
3611 pCurrentDirEntry = pNextDirEntry;
3616 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3617 AFS_TRACE_LEVEL_VERBOSE,
3618 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3620 pCurrentDirEntry->DirOpenReferenceCount));
3622 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3623 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3626 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3627 AFS_TRACE_LEVEL_VERBOSE,
3628 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3629 &pCurrentDirEntry->NameInformation.FileName,
3630 ObjectInfo->FileId.Cell,
3631 ObjectInfo->FileId.Volume,
3632 ObjectInfo->FileId.Vnode,
3633 ObjectInfo->FileId.Unique));
3635 AFSDeleteDirEntry( ObjectInfo,
3641 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3642 AFS_TRACE_LEVEL_VERBOSE,
3643 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3645 &pCurrentDirEntry->NameInformation.FileName,
3646 ObjectInfo->FileId.Cell,
3647 ObjectInfo->FileId.Volume,
3648 ObjectInfo->FileId.Vnode,
3649 ObjectInfo->FileId.Unique));
3651 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3653 AFSRemoveNameEntry( ObjectInfo,
3657 pCurrentDirEntry = pNextDirEntry;
3661 if( !AFSValidateDirList( ObjectInfo))
3664 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3673 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3681 AFSIsVolumeFID( IN AFSFileID *FileID)
3684 BOOLEAN bIsVolume = FALSE;
3686 if( FileID->Vnode == 1 &&
3687 FileID->Unique == 1)
3697 AFSIsFinalNode( IN AFSFcb *Fcb)
3700 BOOLEAN bIsFinalNode = FALSE;
3702 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3703 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3704 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3705 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3706 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3709 bIsFinalNode = TRUE;
3714 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3715 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3718 return bIsFinalNode;
3722 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3723 IN AFSDirEnumEntry *DirEnumEntry)
3726 NTSTATUS ntStatus = STATUS_SUCCESS;
3727 UNICODE_STRING uniTargetName;
3728 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3733 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3735 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3737 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3739 pObjectInfo->FileType = DirEnumEntry->FileType;
3741 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3743 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3745 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3747 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3749 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3751 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3753 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3755 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3756 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3759 pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3762 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
3765 if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
3768 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3773 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3777 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3779 pObjectInfo->Links = DirEnumEntry->Links;
3781 if( DirEnumEntry->TargetNameLength > 0 &&
3782 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3783 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3787 // Update the target name information if needed
3790 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3792 uniTargetName.MaximumLength = uniTargetName.Length;
3794 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3796 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3799 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3800 RtlCompareUnicodeString( &uniTargetName,
3801 &DirEntry->NameInformation.TargetName,
3806 // Update the target name
3809 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3811 uniTargetName.Buffer,
3812 uniTargetName.Length);
3814 if( !NT_SUCCESS( ntStatus))
3817 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3819 try_return( ntStatus);
3823 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3825 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3826 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3829 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3832 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3833 DirEntry->NameInformation.TargetName.Buffer != NULL)
3835 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3838 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3840 DirEntry->NameInformation.TargetName.Length = 0;
3841 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3842 DirEntry->NameInformation.TargetName.Buffer = NULL;
3844 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3856 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3858 IN BOOLEAN FastCall,
3859 IN BOOLEAN bSafeToPurge)
3862 NTSTATUS ntStatus = STATUS_SUCCESS;
3863 LARGE_INTEGER liSystemTime;
3864 AFSDirEnumEntry *pDirEnumEntry = NULL;
3865 AFSFcb *pCurrentFcb = NULL;
3866 BOOLEAN bReleaseFcb = FALSE;
3867 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3873 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3877 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3878 AFS_TRACE_LEVEL_VERBOSE_2,
3879 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3880 &DirEntry->NameInformation.FileName,
3881 pObjectInfo->FileId.Cell,
3882 pObjectInfo->FileId.Volume,
3883 pObjectInfo->FileId.Vnode,
3884 pObjectInfo->FileId.Unique,
3888 // If this is a fake node then bail since the service knows nothing about it
3891 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3894 try_return( ntStatus);
3898 // This routine ensures that the current entry is valid by:
3900 // 1) Checking that the expiration time is non-zero and after where we
3904 KeQuerySystemTime( &liSystemTime);
3906 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3907 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3908 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3909 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3912 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3913 AFS_TRACE_LEVEL_VERBOSE_2,
3914 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3915 &DirEntry->NameInformation.FileName,
3916 pObjectInfo->FileId.Cell,
3917 pObjectInfo->FileId.Volume,
3918 pObjectInfo->FileId.Vnode,
3919 pObjectInfo->FileId.Unique));
3921 try_return( ntStatus);
3925 // This node requires updating
3928 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3933 if( !NT_SUCCESS( ntStatus))
3936 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3937 AFS_TRACE_LEVEL_ERROR,
3938 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3940 &DirEntry->NameInformation.FileName,
3941 pObjectInfo->FileId.Cell,
3942 pObjectInfo->FileId.Volume,
3943 pObjectInfo->FileId.Vnode,
3944 pObjectInfo->FileId.Unique,
3948 // Failed validation of node so return access-denied
3951 try_return( ntStatus);
3954 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3955 AFS_TRACE_LEVEL_VERBOSE,
3956 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3958 &DirEntry->NameInformation.FileName,
3959 pObjectInfo->FileId.Cell,
3960 pObjectInfo->FileId.Volume,
3961 pObjectInfo->FileId.Vnode,
3962 pObjectInfo->FileId.Unique,
3963 pObjectInfo->DataVersion.QuadPart,
3964 pDirEnumEntry->DataVersion.QuadPart,
3965 pDirEnumEntry->FileType));
3969 // Based on the file type, process the node
3972 switch( pDirEnumEntry->FileType)
3975 case AFS_FILE_TYPE_MOUNTPOINT:
3979 // Update the metadata for the entry
3982 ntStatus = AFSUpdateMetaData( DirEntry,
3985 if( NT_SUCCESS( ntStatus))
3988 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3994 case AFS_FILE_TYPE_SYMLINK:
3995 case AFS_FILE_TYPE_DFSLINK:
3999 // Update the metadata for the entry
4002 ntStatus = AFSUpdateMetaData( DirEntry,
4005 if( NT_SUCCESS( ntStatus))
4008 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4014 case AFS_FILE_TYPE_FILE:
4017 BOOLEAN bPurgeExtents = FALSE;
4020 // For a file where the data version has become invalid we need to
4021 // fail any current extent requests and purge the cache for the file
4022 // Can't hold the Fcb resource while doing this
4025 if( pObjectInfo->Fcb != NULL &&
4026 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4027 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4030 pCurrentFcb = pObjectInfo->Fcb;
4032 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4035 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4036 AFS_TRACE_LEVEL_VERBOSE,
4037 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4038 &pCurrentFcb->NPFcb->Resource,
4039 PsGetCurrentThread()));
4041 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4047 if( pCurrentFcb != NULL)
4050 IO_STATUS_BLOCK stIoStatus;
4052 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4053 AFS_TRACE_LEVEL_VERBOSE_2,
4054 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4055 &DirEntry->NameInformation.FileName,
4056 pObjectInfo->FileId.Cell,
4057 pObjectInfo->FileId.Volume,
4058 pObjectInfo->FileId.Vnode,
4059 pObjectInfo->FileId.Unique));
4061 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4064 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4065 AFS_TRACE_LEVEL_VERBOSE,
4066 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4067 &DirEntry->NameInformation.FileName,
4068 pObjectInfo->FileId.Cell,
4069 pObjectInfo->FileId.Volume,
4070 pObjectInfo->FileId.Vnode,
4071 pObjectInfo->FileId.Unique,
4072 pObjectInfo->DataVersion.LowPart,
4073 pDirEnumEntry->DataVersion.LowPart));
4075 bPurgeExtents = TRUE;
4081 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4083 bPurgeExtents = TRUE;
4085 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4086 AFS_TRACE_LEVEL_VERBOSE,
4087 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4088 &DirEntry->NameInformation.FileName,
4089 pObjectInfo->FileId.Cell,
4090 pObjectInfo->FileId.Volume,
4091 pObjectInfo->FileId.Vnode,
4092 pObjectInfo->FileId.Unique));
4094 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4097 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4098 AFS_TRACE_LEVEL_VERBOSE,
4099 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4100 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4101 PsGetCurrentThread()));
4103 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4107 // Release Fcb->Resource to avoid Trend Micro deadlock
4110 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
4115 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4120 if( !NT_SUCCESS( stIoStatus.Status))
4123 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4124 AFS_TRACE_LEVEL_ERROR,
4125 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4126 &DirEntry->NameInformation.FileName,
4127 pObjectInfo->FileId.Cell,
4128 pObjectInfo->FileId.Volume,
4129 pObjectInfo->FileId.Vnode,
4130 pObjectInfo->FileId.Unique,
4132 stIoStatus.Information));
4134 ntStatus = stIoStatus.Status;
4137 if ( bPurgeExtents &&
4138 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4141 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4147 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4148 AFS_TRACE_LEVEL_WARNING,
4149 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4150 &DirEntry->NameInformation.FileName,
4151 pObjectInfo->FileId.Cell,
4152 pObjectInfo->FileId.Volume,
4153 pObjectInfo->FileId.Vnode,
4154 pObjectInfo->FileId.Unique));
4156 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4160 __except( EXCEPTION_EXECUTE_HANDLER)
4162 ntStatus = GetExceptionCode();
4166 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4167 &DirEntry->NameInformation.FileName,
4168 pObjectInfo->FileId.Cell,
4169 pObjectInfo->FileId.Volume,
4170 pObjectInfo->FileId.Vnode,
4171 pObjectInfo->FileId.Unique,
4174 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4177 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4178 AFS_TRACE_LEVEL_VERBOSE,
4179 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4180 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4181 PsGetCurrentThread()));
4183 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4185 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4194 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4199 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4201 bReleaseFcb = FALSE;
4203 if ( bPurgeExtents &&
4206 AFSFlushExtents( pCurrentFcb,
4213 // Update the metadata for the entry but only if it is safe to do so.
4214 // If it was determined that a data version change has occurred or
4215 // that a pending data verification was required, do not update the
4216 // ObjectInfo meta data or the FileObject size information. That
4217 // way it is consistent for the next time that the data is verified
4221 if ( !(bPurgeExtents && bSafeToPurge))
4224 ntStatus = AFSUpdateMetaData( DirEntry,
4227 if( !NT_SUCCESS( ntStatus))
4230 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4231 AFS_TRACE_LEVEL_ERROR,
4232 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4233 &DirEntry->NameInformation.FileName,
4234 pObjectInfo->FileId.Cell,
4235 pObjectInfo->FileId.Volume,
4236 pObjectInfo->FileId.Vnode,
4237 pObjectInfo->FileId.Unique,
4243 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4246 // Update file sizes
4249 if( pObjectInfo->Fcb != NULL)
4251 FILE_OBJECT *pCCFileObject;
4253 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4254 AFS_TRACE_LEVEL_VERBOSE,
4255 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4256 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4257 PsGetCurrentThread()));
4259 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4262 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4264 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4265 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4266 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4268 if ( pCCFileObject != NULL)
4270 CcSetFileSizes( pCCFileObject,
4271 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4274 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4275 AFS_TRACE_LEVEL_VERBOSE,
4276 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4277 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4278 PsGetCurrentThread()));
4280 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4286 case AFS_FILE_TYPE_DIRECTORY:
4289 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4293 // For a directory or root entry flush the content of
4294 // the directory enumeration.
4297 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4298 AFS_TRACE_LEVEL_VERBOSE,
4299 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4300 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4301 PsGetCurrentThread()));
4303 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4306 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4307 AFS_TRACE_LEVEL_VERBOSE_2,
4308 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4309 &DirEntry->NameInformation.FileName,
4310 pObjectInfo->FileId.Cell,
4311 pObjectInfo->FileId.Volume,
4312 pObjectInfo->FileId.Vnode,
4313 pObjectInfo->FileId.Unique));
4315 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4318 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4321 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4324 if( !NT_SUCCESS( ntStatus))
4327 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4328 AFS_TRACE_LEVEL_ERROR,
4329 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4330 &DirEntry->NameInformation.FileName,
4331 pObjectInfo->FileId.Cell,
4332 pObjectInfo->FileId.Volume,
4333 pObjectInfo->FileId.Vnode,
4334 pObjectInfo->FileId.Unique,
4342 // Update the metadata for the entry
4345 ntStatus = AFSUpdateMetaData( DirEntry,
4348 if( NT_SUCCESS( ntStatus))
4351 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4359 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4360 AFS_TRACE_LEVEL_WARNING,
4361 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4362 pObjectInfo->FileType,
4364 &DirEntry->NameInformation.FileName,
4365 pObjectInfo->FileId.Cell,
4366 pObjectInfo->FileId.Volume,
4367 pObjectInfo->FileId.Vnode,
4368 pObjectInfo->FileId.Unique));
4378 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4381 if( pDirEnumEntry != NULL)
4384 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4392 AFSInitializeSpecialShareNameList()
4395 NTSTATUS ntStatus = STATUS_SUCCESS;
4396 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4397 AFSObjectInfoCB *pObjectInfoCB = NULL;
4398 UNICODE_STRING uniShareName;
4399 ULONG ulEntryLength = 0;
4400 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4406 RtlInitUnicodeString( &uniShareName,
4409 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4412 if( pObjectInfoCB == NULL)
4415 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4418 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4419 AFS_OBJECT_REFERENCE_GLOBAL);
4421 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4422 AFS_TRACE_LEVEL_VERBOSE,
4423 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4427 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4429 ulEntryLength = sizeof( AFSDirectoryCB) +
4430 uniShareName.Length;
4432 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4436 if( pDirNode == NULL)
4439 AFSDeleteObjectInfo( &pObjectInfoCB);
4441 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4444 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4445 AFS_TRACE_LEVEL_VERBOSE,
4446 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4449 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4450 sizeof( AFSNonPagedDirectoryCB),
4451 AFS_DIR_ENTRY_NP_TAG);
4453 if( pNonPagedDirEntry == NULL)
4456 ExFreePool( pDirNode);
4458 AFSDeleteObjectInfo( &pObjectInfoCB);
4460 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4463 RtlZeroMemory( pDirNode,
4466 RtlZeroMemory( pNonPagedDirEntry,
4467 sizeof( AFSNonPagedDirectoryCB));
4469 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4471 pDirNode->NonPaged = pNonPagedDirEntry;
4473 pDirNode->ObjectInformation = pObjectInfoCB;
4479 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4481 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4483 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4485 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4487 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4488 uniShareName.Buffer,
4489 pDirNode->NameInformation.FileName.Length);
4491 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4494 AFSSpecialShareNames = pDirNode;
4496 pLastDirNode = pDirNode;
4499 RtlInitUnicodeString( &uniShareName,
4502 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4505 if( pObjectInfoCB == NULL)
4508 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4511 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4512 AFS_OBJECT_REFERENCE_GLOBAL);
4514 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4515 AFS_TRACE_LEVEL_VERBOSE,
4516 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4520 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4522 ulEntryLength = sizeof( AFSDirectoryCB) +
4523 uniShareName.Length;
4525 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4529 if( pDirNode == NULL)
4532 AFSDeleteObjectInfo( &pObjectInfoCB);
4534 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4537 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4538 AFS_TRACE_LEVEL_VERBOSE,
4539 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4542 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4543 sizeof( AFSNonPagedDirectoryCB),
4544 AFS_DIR_ENTRY_NP_TAG);
4546 if( pNonPagedDirEntry == NULL)
4549 ExFreePool( pDirNode);
4551 AFSDeleteObjectInfo( &pObjectInfoCB);
4553 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4556 RtlZeroMemory( pDirNode,
4559 RtlZeroMemory( pNonPagedDirEntry,
4560 sizeof( AFSNonPagedDirectoryCB));
4562 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4564 pDirNode->NonPaged = pNonPagedDirEntry;
4566 pDirNode->ObjectInformation = pObjectInfoCB;
4572 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4574 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4576 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4578 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4580 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4581 uniShareName.Buffer,
4582 pDirNode->NameInformation.FileName.Length);
4584 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4587 pLastDirNode->ListEntry.fLink = pDirNode;
4589 pDirNode->ListEntry.bLink = pLastDirNode;
4593 if( !NT_SUCCESS( ntStatus))
4596 if( AFSSpecialShareNames != NULL)
4599 pDirNode = AFSSpecialShareNames;
4601 while( pDirNode != NULL)
4604 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4606 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4608 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4610 ExFreePool( pDirNode->NonPaged);
4612 ExFreePool( pDirNode);
4614 pDirNode = pLastDirNode;
4617 AFSSpecialShareNames = NULL;
4626 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4627 IN UNICODE_STRING *SecondaryName)
4630 AFSDirectoryCB *pDirectoryCB = NULL;
4631 ULONGLONG ullHash = 0;
4632 UNICODE_STRING uniFullShareName;
4638 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4639 AFS_TRACE_LEVEL_VERBOSE_2,
4640 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4644 uniFullShareName = *ShareName;
4647 // Generate our hash value
4650 ullHash = AFSGenerateCRC( &uniFullShareName,
4654 // Loop through our special share names to see if this is one of them
4657 pDirectoryCB = AFSSpecialShareNames;
4659 while( pDirectoryCB != NULL)
4662 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4668 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4672 return pDirectoryCB;
4676 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4680 // Block on the queue flush event
4683 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4693 AFSWaitOnQueuedReleases()
4696 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4699 // Block on the queue flush event
4702 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4712 AFSIsEqualFID( IN AFSFileID *FileId1,
4713 IN AFSFileID *FileId2)
4716 BOOLEAN bIsEqual = FALSE;
4718 if( FileId1->Hash == FileId2->Hash &&
4719 FileId1->Unique == FileId2->Unique &&
4720 FileId1->Vnode == FileId2->Vnode &&
4721 FileId1->Volume == FileId2->Volume &&
4722 FileId1->Cell == FileId2->Cell)
4732 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4735 NTSTATUS ntStatus = STATUS_SUCCESS;
4736 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4741 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4744 // Reset the directory list information
4747 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4749 while( pCurrentDirEntry != NULL)
4752 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4754 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
4755 pCurrentDirEntry->NameArrayReferenceCount <= 0)
4758 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4759 AFS_TRACE_LEVEL_VERBOSE,
4760 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4762 &pCurrentDirEntry->NameInformation.FileName));
4764 AFSDeleteDirEntry( ObjectInfoCB,
4770 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4771 AFS_TRACE_LEVEL_VERBOSE,
4772 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4774 &pCurrentDirEntry->NameInformation.FileName));
4776 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4778 AFSRemoveNameEntry( ObjectInfoCB,
4782 pCurrentDirEntry = pNextDirEntry;
4785 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4787 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4789 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4791 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4793 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4795 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4797 AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4798 AFS_TRACE_LEVEL_VERBOSE,
4799 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4800 ObjectInfoCB->FileId.Cell,
4801 ObjectInfoCB->FileId.Volume,
4802 ObjectInfoCB->FileId.Vnode,
4803 ObjectInfoCB->FileId.Unique));
4810 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4813 NTSTATUS ntStatus = STATUS_SUCCESS;
4814 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4815 UNICODE_STRING uniFullName;
4820 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4821 AFS_TRACE_LEVEL_VERBOSE,
4822 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4823 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4824 PsGetCurrentThread()));
4826 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4829 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4832 try_return( ntStatus);
4836 // Initialize the root information
4839 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4842 // Enumerate the shares in the volume
4845 ntStatus = AFSEnumerateDirectory( AuthGroup,
4846 &AFSGlobalRoot->ObjectInformation,
4849 if( !NT_SUCCESS( ntStatus))
4852 try_return( ntStatus);
4855 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4857 uniFullName.MaximumLength = PAGE_SIZE;
4858 uniFullName.Length = 0;
4860 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4861 uniFullName.MaximumLength,
4862 AFS_GENERIC_MEMORY_12_TAG);
4864 if( uniFullName.Buffer == NULL)
4868 // Reset the directory content
4871 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4873 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4875 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4879 // Populate our list of entries in the NP enumeration list
4882 while( pDirGlobalDirNode != NULL)
4885 uniFullName.Buffer[ 0] = L'\\';
4886 uniFullName.Buffer[ 1] = L'\\';
4888 uniFullName.Length = 2 * sizeof( WCHAR);
4890 RtlCopyMemory( &uniFullName.Buffer[ 2],
4891 AFSServerName.Buffer,
4892 AFSServerName.Length);
4894 uniFullName.Length += AFSServerName.Length;
4896 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4898 uniFullName.Length += sizeof( WCHAR);
4900 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4901 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4902 pDirGlobalDirNode->NameInformation.FileName.Length);
4904 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4906 AFSAddConnectionEx( &uniFullName,
4907 RESOURCEDISPLAYTYPE_SHARE,
4910 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4913 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
4917 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4924 AFSIsRelativeName( IN UNICODE_STRING *Name)
4927 BOOLEAN bIsRelative = FALSE;
4929 if( Name->Length > 0 &&
4930 Name->Buffer[ 0] != L'\\')
4940 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
4942 UNICODE_STRING uniTempName;
4943 BOOLEAN bIsAbsolute = FALSE;
4946 // An absolute AFS path must begin with \afs\... or equivalent
4949 if ( Name->Length == 0 ||
4950 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
4951 Name->Buffer[ 0] != L'\\' ||
4952 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
4958 uniTempName.Length = AFSMountRootName.Length;
4959 uniTempName.MaximumLength = AFSMountRootName.Length;
4961 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4962 uniTempName.MaximumLength,
4963 AFS_NAME_BUFFER_TWO_TAG);
4965 if( uniTempName.Buffer == NULL)
4971 RtlCopyMemory( uniTempName.Buffer,
4973 AFSMountRootName.Length);
4975 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
4979 AFSExFreePoolWithTag( uniTempName.Buffer,
4980 AFS_NAME_BUFFER_TWO_TAG);
4987 AFSUpdateName( IN UNICODE_STRING *Name)
4992 while( usIndex < Name->Length/sizeof( WCHAR))
4995 if( Name->Buffer[ usIndex] == L'/')
4998 Name->Buffer[ usIndex] = L'\\';
5008 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
5009 IN OUT ULONG *Flags,
5010 IN WCHAR *NameBuffer,
5011 IN USHORT NameLength)
5014 NTSTATUS ntStatus = STATUS_SUCCESS;
5015 WCHAR *pTmpBuffer = NULL;
5021 // If we have enough space then just move in the name otherwise
5022 // allocate a new buffer
5025 if( TargetName->Length < NameLength)
5028 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5030 AFS_NAME_BUFFER_FIVE_TAG);
5032 if( pTmpBuffer == NULL)
5035 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5038 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5041 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5044 TargetName->MaximumLength = NameLength;
5046 TargetName->Buffer = pTmpBuffer;
5048 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5051 TargetName->Length = NameLength;
5053 RtlCopyMemory( TargetName->Buffer,
5055 TargetName->Length);
5058 // Update the name in the buffer
5061 AFSUpdateName( TargetName);
5072 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5077 // Depending on the type of node, set the event
5080 switch( Fcb->Header.NodeTypeCode)
5083 case AFS_DIRECTORY_FCB:
5088 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5098 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5104 // Depending on the type of node, set the event
5107 switch( Fcb->Header.NodeTypeCode)
5110 case AFS_DIRECTORY_FCB:
5115 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5117 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5127 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5130 BOOLEAN bIsInProcess = FALSE;
5135 if( ObjectInfo->Fcb == NULL)
5138 try_return( bIsInProcess);
5141 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5144 case AFS_DIRECTORY_FCB:
5149 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5152 bIsInProcess = TRUE;
5164 return bIsInProcess;
5168 AFSVerifyVolume( IN ULONGLONG ProcessId,
5169 IN AFSVolumeCB *VolumeCB)
5172 UNREFERENCED_PARAMETER(ProcessId);
5173 UNREFERENCED_PARAMETER(VolumeCB);
5174 NTSTATUS ntStatus = STATUS_SUCCESS;
5181 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5184 NTSTATUS ntStatus = STATUS_SUCCESS;
5185 AFSObjectInfoCB *pObjectInfoCB = NULL;
5186 AFSDirectoryCB *pDirNode = NULL;
5187 ULONG ulEntryLength = 0;
5188 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5194 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5197 if( pObjectInfoCB == NULL)
5200 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5203 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5204 AFS_OBJECT_REFERENCE_DIRENTRY);
5206 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5207 AFS_TRACE_LEVEL_VERBOSE,
5208 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5212 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5214 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5216 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5218 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5222 if( pDirNode == NULL)
5225 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5228 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5229 AFS_TRACE_LEVEL_VERBOSE,
5230 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5233 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5234 sizeof( AFSNonPagedDirectoryCB),
5235 AFS_DIR_ENTRY_NP_TAG);
5237 if( pNonPagedDirEntry == NULL)
5240 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5243 RtlZeroMemory( pDirNode,
5246 RtlZeroMemory( pNonPagedDirEntry,
5247 sizeof( AFSNonPagedDirectoryCB));
5249 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5251 pDirNode->NonPaged = pNonPagedDirEntry;
5253 pDirNode->ObjectInformation = pObjectInfoCB;
5255 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5261 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5263 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5265 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5267 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5269 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5270 AFSPIOCtlName.Buffer,
5271 pDirNode->NameInformation.FileName.Length);
5273 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5276 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5279 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5280 AFS_TRACE_LEVEL_WARNING,
5281 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5282 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5285 try_return( ntStatus = STATUS_REPARSE);
5290 if ( ntStatus != STATUS_SUCCESS)
5293 if ( pDirNode != NULL)
5296 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5297 AFS_TRACE_LEVEL_VERBOSE,
5298 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
5301 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5304 if( pNonPagedDirEntry != NULL)
5307 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5309 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5312 if ( pObjectInfoCB != NULL)
5315 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
5316 AFS_OBJECT_REFERENCE_DIRENTRY);
5318 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5319 AFS_TRACE_LEVEL_VERBOSE,
5320 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
5324 AFSDeleteObjectInfo( &pObjectInfoCB);
5333 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5334 IN AFSDirectoryCB *DirectoryCB,
5335 IN UNICODE_STRING *ParentPathName,
5336 IN AFSNameArrayHdr *RelatedNameArray,
5338 OUT AFSFileInfoCB *FileInfo)
5341 NTSTATUS ntStatus = STATUS_SUCCESS;
5342 AFSDirEnumEntry *pDirEntry = NULL;
5343 UNICODE_STRING uniFullPathName = {0};
5344 AFSNameArrayHdr *pNameArray = NULL;
5345 AFSVolumeCB *pVolumeCB = NULL;
5346 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5347 AFSVolumeCB *pNewVolumeCB = NULL;
5348 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5349 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5350 AFSDirectoryCB *pNewParentDirEntry = NULL;
5351 WCHAR *pwchBuffer = NULL;
5352 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5353 ULONG ulNameDifference = 0;
5360 // Retrieve a target name for the entry
5363 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5366 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5369 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5371 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5376 if( !NT_SUCCESS( ntStatus) ||
5377 pDirEntry->TargetNameLength == 0)
5380 if( pDirEntry != NULL)
5383 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5386 try_return( ntStatus);
5389 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5392 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5396 // Update the target name
5399 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5400 &DirectoryCB->Flags,
5401 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5402 (USHORT)pDirEntry->TargetNameLength);
5404 if( !NT_SUCCESS( ntStatus))
5407 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5409 try_return( ntStatus);
5413 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5417 // Need to pass the full path in for parsing.
5420 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5423 uniFullPathName.Length = 0;
5424 uniFullPathName.MaximumLength = ParentPathName->Length +
5426 DirectoryCB->NameInformation.TargetName.Length;
5428 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5429 uniFullPathName.MaximumLength,
5430 AFS_NAME_BUFFER_SIX_TAG);
5432 if( uniFullPathName.Buffer == NULL)
5435 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5437 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5440 pwchBuffer = uniFullPathName.Buffer;
5442 RtlZeroMemory( uniFullPathName.Buffer,
5443 uniFullPathName.MaximumLength);
5445 RtlCopyMemory( uniFullPathName.Buffer,
5446 ParentPathName->Buffer,
5447 ParentPathName->Length);
5449 uniFullPathName.Length = ParentPathName->Length;
5451 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5452 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5455 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5457 uniFullPathName.Length += sizeof( WCHAR);
5460 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5461 DirectoryCB->NameInformation.TargetName.Buffer,
5462 DirectoryCB->NameInformation.TargetName.Length);
5464 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5466 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5467 uniParsedName.MaximumLength = uniParsedName.Length;
5469 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5471 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5474 // We populate up to the current parent
5477 if( RelatedNameArray != NULL)
5480 pNameArray = AFSInitNameArray( NULL,
5481 RelatedNameArray->MaxElementCount);
5483 if( pNameArray == NULL)
5486 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5489 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5496 pNameArray = AFSInitNameArray( NULL,
5499 if( pNameArray == NULL)
5502 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5505 ntStatus = AFSPopulateNameArray( pNameArray,
5510 if( !NT_SUCCESS( ntStatus))
5513 try_return( ntStatus);
5516 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5518 pParentDirEntry = ParentDirectoryCB;
5523 uniFullPathName.Length = 0;
5524 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5526 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5527 uniFullPathName.MaximumLength,
5528 AFS_NAME_BUFFER_SEVEN_TAG);
5530 if( uniFullPathName.Buffer == NULL)
5533 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5535 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5538 pwchBuffer = uniFullPathName.Buffer;
5540 RtlZeroMemory( uniFullPathName.Buffer,
5541 uniFullPathName.MaximumLength);
5543 RtlCopyMemory( uniFullPathName.Buffer,
5544 DirectoryCB->NameInformation.TargetName.Buffer,
5545 DirectoryCB->NameInformation.TargetName.Length);
5547 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5550 // This name should begin with the \afs server so parse it off and check it
5553 FsRtlDissectName( uniFullPathName,
5557 if( RtlCompareUnicodeString( &uniComponentName,
5562 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5564 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5565 AFS_TRACE_LEVEL_ERROR,
5566 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5569 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5572 uniFullPathName = uniRemainingPath;
5574 uniParsedName = uniFullPathName;
5576 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5578 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5584 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5587 if( pNameArray == NULL)
5590 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5593 pVolumeCB = AFSGlobalRoot;
5595 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5599 // Increment the ref count on the volume and dir entry for correct processing below
5602 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
5604 lCount = AFSVolumeIncrement( pVolumeCB,
5605 VolumeReferenceReason);
5607 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5608 AFS_TRACE_LEVEL_VERBOSE,
5609 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
5611 VolumeReferenceReason,
5614 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
5616 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5617 AFS_TRACE_LEVEL_VERBOSE,
5618 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5619 &pParentDirEntry->NameInformation.FileName,
5624 ntStatus = AFSLocateNameEntry( NULL,
5629 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5633 &NewVolumeReferenceReason,
5634 &pNewParentDirEntry,
5638 if ( pNewVolumeCB != NULL)
5641 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
5642 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
5643 // the reference on pVolumeCB that was held prior to the call.
5644 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
5645 // will be released second.
5648 lCount = AFSVolumeDecrement( pVolumeCB,
5649 VolumeReferenceReason);
5651 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5652 AFS_TRACE_LEVEL_VERBOSE,
5653 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
5655 VolumeReferenceReason,
5658 pVolumeCB = pNewVolumeCB;
5660 pNewVolumeCB = NULL;
5662 VolumeReferenceReason = NewVolumeReferenceReason;
5664 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5668 // AFSLocateNameEntry does not alter the reference count of
5669 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
5670 // a reference held.
5673 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5675 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5676 AFS_TRACE_LEVEL_VERBOSE,
5677 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
5678 &pParentDirEntry->NameInformation.FileName,
5682 pParentDirEntry = pNewParentDirEntry;
5684 pNewParentDirEntry = NULL;
5686 if( !NT_SUCCESS( ntStatus) ||
5687 ntStatus == STATUS_REPARSE)
5690 try_return( ntStatus);
5694 // Store off the information
5697 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5700 // Check for the mount point being returned
5703 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
5704 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5707 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5709 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
5712 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
5715 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
5720 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5724 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5726 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5728 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5730 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5732 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5734 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5738 if( pDirEntry != NULL)
5741 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
5744 if( pDirectoryEntry != NULL)
5747 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
5749 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5750 AFS_TRACE_LEVEL_VERBOSE,
5751 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5752 &pDirectoryEntry->NameInformation.FileName,
5757 ASSERT( lCount >= 0);
5760 if ( pParentDirEntry != NULL)
5763 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5765 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5766 AFS_TRACE_LEVEL_VERBOSE,
5767 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5768 &pParentDirEntry->NameInformation.FileName,
5773 ASSERT( lCount >= 0);
5776 if( pVolumeCB != NULL)
5779 lCount = AFSVolumeDecrement( pVolumeCB,
5780 VolumeReferenceReason);
5782 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5783 AFS_TRACE_LEVEL_VERBOSE,
5784 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
5786 VolumeReferenceReason,
5790 if( pNameArray != NULL)
5793 AFSFreeNameArray( pNameArray);
5796 if( pwchBuffer != NULL)
5800 // Always free the buffer that we allocated as AFSLocateNameEntry
5801 // will not free it. If uniFullPathName.Buffer was allocated by
5802 // AFSLocateNameEntry, then we must free that as well.
5803 // Check that the uniFullPathName.Buffer in the string is not the same
5804 // offset by the length of the server name
5807 if( uniFullPathName.Length > 0 &&
5808 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
5811 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
5814 AFSExFreePoolWithTag( pwchBuffer, 0);
5822 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
5823 IN ULONGLONG HashIndex)
5826 NTSTATUS ntStatus = STATUS_SUCCESS;
5827 AFSObjectInfoCB *pObjectInfo = NULL;
5833 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
5834 sizeof( AFSObjectInfoCB),
5835 AFS_OBJECT_INFO_TAG);
5837 if( pObjectInfo == NULL)
5840 try_return( pObjectInfo);
5843 RtlZeroMemory( pObjectInfo,
5844 sizeof( AFSObjectInfoCB));
5846 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5847 sizeof( AFSNonPagedObjectInfoCB),
5848 AFS_NP_OBJECT_INFO_TAG);
5850 if( pObjectInfo->NonPagedInfo == NULL)
5853 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
5855 try_return( pObjectInfo = NULL);
5858 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
5860 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
5862 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
5864 if( ParentObjectInfo != NULL)
5867 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
5869 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
5871 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
5873 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
5874 AFS_OBJECT_REFERENCE_CHILD);
5876 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5877 AFS_TRACE_LEVEL_VERBOSE,
5878 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
5884 // Initialize the access time
5887 KeQueryTickCount( &pObjectInfo->LastAccessCount);
5892 ASSERT( ParentObjectInfo);
5895 // Insert the entry into the object tree and list
5898 pObjectInfo->TreeEntry.HashIndex = HashIndex;
5900 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
5903 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
5908 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
5909 &pObjectInfo->TreeEntry);
5911 ASSERT( NT_SUCCESS( ntStatus));
5915 // And the object list in the volume
5918 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
5921 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
5926 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
5928 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
5931 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
5934 // Indicate the object is in the hash tree and linked list in the volume
5937 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
5949 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
5955 if ( ObjectInfo->ObjectReferenceCount == 0)
5958 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
5961 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
5966 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
5969 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
5974 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
5976 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
5981 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
5983 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
5989 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
5993 LONG lCount, lCount2;
5995 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
5998 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6003 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6005 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6007 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6010 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6013 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6015 ASSERT( lCount2 >= 0);
6017 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6023 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6024 IN AFSFileID *FileId)
6026 DWORD ntStatus = STATUS_SUCCESS;
6028 AFSObjectInfoCB *pObjectInfo = NULL;
6031 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6034 pObjectInfo = &VolumeCB->ObjectInformation;
6039 AFSAcquireExcl( VolumeCB->ObjectInfoTree.TreeLock,
6042 ullIndex = AFSCreateLowIndex( FileId);
6044 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6046 (AFSBTreeEntry **)&pObjectInfo);
6048 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6051 if ( NT_SUCCESS( ntStatus)) {
6053 lCount = AFSObjectInfoIncrement( pObjectInfo,
6054 AFS_OBJECT_REFERENCE_FIND);
6056 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6057 AFS_TRACE_LEVEL_VERBOSE,
6058 "AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
6067 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6071 lCount = AFSObjectInfoDecrement( *ppObjectInfo,
6072 AFS_OBJECT_REFERENCE_FIND);
6074 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6075 AFS_TRACE_LEVEL_VERBOSE,
6076 "AFSReleaseObjectInfo Decrement count on object %p Cnt %d\n",
6080 *ppObjectInfo = NULL;
6084 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6087 BOOLEAN bAcquiredTreeLock = FALSE;
6088 AFSObjectInfoCB *pObjectInfo = NULL;
6089 BOOLEAN bHeldInService;
6090 AFSObjectInfoCB * pParentObjectInfo = NULL;
6094 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
6098 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6099 // embedded in the VolumeCB.
6107 pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
6111 if ( pObjectInfo == NULL)
6117 ASSERT( *ppObjectInfo == NULL);
6119 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6121 bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6123 if( !ExIsResourceAcquiredExclusiveLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6126 ASSERT( !ExIsResourceAcquiredLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6128 AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6131 bAcquiredTreeLock = TRUE;
6134 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6137 pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
6138 &pObjectInfo->ParentFileId);
6142 // Remove it from the tree and list if it was inserted
6145 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6148 AFSRemoveHashEntry( &pObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6149 &pObjectInfo->TreeEntry);
6152 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6155 if( pObjectInfo->ListEntry.fLink == NULL)
6158 pObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6160 if( pObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6163 pObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6169 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6172 if( pObjectInfo->ListEntry.bLink == NULL)
6175 pObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6177 if( pObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6180 pObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6186 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6190 if( pParentObjectInfo != NULL)
6193 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6195 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6196 AFS_OBJECT_REFERENCE_CHILD);
6198 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6199 AFS_TRACE_LEVEL_VERBOSE,
6200 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6204 AFSReleaseObjectInfo( &pParentObjectInfo);
6207 if( bAcquiredTreeLock)
6210 AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6216 FileId = pObjectInfo->FileId;
6219 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6221 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6223 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6225 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6228 // Release the fid in the service
6234 AFSReleaseFid( &FileId);
6241 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6242 OUT AFSDirectoryCB **TargetDirEntry)
6245 NTSTATUS ntStatus = STATUS_SUCCESS;
6246 AFSDirEnumEntry *pDirEntry = NULL;
6247 UNICODE_STRING uniFullPathName = {0};
6248 AFSNameArrayHdr *pNameArray = NULL;
6249 AFSVolumeCB *pVolumeCB = NULL;
6250 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6251 AFSVolumeCB *pNewVolumeCB = NULL;
6252 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6253 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6254 AFSDirectoryCB *pNewParentDirEntry = NULL;
6255 WCHAR *pwchBuffer = NULL;
6256 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6257 ULONG ulNameDifference = 0;
6264 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6265 DirectoryCB->ObjectInformation,
6269 if( !NT_SUCCESS( ntStatus))
6271 try_return( ntStatus);
6275 // Retrieve a target name for the entry
6278 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6281 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6284 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6286 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6291 if( !NT_SUCCESS( ntStatus) ||
6292 pDirEntry->TargetNameLength == 0)
6295 if( pDirEntry != NULL)
6298 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6301 try_return( ntStatus);
6304 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6307 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6311 // Update the target name
6314 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6315 &DirectoryCB->Flags,
6316 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6317 (USHORT)pDirEntry->TargetNameLength);
6319 if( !NT_SUCCESS( ntStatus))
6322 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6324 try_return( ntStatus);
6328 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6332 // Need to pass the full path in for parsing.
6335 uniFullPathName.Length = 0;
6336 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6338 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6339 uniFullPathName.MaximumLength,
6340 AFS_NAME_BUFFER_EIGHT_TAG);
6342 if( uniFullPathName.Buffer == NULL)
6345 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6347 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6350 pwchBuffer = uniFullPathName.Buffer;
6352 RtlZeroMemory( uniFullPathName.Buffer,
6353 uniFullPathName.MaximumLength);
6355 RtlCopyMemory( uniFullPathName.Buffer,
6356 DirectoryCB->NameInformation.TargetName.Buffer,
6357 DirectoryCB->NameInformation.TargetName.Length);
6359 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6362 // This name should begin with the \afs server so parse it off and chech it
6365 FsRtlDissectName( uniFullPathName,
6369 if( RtlCompareUnicodeString( &uniComponentName,
6375 // Try evaluating the full path
6378 uniFullPathName.Buffer = pwchBuffer;
6380 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6382 uniFullPathName.MaximumLength = uniFullPathName.Length;
6387 uniFullPathName = uniRemainingPath;
6390 uniParsedName = uniFullPathName;
6392 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6394 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6400 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6403 if( pNameArray == NULL)
6406 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6409 pVolumeCB = AFSGlobalRoot;
6411 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6413 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
6415 lCount = AFSVolumeIncrement( pVolumeCB,
6416 VolumeReferenceReason);
6418 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6419 AFS_TRACE_LEVEL_VERBOSE,
6420 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
6422 VolumeReferenceReason,
6425 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6427 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6428 AFS_TRACE_LEVEL_VERBOSE,
6429 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6430 &pParentDirEntry->NameInformation.FileName,
6435 ntStatus = AFSLocateNameEntry( NULL,
6444 &VolumeReferenceReason,
6445 &pNewParentDirEntry,
6449 if ( pNewVolumeCB != NULL)
6452 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6453 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6454 // the reference on pVolumeCB that was held prior to the call.
6455 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6456 // will be released second.
6459 lCount = AFSVolumeDecrement( pVolumeCB,
6460 VolumeReferenceReason);
6462 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6463 AFS_TRACE_LEVEL_VERBOSE,
6464 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
6466 VolumeReferenceReason,
6469 pVolumeCB = pNewVolumeCB;
6471 pNewVolumeCB = NULL;
6473 VolumeReferenceReason = NewVolumeReferenceReason;
6475 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6479 // AFSLocateNameEntry does not alter the reference count of
6480 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6481 // a reference held.
6484 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6486 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6487 AFS_TRACE_LEVEL_VERBOSE,
6488 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
6489 &pParentDirEntry->NameInformation.FileName,
6493 pParentDirEntry = pNewParentDirEntry;
6495 pNewParentDirEntry = NULL;
6497 if( !NT_SUCCESS( ntStatus) ||
6498 ntStatus == STATUS_REPARSE)
6503 try_return( ntStatus);
6507 // Pass back the target dir entry for this request
6508 // The caller must release the DirOpenReferenceCount
6511 *TargetDirEntry = pDirectoryEntry;
6513 pDirectoryEntry = NULL;
6517 if( pDirectoryEntry != NULL)
6520 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6522 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6523 AFS_TRACE_LEVEL_VERBOSE,
6524 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6525 &pDirectoryEntry->NameInformation.FileName,
6530 ASSERT( lCount >= 0);
6533 if ( pParentDirEntry != NULL)
6536 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6538 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6539 AFS_TRACE_LEVEL_VERBOSE,
6540 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6541 &pParentDirEntry->NameInformation.FileName,
6546 ASSERT( lCount >= 0);
6549 if( pDirEntry != NULL)
6552 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6555 if( pVolumeCB != NULL)
6558 lCount = AFSVolumeDecrement( pVolumeCB,
6559 VolumeReferenceReason);
6561 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6562 AFS_TRACE_LEVEL_VERBOSE,
6563 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
6565 VolumeReferenceReason,
6569 if( pNameArray != NULL)
6572 AFSFreeNameArray( pNameArray);
6575 if( pwchBuffer != NULL)
6579 // Always free the buffer that we allocated as AFSLocateNameEntry
6580 // will not free it. If uniFullPathName.Buffer was allocated by
6581 // AFSLocateNameEntry, then we must free that as well.
6582 // Check that the uniFullPathName.Buffer in the string is not the same
6583 // offset by the length of the server name
6586 if( uniFullPathName.Length > 0 &&
6587 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6590 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6593 AFSExFreePoolWithTag( pwchBuffer, 0);
6601 AFSCleanupFcb( IN AFSFcb *Fcb,
6602 IN BOOLEAN ForceFlush)
6605 NTSTATUS ntStatus = STATUS_SUCCESS;
6606 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6607 LARGE_INTEGER liTime;
6608 IO_STATUS_BLOCK stIoStatus;
6613 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6615 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6617 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6620 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6621 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6624 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6625 AFS_TRACE_LEVEL_VERBOSE,
6626 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
6627 &Fcb->NPFcb->Resource,
6628 PsGetCurrentThread()));
6630 AFSAcquireShared( &Fcb->NPFcb->Resource,
6633 if( Fcb->OpenReferenceCount > 0)
6636 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6637 AFS_TRACE_LEVEL_VERBOSE,
6638 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
6639 &Fcb->NPFcb->SectionObjectResource,
6640 PsGetCurrentThread()));
6642 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
6648 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6653 if( !NT_SUCCESS( stIoStatus.Status))
6656 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6657 AFS_TRACE_LEVEL_ERROR,
6658 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6659 Fcb->ObjectInformation->FileId.Cell,
6660 Fcb->ObjectInformation->FileId.Volume,
6661 Fcb->ObjectInformation->FileId.Vnode,
6662 Fcb->ObjectInformation->FileId.Unique,
6664 stIoStatus.Information));
6666 ntStatus = stIoStatus.Status;
6669 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
6672 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6678 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6679 AFS_TRACE_LEVEL_WARNING,
6680 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
6681 Fcb->ObjectInformation->FileId.Cell,
6682 Fcb->ObjectInformation->FileId.Volume,
6683 Fcb->ObjectInformation->FileId.Vnode,
6684 Fcb->ObjectInformation->FileId.Unique));
6686 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6690 __except( EXCEPTION_EXECUTE_HANDLER)
6693 ntStatus = GetExceptionCode();
6697 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
6698 Fcb->ObjectInformation->FileId.Cell,
6699 Fcb->ObjectInformation->FileId.Volume,
6700 Fcb->ObjectInformation->FileId.Vnode,
6701 Fcb->ObjectInformation->FileId.Unique,
6704 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6707 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6708 AFS_TRACE_LEVEL_VERBOSE,
6709 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
6710 &Fcb->NPFcb->SectionObjectResource,
6711 PsGetCurrentThread()));
6713 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
6716 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6717 AFS_TRACE_LEVEL_VERBOSE,
6718 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
6719 &Fcb->NPFcb->Resource,
6720 PsGetCurrentThread()));
6722 AFSReleaseResource( &Fcb->NPFcb->Resource);
6725 // Wait for any currently running flush or release requests to complete
6728 AFSWaitOnQueuedFlushes( Fcb);
6731 // Now perform another flush on the file
6734 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6738 AFSReleaseExtentsWithFlush( Fcb,
6744 if( Fcb->OpenReferenceCount == 0 ||
6745 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6746 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6749 AFSTearDownFcbExtents( Fcb,
6753 try_return( ntStatus);
6756 KeQueryTickCount( &liTime);
6759 // First up are there dirty extents in the cache to flush?
6762 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6763 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6767 // The file has been marked as invalid. Dump it
6770 AFSTearDownFcbExtents( Fcb,
6773 else if( ForceFlush ||
6774 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
6775 Fcb->Specific.File.ExtentCount) &&
6776 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6777 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6779 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6781 Fcb->OpenReferenceCount == 0)
6784 AFSReleaseExtentsWithFlush( Fcb,
6791 // If there are extents and they haven't been used recently *and*
6792 // are not being used
6796 ( 0 != Fcb->Specific.File.ExtentCount &&
6797 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6798 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6799 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
6802 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6803 AFS_TRACE_LEVEL_VERBOSE,
6804 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
6805 &Fcb->NPFcb->SectionObjectResource,
6806 PsGetCurrentThread()));
6808 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
6814 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6819 if( !NT_SUCCESS( stIoStatus.Status))
6822 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6823 AFS_TRACE_LEVEL_ERROR,
6824 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6825 Fcb->ObjectInformation->FileId.Cell,
6826 Fcb->ObjectInformation->FileId.Volume,
6827 Fcb->ObjectInformation->FileId.Vnode,
6828 Fcb->ObjectInformation->FileId.Unique,
6830 stIoStatus.Information));
6832 ntStatus = stIoStatus.Status;
6836 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
6839 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6845 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6846 AFS_TRACE_LEVEL_WARNING,
6847 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
6848 Fcb->ObjectInformation->FileId.Cell,
6849 Fcb->ObjectInformation->FileId.Volume,
6850 Fcb->ObjectInformation->FileId.Vnode,
6851 Fcb->ObjectInformation->FileId.Unique));
6853 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6857 __except( EXCEPTION_EXECUTE_HANDLER)
6860 ntStatus = GetExceptionCode();
6864 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
6865 Fcb->ObjectInformation->FileId.Cell,
6866 Fcb->ObjectInformation->FileId.Volume,
6867 Fcb->ObjectInformation->FileId.Vnode,
6868 Fcb->ObjectInformation->FileId.Unique,
6872 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6873 AFS_TRACE_LEVEL_VERBOSE,
6874 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
6875 &Fcb->NPFcb->SectionObjectResource,
6876 PsGetCurrentThread()));
6878 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
6880 if( Fcb->OpenReferenceCount <= 0)
6884 // Tear em down we'll not be needing them again
6887 AFSTearDownFcbExtents( Fcb,
6894 ntStatus = STATUS_RETRY;
6907 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
6908 IN UNICODE_STRING *NewFileName)
6911 NTSTATUS ntStatus = STATUS_SUCCESS;
6912 WCHAR *pTmpBuffer = NULL;
6917 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
6920 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
6923 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
6925 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6927 DirectoryCB->NameInformation.FileName.Buffer = NULL;
6931 // OK, we need to allocate a new name buffer
6934 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6935 NewFileName->Length,
6936 AFS_NAME_BUFFER_NINE_TAG);
6938 if( pTmpBuffer == NULL)
6941 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6944 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
6946 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
6948 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6951 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
6953 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
6954 NewFileName->Buffer,
6955 NewFileName->Length);
6966 AFSReadCacheFile( IN void *ReadBuffer,
6967 IN LARGE_INTEGER *ReadOffset,
6968 IN ULONG RequestedDataLength,
6969 IN OUT PULONG BytesRead)
6972 NTSTATUS ntStatus = STATUS_SUCCESS;
6975 PIO_STACK_LOCATION pIoStackLocation = NULL;
6976 DEVICE_OBJECT *pTargetDeviceObject = NULL;
6977 FILE_OBJECT *pCacheFileObject = NULL;
6982 pCacheFileObject = AFSReferenceCacheFileObject();
6984 if( pCacheFileObject == NULL)
6986 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
6989 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
6992 // Initialize the event
6995 KeInitializeEvent( &kEvent,
6996 SynchronizationEvent,
7000 // Allocate an irp for this request. This could also come from a
7001 // private pool, for instance.
7004 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7010 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7014 // Build the IRP's main body
7017 pIrp->UserBuffer = ReadBuffer;
7019 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7020 pIrp->RequestorMode = KernelMode;
7021 pIrp->Flags |= IRP_READ_OPERATION;
7024 // Set up the I/O stack location.
7027 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7028 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7029 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7030 pIoStackLocation->FileObject = pCacheFileObject;
7031 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7033 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7036 // Set the completion routine.
7039 IoSetCompletionRoutine( pIrp,
7047 // Send it to the FSD
7050 ntStatus = IoCallDriver( pTargetDeviceObject,
7053 if( NT_SUCCESS( ntStatus))
7060 ntStatus = KeWaitForSingleObject( &kEvent,
7066 if( NT_SUCCESS( ntStatus))
7069 ntStatus = pIrp->IoStatus.Status;
7071 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7077 if( pCacheFileObject != NULL)
7079 AFSReleaseCacheFileObject( pCacheFileObject);
7085 if( pIrp->MdlAddress != NULL)
7088 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7091 MmUnlockPages( pIrp->MdlAddress);
7094 IoFreeMdl( pIrp->MdlAddress);
7097 pIrp->MdlAddress = NULL;
7111 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7116 UNREFERENCED_PARAMETER(Irp);
7117 UNREFERENCED_PARAMETER(DeviceObject);
7118 KEVENT *pEvent = (KEVENT *)Context;
7124 return STATUS_MORE_PROCESSING_REQUIRED;
7128 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7131 BOOLEAN bIsEmpty = FALSE;
7132 AFSDirectoryCB *pDirEntry = NULL;
7137 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7142 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7145 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7147 while( pDirEntry != NULL)
7150 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7151 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7159 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7164 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7171 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7172 IN AFSDirectoryCB *DirEntry)
7175 NTSTATUS ntStatus = STATUS_SUCCESS;
7180 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7183 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7184 AFS_TRACE_LEVEL_VERBOSE,
7185 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7187 &DirEntry->NameInformation.FileName));
7189 try_return( ntStatus);
7192 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7195 // Remove the entry from the parent tree
7198 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7199 AFS_TRACE_LEVEL_VERBOSE,
7200 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7202 &DirEntry->NameInformation.FileName));
7204 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7207 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7208 AFS_TRACE_LEVEL_VERBOSE,
7209 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7211 &DirEntry->NameInformation.FileName));
7213 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7216 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7220 // From the short name tree
7223 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7224 AFS_TRACE_LEVEL_VERBOSE,
7225 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7227 &DirEntry->NameInformation.FileName));
7229 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7232 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7235 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7236 AFS_TRACE_LEVEL_VERBOSE,
7237 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7239 &DirEntry->NameInformation.FileName));
7241 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7243 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7254 AFSGetAuthenticationId()
7257 LARGE_INTEGER liAuthId = {0,0};
7258 NTSTATUS ntStatus = STATUS_SUCCESS;
7259 PACCESS_TOKEN hToken = NULL;
7260 PTOKEN_STATISTICS pTokenInfo = NULL;
7261 BOOLEAN bCopyOnOpen = FALSE;
7262 BOOLEAN bEffectiveOnly = FALSE;
7263 BOOLEAN bPrimaryToken = FALSE;
7264 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7269 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7272 &stImpersonationLevel);
7277 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7282 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7283 AFS_TRACE_LEVEL_ERROR,
7284 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
7286 try_return( ntStatus);
7289 bPrimaryToken = TRUE;
7292 ntStatus = SeQueryInformationToken( hToken,
7294 (PVOID *)&pTokenInfo);
7296 if( !NT_SUCCESS( ntStatus))
7299 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7300 AFS_TRACE_LEVEL_ERROR,
7301 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
7304 try_return( ntStatus);
7307 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7308 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7310 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7311 AFS_TRACE_LEVEL_VERBOSE,
7312 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7313 liAuthId.QuadPart));
7323 PsDereferenceImpersonationToken( hToken);
7328 PsDereferencePrimaryToken( hToken);
7332 if( pTokenInfo != NULL)
7335 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7343 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7347 UNREFERENCED_PARAMETER(Fcb);
7348 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7350 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7353 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7355 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7358 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7360 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7363 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7365 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7368 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7370 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7377 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7380 BOOLEAN bIsValid = TRUE;
7382 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7384 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7386 while( pCurrentDirEntry != NULL)
7389 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7393 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7398 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7399 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7402 if( pDirEntry == NULL)
7409 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7412 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
7415 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7417 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7419 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7428 AFSReferenceCacheFileObject()
7431 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7432 FILE_OBJECT *pCacheFileObject = NULL;
7434 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7437 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7439 if( pCacheFileObject != NULL)
7441 ObReferenceObject( pCacheFileObject);
7444 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7446 return pCacheFileObject;
7450 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7453 ASSERT( CacheFileObject != NULL);
7455 ObDereferenceObject( CacheFileObject);
7461 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7464 NTSTATUS ntStatus = STATUS_SUCCESS;
7465 AFSDeviceExt *pControlDevExt = NULL;
7466 ULONG ulTimeIncrement = 0;
7472 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7474 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7476 AFSServerName = LibraryInit->AFSServerName;
7478 AFSMountRootName = LibraryInit->AFSMountRootName;
7480 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7483 // Callbacks in the framework
7486 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7488 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7490 AFSDebugTraceFnc = AFSDbgLogMsg;
7492 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7494 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7496 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
7498 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7500 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7502 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7504 if( LibraryInit->AFSCacheBaseAddress != NULL)
7507 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7509 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7511 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7515 // Initialize some flush parameters
7518 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7520 ulTimeIncrement = KeQueryTimeIncrement();
7522 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7523 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7524 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7525 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7526 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7529 // Initialize the global root entry
7532 ntStatus = AFSInitVolume( NULL,
7533 &LibraryInit->GlobalRootFid,
7534 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
7537 if( !NT_SUCCESS( ntStatus))
7540 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7541 AFS_TRACE_LEVEL_ERROR,
7542 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7545 try_return( ntStatus);
7548 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7551 if( !NT_SUCCESS( ntStatus))
7554 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7555 AFS_TRACE_LEVEL_ERROR,
7556 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7559 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7560 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7562 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7563 AFS_TRACE_LEVEL_VERBOSE,
7564 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7568 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7570 try_return( ntStatus);
7574 // Update the node type code to AFS_ROOT_ALL
7577 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7579 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7582 // Invalidate all known volumes since contact with the service and therefore
7583 // the file server was lost.
7586 AFSInvalidateAllVolumes();
7589 // Drop the locks acquired above
7592 AFSInitVolumeWorker( AFSGlobalRoot);
7594 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7595 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7597 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7598 AFS_TRACE_LEVEL_VERBOSE,
7599 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7603 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7605 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7619 NTSTATUS ntStatus = STATUS_SUCCESS;
7620 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7626 if( AFSGlobalDotDirEntry != NULL)
7629 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
7630 AFS_OBJECT_REFERENCE_GLOBAL);
7632 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7633 AFS_TRACE_LEVEL_VERBOSE,
7634 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7635 AFSGlobalDotDirEntry->ObjectInformation,
7638 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
7640 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7642 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7644 ExFreePool( AFSGlobalDotDirEntry);
7646 AFSGlobalDotDirEntry = NULL;
7649 if( AFSGlobalDotDotDirEntry != NULL)
7652 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
7653 AFS_OBJECT_REFERENCE_GLOBAL);
7655 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7656 AFS_TRACE_LEVEL_VERBOSE,
7657 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7658 AFSGlobalDotDotDirEntry->ObjectInformation,
7661 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
7663 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7665 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7667 ExFreePool( AFSGlobalDotDotDirEntry);
7669 AFSGlobalDotDotDirEntry = NULL;
7672 if( AFSSpecialShareNames != NULL)
7675 pDirNode = AFSSpecialShareNames;
7677 while( pDirNode != NULL)
7680 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7682 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
7683 AFS_OBJECT_REFERENCE_GLOBAL);
7685 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7686 AFS_TRACE_LEVEL_VERBOSE,
7687 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7688 pDirNode->ObjectInformation,
7691 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
7693 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7695 ExFreePool( pDirNode->NonPaged);
7697 ExFreePool( pDirNode);
7699 pDirNode = pLastDirNode;
7702 AFSSpecialShareNames = NULL;
7710 AFSDefaultLogMsg( IN ULONG Subsystem,
7716 UNREFERENCED_PARAMETER(Subsystem);
7717 UNREFERENCED_PARAMETER(Level);
7718 NTSTATUS ntStatus = STATUS_SUCCESS;
7720 char chDebugBuffer[ 256];
7725 va_start( va_args, Format);
7727 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7732 if( NT_SUCCESS( ntStatus))
7734 DbgPrint( chDebugBuffer);
7744 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7745 IN ULONG InputBufferLength,
7746 IN AFSStatusInfoCB *StatusInfo,
7747 OUT ULONG *ReturnLength)
7750 NTSTATUS ntStatus = STATUS_SUCCESS;
7751 AFSVolumeCB *pVolumeCB = NULL;
7752 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7753 AFSVolumeCB *pNewVolumeCB = NULL;
7754 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7755 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7756 AFSObjectInfoCB *pObjectInfo = NULL;
7757 ULONGLONG ullIndex = 0;
7758 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7759 AFSNameArrayHdr *pNameArray = NULL;
7760 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7761 AFSDirectoryCB *pNewParentDirEntry = NULL;
7768 // If we are given a FID then look up the entry by that, otherwise
7772 if( GetStatusInfo->FileID.Cell != 0 &&
7773 GetStatusInfo->FileID.Volume != 0 &&
7774 GetStatusInfo->FileID.Vnode != 0 &&
7775 GetStatusInfo->FileID.Unique != 0)
7778 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7781 // Locate the volume node
7784 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7786 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7788 (AFSBTreeEntry **)&pVolumeCB);
7790 if( pVolumeCB != NULL)
7793 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
7795 lCount = AFSVolumeIncrement( pVolumeCB,
7796 VolumeReferenceReason);
7798 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7799 AFS_TRACE_LEVEL_VERBOSE,
7800 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
7802 VolumeReferenceReason,
7806 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7808 if( !NT_SUCCESS( ntStatus) ||
7811 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7814 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
7817 pObjectInfo = &pVolumeCB->ObjectInformation;
7819 lCount = AFSObjectInfoIncrement( pObjectInfo,
7820 AFS_OBJECT_REFERENCE_STATUS);
7822 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7823 AFS_TRACE_LEVEL_VERBOSE,
7824 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
7831 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
7834 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
7836 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
7838 (AFSBTreeEntry **)&pObjectInfo);
7840 if( pObjectInfo != NULL)
7844 // Reference the node so it won't be torn down
7847 lCount = AFSObjectInfoIncrement( pObjectInfo,
7848 AFS_OBJECT_REFERENCE_STATUS);
7850 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7851 AFS_TRACE_LEVEL_VERBOSE,
7852 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
7857 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
7859 if( !NT_SUCCESS( ntStatus) ||
7860 pObjectInfo == NULL)
7862 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7869 if( GetStatusInfo->FileNameLength == 0 ||
7870 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
7872 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7875 uniFullPathName.Length = GetStatusInfo->FileNameLength;
7876 uniFullPathName.MaximumLength = uniFullPathName.Length;
7878 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
7881 // This name should begin with the \afs server so parse it off and check it
7884 FsRtlDissectName( uniFullPathName,
7888 if( RtlCompareUnicodeString( &uniComponentName,
7892 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
7893 AFS_TRACE_LEVEL_ERROR,
7894 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
7897 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
7900 uniFullPathName = uniRemainingPath;
7902 uniParsedName = uniFullPathName;
7908 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7911 if( pNameArray == NULL)
7913 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7916 pVolumeCB = AFSGlobalRoot;
7918 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7921 // Increment the ref count on the volume and dir entry for correct processing below
7924 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
7926 lCount = AFSVolumeIncrement( pVolumeCB,
7927 VolumeReferenceReason);
7929 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7930 AFS_TRACE_LEVEL_VERBOSE,
7931 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
7933 VolumeReferenceReason,
7936 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
7938 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7939 AFS_TRACE_LEVEL_VERBOSE,
7940 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7941 &pParentDirEntry->NameInformation.FileName,
7946 ntStatus = AFSLocateNameEntry( NULL,
7951 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
7952 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
7956 &NewVolumeReferenceReason,
7957 &pNewParentDirEntry,
7961 if ( pNewVolumeCB != NULL)
7965 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
7966 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
7967 // the reference on pVolumeCB that was held prior to the call.
7968 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
7969 // will be released second.
7972 lCount = AFSVolumeDecrement( pVolumeCB,
7973 VolumeReferenceReason);
7975 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7976 AFS_TRACE_LEVEL_VERBOSE,
7977 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
7979 VolumeReferenceReason,
7982 pVolumeCB = pNewVolumeCB;
7984 pNewVolumeCB = NULL;
7986 VolumeReferenceReason = NewVolumeReferenceReason;
7988 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7992 // AFSLocateNameEntry does not alter the reference count of
7993 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
7994 // a reference held.
7997 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
7999 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8000 AFS_TRACE_LEVEL_VERBOSE,
8001 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8002 &pParentDirEntry->NameInformation.FileName,
8006 pParentDirEntry = pNewParentDirEntry;
8008 pNewParentDirEntry = NULL;
8010 if( !NT_SUCCESS( ntStatus) ||
8011 ntStatus == STATUS_REPARSE)
8016 try_return( ntStatus);
8019 pObjectInfo = pDirectoryEntry->ObjectInformation;
8021 lCount = AFSObjectInfoIncrement( pObjectInfo,
8022 AFS_OBJECT_REFERENCE_STATUS);
8024 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8025 AFS_TRACE_LEVEL_VERBOSE,
8026 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8032 // At this point we have an object info block, return the information
8035 StatusInfo->FileId = pObjectInfo->FileId;
8037 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8039 StatusInfo->Expiration = pObjectInfo->Expiration;
8041 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8043 StatusInfo->FileType = pObjectInfo->FileType;
8045 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8047 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8049 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8051 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8053 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8055 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8057 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8059 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8061 StatusInfo->EaSize = pObjectInfo->EaSize;
8063 StatusInfo->Links = pObjectInfo->Links;
8066 // Return the information length
8069 *ReturnLength = sizeof( AFSStatusInfoCB);
8073 if( pDirectoryEntry != NULL)
8076 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8078 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8079 AFS_TRACE_LEVEL_VERBOSE,
8080 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8081 &pDirectoryEntry->NameInformation.FileName,
8086 ASSERT( lCount >= 0);
8089 if ( pParentDirEntry != NULL)
8092 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8094 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8095 AFS_TRACE_LEVEL_VERBOSE,
8096 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8097 &pParentDirEntry->NameInformation.FileName,
8102 ASSERT( lCount >= 0);
8105 if( pObjectInfo != NULL)
8108 lCount = AFSObjectInfoDecrement( pObjectInfo,
8109 AFS_OBJECT_REFERENCE_STATUS);
8111 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8112 AFS_TRACE_LEVEL_VERBOSE,
8113 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8118 if( pVolumeCB != NULL)
8121 lCount = AFSVolumeDecrement( pVolumeCB,
8122 VolumeReferenceReason);
8124 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8125 AFS_TRACE_LEVEL_VERBOSE,
8126 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8128 VolumeReferenceReason,
8132 if( pNameArray != NULL)
8135 AFSFreeNameArray( pNameArray);
8143 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8144 IN UNICODE_STRING *ComponentName)
8147 NTSTATUS ntStatus = STATUS_SUCCESS;
8148 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8149 AFSDirectoryCB *pDirEntry = NULL;
8157 // Search for the entry in the parent
8160 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8161 AFS_TRACE_LEVEL_VERBOSE_2,
8162 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8165 ulCRC = AFSGenerateCRC( ComponentName,
8168 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8171 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8175 if( pDirEntry == NULL)
8179 // Missed so perform a case insensitive lookup
8182 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8183 AFS_TRACE_LEVEL_VERBOSE_2,
8184 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8187 ulCRC = AFSGenerateCRC( ComponentName,
8190 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8194 if( pDirEntry == NULL)
8198 // OK, if this component is a valid short name then try
8199 // a lookup in the short name tree
8202 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8203 RtlIsNameLegalDOS8Dot3( ComponentName,
8208 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8209 AFS_TRACE_LEVEL_VERBOSE_2,
8210 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8213 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8220 if( pDirEntry != NULL)
8222 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8224 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8225 AFS_TRACE_LEVEL_VERBOSE,
8226 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8227 &pDirEntry->NameInformation.FileName,
8232 ASSERT( lCount >= 0);
8235 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8237 if( pDirEntry == NULL)
8240 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8241 AFS_TRACE_LEVEL_VERBOSE_2,
8242 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8244 STATUS_OBJECT_NAME_NOT_FOUND));
8246 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8250 // We have the symlink object but previously failed to process it so return access
8254 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8255 AFS_TRACE_LEVEL_VERBOSE_2,
8256 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8259 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8261 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8263 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8264 AFS_TRACE_LEVEL_VERBOSE,
8265 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8266 &pDirEntry->NameInformation.FileName,
8271 ASSERT( lCount >= 0);
8282 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8283 OUT UNICODE_STRING *ComponentName)
8286 NTSTATUS ntStatus = STATUS_SUCCESS;
8287 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8289 uniFullPathName = *FullPathName;
8294 FsRtlDissectName( uniFullPathName,
8298 if( uniRemainingPath.Length == 0)
8303 uniFullPathName = uniRemainingPath;
8306 if( uniComponentName.Length > 0)
8308 *ComponentName = uniComponentName;
8315 AFSDumpTraceFiles_Default()
8321 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8324 BOOLEAN bIsValidName = TRUE;
8330 while( usIndex < FileName->Length/sizeof( WCHAR))
8333 if( FileName->Buffer[ usIndex] == L':' ||
8334 FileName->Buffer[ usIndex] == L'*' ||
8335 FileName->Buffer[ usIndex] == L'?' ||
8336 FileName->Buffer[ usIndex] == L'"' ||
8337 FileName->Buffer[ usIndex] == L'<' ||
8338 FileName->Buffer[ usIndex] == L'>')
8340 bIsValidName = FALSE;
8348 return bIsValidName;
8352 AFSCreateDefaultSecurityDescriptor()
8355 NTSTATUS ntStatus = STATUS_SUCCESS;
8357 ULONG ulSACLSize = 0;
8358 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8359 ULONG ulACESize = 0;
8360 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8361 ULONG ulSDLength = 0;
8362 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8363 PSID pWorldSID = NULL;
8364 ULONG *pulSubAuthority = NULL;
8365 ULONG ulWorldSIDLEngth = 0;
8370 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8372 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8374 AFS_GENERIC_MEMORY_29_TAG);
8376 if( pWorldSID == NULL)
8378 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8380 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8383 RtlZeroMemory( pWorldSID,
8386 RtlInitializeSid( pWorldSID,
8387 &SeWorldSidAuthority,
8390 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8391 *pulSubAuthority = SECURITY_WORLD_RID;
8393 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8396 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8401 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8403 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8405 AFS_GENERIC_MEMORY_29_TAG);
8410 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8412 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8415 RtlZeroMemory( pACE,
8418 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8419 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8420 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8421 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8423 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8425 SeExports->SeLowMandatorySid);
8427 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8428 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8430 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8432 AFS_GENERIC_MEMORY_29_TAG);
8437 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8439 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8442 ntStatus = RtlCreateAcl( pSACL,
8446 if( !NT_SUCCESS( ntStatus))
8449 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8452 try_return( ntStatus);
8455 ntStatus = RtlAddAce( pSACL,
8459 pACE->Header.AceSize);
8461 if( !NT_SUCCESS( ntStatus))
8464 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8467 try_return( ntStatus);
8471 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8472 sizeof( SECURITY_DESCRIPTOR),
8473 AFS_GENERIC_MEMORY_27_TAG);
8475 if( pSecurityDescr == NULL)
8478 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8480 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8483 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8484 SECURITY_DESCRIPTOR_REVISION);
8486 if( !NT_SUCCESS( ntStatus))
8489 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8492 try_return( ntStatus);
8495 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8497 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8502 if( !NT_SUCCESS( ntStatus))
8505 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8508 try_return( ntStatus);
8513 // Add in the group and owner to the SD
8516 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8518 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8522 if( !NT_SUCCESS( ntStatus))
8525 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8528 try_return( ntStatus);
8532 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8536 if( !NT_SUCCESS( ntStatus))
8539 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8542 try_return( ntStatus);
8545 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8548 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8550 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8553 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8555 AFS_GENERIC_MEMORY_27_TAG);
8557 if( pRelativeSecurityDescr == NULL)
8560 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8562 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8565 ulSDLength = PAGE_SIZE;
8567 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8568 pRelativeSecurityDescr,
8571 if( !NT_SUCCESS( ntStatus))
8574 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8577 try_return( ntStatus);
8580 AFSDefaultSD = pRelativeSecurityDescr;
8584 if( !NT_SUCCESS( ntStatus))
8587 if( pRelativeSecurityDescr != NULL)
8589 ExFreePool( pRelativeSecurityDescr);
8593 if( pSecurityDescr != NULL)
8595 ExFreePool( pSecurityDescr);
8608 if( pWorldSID != NULL)
8610 ExFreePool( pWorldSID);
8618 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8619 OUT UNICODE_STRING *ParentPath)
8622 *ParentPath = *FullFileName;
8625 // If the final character is a \, jump over it
8628 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8630 ParentPath->Length -= sizeof( WCHAR);
8633 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8635 ParentPath->Length -= sizeof( WCHAR);
8639 // And the separator
8642 ParentPath->Length -= sizeof( WCHAR);
8648 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8649 IN AFSObjectInfoCB *ObjectInfo,
8650 IN BOOLEAN WriteAccess,
8651 OUT GUID *AuthGroup)
8654 NTSTATUS ntStatus = STATUS_SUCCESS;
8655 GUID stAuthGroup, stZeroAuthGroup;
8656 BOOLEAN bFoundAuthGroup = FALSE;
8657 AFSCcb *pCcb = NULL;
8663 RtlZeroMemory( &stAuthGroup,
8666 RtlZeroMemory( &stZeroAuthGroup,
8672 if( ObjectInfo != NULL &&
8673 ObjectInfo->Fcb != NULL)
8675 pFcb = ObjectInfo->Fcb;
8682 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8685 pCcb = Fcb->CcbListHead;
8687 while( pCcb != NULL)
8691 pCcb->GrantedAccess & FILE_WRITE_DATA)
8693 RtlCopyMemory( &stAuthGroup,
8697 bFoundAuthGroup = TRUE;
8701 else if( pCcb->GrantedAccess & FILE_READ_DATA)
8704 // At least get the read-only access
8707 RtlCopyMemory( &stAuthGroup,
8711 bFoundAuthGroup = TRUE;
8714 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
8717 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
8720 if( !bFoundAuthGroup)
8723 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
8724 (ULONGLONG)PsGetCurrentThreadId(),
8727 if( RtlCompareMemory( &stZeroAuthGroup,
8729 sizeof( GUID)) == sizeof( GUID))
8732 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
8734 try_return( ntStatus = STATUS_ACCESS_DENIED);
8738 RtlCopyMemory( AuthGroup,
8751 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
8752 IN ULONG InvalidateReason)
8755 NTSTATUS ntStatus = STATUS_SUCCESS;
8758 ULONG ulProcessCount = 0;
8765 switch( InvalidateReason)
8768 case AFS_INVALIDATE_DELETED:
8771 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8772 ObjectInfo->Fcb != NULL)
8775 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
8778 ObjectInfo->Links = 0;
8780 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
8782 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
8787 // Clear out the extents
8788 // And get rid of them (note this involves waiting
8789 // for any writes or reads to the cache to complete)
8792 AFSTearDownFcbExtents( ObjectInfo->Fcb,
8795 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
8801 case AFS_INVALIDATE_DATA_VERSION:
8804 LARGE_INTEGER liCurrentOffset = {0,0};
8805 LARGE_INTEGER liFlushLength = {0,0};
8806 ULONG ulFlushLength = 0;
8807 BOOLEAN bLocked = FALSE;
8808 BOOLEAN bExtentsLocked = FALSE;
8809 BOOLEAN bCleanExtents = FALSE;
8811 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8812 ObjectInfo->Fcb != NULL)
8815 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
8820 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
8821 AFS_TRACE_LEVEL_VERBOSE,
8822 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
8823 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
8824 PsGetCurrentThread()));
8826 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
8829 bExtentsLocked = TRUE;
8832 // There are several possibilities here:
8834 // 0. If there are no extents or all of the extents are dirty, do nothing.
8836 // 1. There could be nothing dirty and an open reference count of zero
8837 // in which case we can just tear down all of the extents without
8838 // holding any resources.
8840 // 2. There could be nothing dirty and a non-zero open reference count
8841 // in which case we can issue a CcPurge against the entire file
8842 // while holding just the Fcb Resource.
8844 // 3. There can be dirty extents in which case we need to identify
8845 // the non-dirty ranges and then perform a CcPurge on just the
8846 // non-dirty ranges while holding just the Fcb Resource.
8849 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
8852 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
8855 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
8857 bExtentsLocked = FALSE;
8859 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
8862 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
8866 AFSTearDownFcbExtents( ObjectInfo->Fcb,
8872 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
8873 AFS_TRACE_LEVEL_VERBOSE,
8874 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
8875 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
8876 PsGetCurrentThread()));
8878 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
8881 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
8888 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
8889 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
8895 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
8896 AFS_TRACE_LEVEL_WARNING,
8897 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
8898 ObjectInfo->FileId.Cell,
8899 ObjectInfo->FileId.Volume,
8900 ObjectInfo->FileId.Vnode,
8901 ObjectInfo->FileId.Unique));
8903 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
8908 bCleanExtents = TRUE;
8911 __except( EXCEPTION_EXECUTE_HANDLER)
8914 ntStatus = GetExceptionCode();
8918 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
8919 ObjectInfo->FileId.Cell,
8920 ObjectInfo->FileId.Volume,
8921 ObjectInfo->FileId.Vnode,
8922 ObjectInfo->FileId.Unique,
8925 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
8928 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
8929 AFS_TRACE_LEVEL_VERBOSE,
8930 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
8931 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
8932 PsGetCurrentThread()));
8934 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
8940 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
8942 bExtentsLocked = FALSE;
8944 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
8945 AFS_TRACE_LEVEL_VERBOSE,
8946 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
8947 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
8948 PsGetCurrentThread()));
8950 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
8953 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
8958 // Must build a list of non-dirty ranges from the beginning of the file
8959 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
8960 // ranges. In all but the most extreme random data write scenario there will
8961 // be significantly fewer.
8963 // For each range we need offset and size.
8966 AFSByteRange * ByteRangeList = NULL;
8967 ULONG ulByteRangeCount = 0;
8969 BOOLEAN bPurgeOnClose = FALSE;
8974 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
8977 if ( ByteRangeList != NULL ||
8978 ulByteRangeCount == 0)
8981 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
8988 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
8990 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
8991 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
8992 &ByteRangeList[ulIndex].FileOffset,
8997 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
8998 AFS_TRACE_LEVEL_WARNING,
8999 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9000 ObjectInfo->FileId.Cell,
9001 ObjectInfo->FileId.Volume,
9002 ObjectInfo->FileId.Vnode,
9003 ObjectInfo->FileId.Unique));
9005 bPurgeOnClose = TRUE;
9010 bCleanExtents = TRUE;
9013 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9015 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9017 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9024 // We couldn't allocate the memory to build the purge list
9025 // so just walk the extent list while holding the ExtentsList Resource.
9026 // This could deadlock but we do not have much choice.
9029 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9031 bExtentsLocked = TRUE;
9033 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9037 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9041 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9043 while( ulProcessCount < ulCount)
9045 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9047 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9049 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9050 &pEntry->FileOffset,
9055 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9056 AFS_TRACE_LEVEL_WARNING,
9057 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9058 ObjectInfo->FileId.Cell,
9059 ObjectInfo->FileId.Volume,
9060 ObjectInfo->FileId.Vnode,
9061 ObjectInfo->FileId.Unique));
9063 bPurgeOnClose = TRUE;
9068 bCleanExtents = TRUE;
9072 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9075 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9077 while( liFlushLength.QuadPart > 0)
9080 if( liFlushLength.QuadPart > 512 * 1024000)
9082 ulFlushLength = 512 * 1024000;
9086 ulFlushLength = liFlushLength.LowPart;
9089 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9095 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9096 AFS_TRACE_LEVEL_WARNING,
9097 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9098 ObjectInfo->FileId.Cell,
9099 ObjectInfo->FileId.Volume,
9100 ObjectInfo->FileId.Vnode,
9101 ObjectInfo->FileId.Unique));
9103 bPurgeOnClose = TRUE;
9108 bCleanExtents = TRUE;
9111 liFlushLength.QuadPart -= ulFlushLength;
9115 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9123 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9129 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9130 AFS_TRACE_LEVEL_WARNING,
9131 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9132 ObjectInfo->FileId.Cell,
9133 ObjectInfo->FileId.Volume,
9134 ObjectInfo->FileId.Vnode,
9135 ObjectInfo->FileId.Unique));
9137 bPurgeOnClose = TRUE;
9142 bCleanExtents = TRUE;
9149 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9153 __except( EXCEPTION_EXECUTE_HANDLER)
9156 ntStatus = GetExceptionCode();
9160 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9161 ObjectInfo->FileId.Cell,
9162 ObjectInfo->FileId.Volume,
9163 ObjectInfo->FileId.Vnode,
9164 ObjectInfo->FileId.Unique,
9168 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9169 AFS_TRACE_LEVEL_VERBOSE,
9170 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9171 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9172 PsGetCurrentThread()));
9174 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9178 if ( bExtentsLocked)
9181 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9187 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9193 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9203 // Destroy the reference passed in by the caller to AFSInvalidateObject
9204 // or AFSQueueInvalidateObject
9207 lCount = AFSObjectInfoDecrement( ObjectInfo,
9208 AFS_OBJECT_REFERENCE_INVALIDATION);
9210 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9211 AFS_TRACE_LEVEL_VERBOSE,
9212 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",