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 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
5073 IN ULONG InitialElementCount)
5076 AFSNameArrayHdr *pNameArray = NULL;
5077 AFSNameArrayCB *pCurrentElement = NULL;
5078 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5084 if( InitialElementCount == 0)
5087 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
5090 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
5091 sizeof( AFSNameArrayHdr) +
5092 (InitialElementCount * sizeof( AFSNameArrayCB)),
5093 AFS_NAME_ARRAY_TAG);
5095 if( pNameArray == NULL)
5098 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5099 AFS_TRACE_LEVEL_ERROR,
5100 "AFSInitNameArray Failed to allocate name array\n"));
5102 try_return( pNameArray);
5105 RtlZeroMemory( pNameArray,
5106 sizeof( AFSNameArrayHdr) +
5107 (InitialElementCount * sizeof( AFSNameArrayCB)));
5109 pNameArray->MaxElementCount = InitialElementCount;
5111 if( DirectoryCB != NULL)
5114 pCurrentElement = &pNameArray->ElementArray[ 0];
5116 pNameArray->CurrentEntry = pCurrentElement;
5118 pNameArray->Count = 1;
5120 pNameArray->LinkCount = 0;
5122 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5124 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5125 AFS_TRACE_LEVEL_VERBOSE,
5126 "AFSInitNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5128 &DirectoryCB->NameInformation.FileName,
5132 pCurrentElement->DirectoryCB = DirectoryCB;
5134 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5136 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5138 if( pCurrentElement->FileId.Vnode == 1)
5141 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5144 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5145 AFS_TRACE_LEVEL_VERBOSE,
5146 "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5148 pCurrentElement->DirectoryCB,
5149 pCurrentElement->FileId.Cell,
5150 pCurrentElement->FileId.Volume,
5151 pCurrentElement->FileId.Vnode,
5152 pCurrentElement->FileId.Unique,
5153 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5154 pCurrentElement->DirectoryCB->ObjectInformation->FileType));
5166 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
5167 IN UNICODE_STRING *Path,
5168 IN AFSDirectoryCB *DirectoryCB)
5171 NTSTATUS ntStatus = STATUS_SUCCESS;
5172 AFSNameArrayCB *pCurrentElement = NULL;
5178 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5179 AFS_TRACE_LEVEL_VERBOSE,
5180 "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5184 DirectoryCB->ObjectInformation->FileId.Cell,
5185 DirectoryCB->ObjectInformation->FileId.Volume,
5186 DirectoryCB->ObjectInformation->FileId.Vnode,
5187 DirectoryCB->ObjectInformation->FileId.Unique,
5188 &DirectoryCB->NameInformation.FileName,
5189 DirectoryCB->ObjectInformation->FileType));
5192 // Init some info in the header
5195 pCurrentElement = &NameArray->ElementArray[ 0];
5197 NameArray->CurrentEntry = pCurrentElement;
5200 // The first entry points at the root
5203 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
5205 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5207 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5208 AFS_TRACE_LEVEL_VERBOSE,
5209 "AFSPopulateNameArray [NA:%p] Increment count on volume %wZ DE %p Cnt %d\n",
5211 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5212 pCurrentElement->DirectoryCB,
5215 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
5217 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
5219 pCurrentElement->Flags = 0;
5221 if( pCurrentElement->FileId.Vnode == 1)
5224 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5227 NameArray->Count = 1;
5229 NameArray->LinkCount = 0;
5231 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5232 AFS_TRACE_LEVEL_VERBOSE,
5233 "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5235 pCurrentElement->DirectoryCB,
5236 pCurrentElement->FileId.Cell,
5237 pCurrentElement->FileId.Volume,
5238 pCurrentElement->FileId.Vnode,
5239 pCurrentElement->FileId.Unique,
5240 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5241 pCurrentElement->DirectoryCB->ObjectInformation->FileType));
5244 // If the root is the parent then we are done ...
5247 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
5249 try_return( ntStatus);
5261 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
5262 IN AFSNameArrayHdr *RelatedNameArray,
5263 IN AFSDirectoryCB *DirectoryCB)
5266 NTSTATUS ntStatus = STATUS_SUCCESS;
5267 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
5276 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5277 AFS_TRACE_LEVEL_VERBOSE,
5278 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5282 DirectoryCB->ObjectInformation->FileId.Cell,
5283 DirectoryCB->ObjectInformation->FileId.Volume,
5284 DirectoryCB->ObjectInformation->FileId.Vnode,
5285 DirectoryCB->ObjectInformation->FileId.Unique,
5286 &DirectoryCB->NameInformation.FileName,
5287 DirectoryCB->ObjectInformation->FileType));
5292 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5293 AFS_TRACE_LEVEL_VERBOSE,
5294 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE NULL\n",
5300 // Init some info in the header
5303 pCurrentElement = &NameArray->ElementArray[ 0];
5305 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5307 NameArray->Count = 0;
5309 NameArray->LinkCount = RelatedNameArray->LinkCount;
5312 // Populate the name array with the data from the related array
5318 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5320 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5322 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5324 pCurrentElement->Flags = 0;
5326 if( pCurrentElement->FileId.Vnode == 1)
5329 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5332 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5334 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5335 AFS_TRACE_LEVEL_VERBOSE,
5336 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5338 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5339 pCurrentElement->DirectoryCB,
5342 lCount = InterlockedIncrement( &NameArray->Count);
5344 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5345 AFS_TRACE_LEVEL_VERBOSE,
5346 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5349 pCurrentElement->DirectoryCB,
5350 pCurrentElement->FileId.Cell,
5351 pCurrentElement->FileId.Volume,
5352 pCurrentElement->FileId.Vnode,
5353 pCurrentElement->FileId.Unique,
5354 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5355 pCurrentElement->DirectoryCB->ObjectInformation->FileType));
5357 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5358 NameArray->Count == RelatedNameArray->Count)
5370 pCurrentRelatedElement++;
5373 NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
5380 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5383 NTSTATUS ntStatus = STATUS_SUCCESS;
5384 AFSNameArrayCB *pCurrentElement = NULL;
5385 LONG lCount, lElement;
5390 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5391 AFS_TRACE_LEVEL_VERBOSE,
5392 "AFSFreeNameArray [NA:%p]\n",
5395 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5398 pCurrentElement = &NameArray->ElementArray[ lElement];
5400 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5402 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5403 AFS_TRACE_LEVEL_VERBOSE,
5404 "AFSFreeNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5406 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5407 pCurrentElement->DirectoryCB,
5410 ASSERT( lCount >= 0);
5413 AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
5420 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5421 IN AFSDirectoryCB *DirectoryCB)
5424 NTSTATUS ntStatus = STATUS_SUCCESS;
5425 AFSNameArrayCB *pCurrentElement = NULL;
5431 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5432 AFS_TRACE_LEVEL_VERBOSE,
5433 "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5436 DirectoryCB->ObjectInformation->FileId.Cell,
5437 DirectoryCB->ObjectInformation->FileId.Volume,
5438 DirectoryCB->ObjectInformation->FileId.Vnode,
5439 DirectoryCB->ObjectInformation->FileId.Unique,
5440 &DirectoryCB->NameInformation.FileName,
5441 DirectoryCB->ObjectInformation->FileType));
5443 if( NameArray->Count == (LONG) NameArray->MaxElementCount)
5446 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5447 AFS_TRACE_LEVEL_ERROR,
5448 "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
5451 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5454 for ( lCount = 0; lCount < NameArray->Count; lCount++)
5457 if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
5458 &DirectoryCB->ObjectInformation->FileId) )
5461 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5462 AFS_TRACE_LEVEL_WARNING,
5463 "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
5466 STATUS_ACCESS_DENIED));
5468 try_return( ntStatus = STATUS_ACCESS_DENIED);
5472 if( NameArray->Count > 0)
5475 NameArray->CurrentEntry++;
5479 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5482 pCurrentElement = NameArray->CurrentEntry;
5484 lCount = InterlockedIncrement( &NameArray->Count);
5486 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5488 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5489 AFS_TRACE_LEVEL_VERBOSE,
5490 "AFSInsertNextElement [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5492 &DirectoryCB->NameInformation.FileName,
5496 ASSERT( lCount > 0);
5498 pCurrentElement->DirectoryCB = DirectoryCB;
5500 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5502 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5504 pCurrentElement->Flags = 0;
5506 if( pCurrentElement->FileId.Vnode == 1)
5509 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5512 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5513 AFS_TRACE_LEVEL_VERBOSE,
5514 "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5516 NameArray->Count - 1,
5517 pCurrentElement->DirectoryCB,
5518 pCurrentElement->FileId.Cell,
5519 pCurrentElement->FileId.Volume,
5520 pCurrentElement->FileId.Vnode,
5521 pCurrentElement->FileId.Unique,
5522 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5523 pCurrentElement->DirectoryCB->ObjectInformation->FileType));
5534 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5537 AFSDirectoryCB *pDirectoryCB = NULL;
5538 AFSNameArrayCB *pCurrentElement = NULL;
5539 BOOLEAN bVolumeRoot = FALSE;
5545 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5546 AFS_TRACE_LEVEL_VERBOSE,
5547 "AFSBackupEntry [NA:%p]\n",
5550 if( NameArray->Count == 0)
5553 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5554 AFS_TRACE_LEVEL_ERROR,
5555 "AFSBackupEntry [NA:%p] No more entries\n",
5558 try_return( pCurrentElement);
5561 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->NameArrayReferenceCount);
5563 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5564 AFS_TRACE_LEVEL_VERBOSE,
5565 "AFSBackupEntry [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5567 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5568 NameArray->CurrentEntry->DirectoryCB,
5571 ASSERT( lCount >= 0);
5573 NameArray->CurrentEntry->DirectoryCB = NULL;
5575 lCount = InterlockedDecrement( &NameArray->Count);
5579 NameArray->CurrentEntry = NULL;
5581 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5582 AFS_TRACE_LEVEL_ERROR,
5583 "AFSBackupEntry [NA:%p] No more entries\n",
5589 bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5591 NameArray->CurrentEntry--;
5593 pCurrentElement = NameArray->CurrentEntry;
5595 pDirectoryCB = pCurrentElement->DirectoryCB;
5597 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5598 AFS_TRACE_LEVEL_VERBOSE,
5599 "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5601 NameArray->Count - 1,
5602 pCurrentElement->DirectoryCB,
5603 pCurrentElement->FileId.Cell,
5604 pCurrentElement->FileId.Volume,
5605 pCurrentElement->FileId.Vnode,
5606 pCurrentElement->FileId.Unique,
5607 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5608 pCurrentElement->DirectoryCB->ObjectInformation->FileType));
5611 // If the entry we are removing is a volume root,
5612 // we must remove the mount point entry as well.
5613 // If the NameArray was constructed by checking the
5614 // share name via the service, the name array can
5615 // contain two volume roots in sequence without a
5616 // mount point separating them.
5620 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
5623 pDirectoryCB = AFSBackupEntry( NameArray);
5633 return pDirectoryCB;
5637 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5640 AFSDirectoryCB *pDirEntry = NULL;
5641 AFSNameArrayCB *pElement = NULL;
5646 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5647 AFS_TRACE_LEVEL_VERBOSE,
5648 "AFSGetParentEntry [NA:%p]\n",
5651 if( NameArray->Count == 0 ||
5652 NameArray->Count == 1)
5655 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5656 AFS_TRACE_LEVEL_ERROR,
5657 "AFSGetParentEntry [NA:%p] No more entries\n",
5660 try_return( pDirEntry = NULL);
5663 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5665 pDirEntry = pElement->DirectoryCB;
5667 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5668 AFS_TRACE_LEVEL_VERBOSE,
5669 "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5671 NameArray->Count - 2,
5672 pElement->DirectoryCB,
5673 pElement->FileId.Cell,
5674 pElement->FileId.Volume,
5675 pElement->FileId.Vnode,
5676 pElement->FileId.Unique,
5677 &pElement->DirectoryCB->NameInformation.FileName,
5678 pElement->DirectoryCB->ObjectInformation->FileType));
5689 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5690 IN AFSDirectoryCB *DirectoryCB)
5693 AFSNameArrayCB *pCurrentElement = NULL;
5694 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5695 LONG lCount, lElement;
5700 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5701 AFS_TRACE_LEVEL_VERBOSE,
5702 "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5705 DirectoryCB->ObjectInformation->FileId.Cell,
5706 DirectoryCB->ObjectInformation->FileId.Volume,
5707 DirectoryCB->ObjectInformation->FileId.Vnode,
5708 DirectoryCB->ObjectInformation->FileId.Unique,
5709 &DirectoryCB->NameInformation.FileName,
5710 DirectoryCB->ObjectInformation->FileType));
5713 // Dereference previous name array contents
5716 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5719 pCurrentElement = &NameArray->ElementArray[ lElement];
5721 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->NameArrayReferenceCount);
5723 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5724 AFS_TRACE_LEVEL_VERBOSE,
5725 "AFSResetNameArray [NA:%p] Decrement count on %wZ DE %p Cnt %d\n",
5727 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5728 pCurrentElement->DirectoryCB,
5731 ASSERT( lCount >= 0);
5734 RtlZeroMemory( NameArray,
5735 sizeof( AFSNameArrayHdr) +
5736 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5738 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5740 if( DirectoryCB != NULL)
5743 pCurrentElement = &NameArray->ElementArray[ 0];
5745 NameArray->CurrentEntry = pCurrentElement;
5747 NameArray->Count = 1;
5749 NameArray->LinkCount = 0;
5751 lCount = InterlockedIncrement( &DirectoryCB->NameArrayReferenceCount);
5753 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_REF_COUNTING,
5754 AFS_TRACE_LEVEL_VERBOSE,
5755 "AFSResetNameArray [NA:%p] Increment count on %wZ DE %p Cnt %d\n",
5757 &DirectoryCB->NameInformation.FileName,
5761 pCurrentElement->DirectoryCB = DirectoryCB;
5763 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5765 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5767 pCurrentElement->Flags = 0;
5769 if( pCurrentElement->FileId.Vnode == 1)
5772 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5775 AFSDbgTrace(( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5776 AFS_TRACE_LEVEL_VERBOSE,
5777 "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5779 pCurrentElement->DirectoryCB,
5780 pCurrentElement->FileId.Cell,
5781 pCurrentElement->FileId.Volume,
5782 pCurrentElement->FileId.Vnode,
5783 pCurrentElement->FileId.Unique,
5784 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5785 pCurrentElement->DirectoryCB->ObjectInformation->FileType));
5793 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5796 AFSNameArrayCB *pCurrentElement = NULL;
5798 pCurrentElement = &NameArray->ElementArray[ 0];
5800 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5802 while( pCurrentElement->DirectoryCB != NULL)
5805 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5806 pCurrentElement->FileId.Cell,
5807 pCurrentElement->FileId.Volume,
5808 pCurrentElement->FileId.Vnode,
5809 pCurrentElement->FileId.Unique,
5810 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5815 AFSPrint("AFSDumpNameArray End\n\n");
5821 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5826 // Depending on the type of node, set the event
5829 switch( Fcb->Header.NodeTypeCode)
5832 case AFS_DIRECTORY_FCB:
5837 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5847 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5853 // Depending on the type of node, set the event
5856 switch( Fcb->Header.NodeTypeCode)
5859 case AFS_DIRECTORY_FCB:
5864 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5866 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5876 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5879 BOOLEAN bIsInProcess = FALSE;
5884 if( ObjectInfo->Fcb == NULL)
5887 try_return( bIsInProcess);
5890 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5893 case AFS_DIRECTORY_FCB:
5898 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5901 bIsInProcess = TRUE;
5913 return bIsInProcess;
5917 AFSVerifyVolume( IN ULONGLONG ProcessId,
5918 IN AFSVolumeCB *VolumeCB)
5921 UNREFERENCED_PARAMETER(ProcessId);
5922 UNREFERENCED_PARAMETER(VolumeCB);
5923 NTSTATUS ntStatus = STATUS_SUCCESS;
5930 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5933 NTSTATUS ntStatus = STATUS_SUCCESS;
5934 AFSObjectInfoCB *pObjectInfoCB = NULL;
5935 AFSDirectoryCB *pDirNode = NULL;
5936 ULONG ulEntryLength = 0;
5937 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5943 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5946 if( pObjectInfoCB == NULL)
5949 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5952 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5953 AFS_OBJECT_REFERENCE_DIRENTRY);
5955 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5956 AFS_TRACE_LEVEL_VERBOSE,
5957 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5961 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5963 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5965 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5967 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5971 if( pDirNode == NULL)
5974 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5977 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5978 AFS_TRACE_LEVEL_VERBOSE,
5979 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5982 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5983 sizeof( AFSNonPagedDirectoryCB),
5984 AFS_DIR_ENTRY_NP_TAG);
5986 if( pNonPagedDirEntry == NULL)
5989 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5992 RtlZeroMemory( pDirNode,
5995 RtlZeroMemory( pNonPagedDirEntry,
5996 sizeof( AFSNonPagedDirectoryCB));
5998 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
6000 pDirNode->NonPaged = pNonPagedDirEntry;
6002 pDirNode->ObjectInformation = pObjectInfoCB;
6004 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
6010 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
6012 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
6014 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
6016 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
6018 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
6019 AFSPIOCtlName.Buffer,
6020 pDirNode->NameInformation.FileName.Length);
6022 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
6025 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
6028 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
6029 AFS_TRACE_LEVEL_WARNING,
6030 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
6031 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
6034 try_return( ntStatus = STATUS_REPARSE);
6039 if ( ntStatus != STATUS_SUCCESS)
6042 if ( pDirNode != NULL)
6045 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
6046 AFS_TRACE_LEVEL_VERBOSE,
6047 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
6050 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
6053 if( pNonPagedDirEntry != NULL)
6056 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
6058 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
6061 if ( pObjectInfoCB != NULL)
6064 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
6065 AFS_OBJECT_REFERENCE_DIRENTRY);
6067 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6068 AFS_TRACE_LEVEL_VERBOSE,
6069 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
6073 AFSDeleteObjectInfo( &pObjectInfoCB);
6082 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
6083 IN AFSDirectoryCB *DirectoryCB,
6084 IN UNICODE_STRING *ParentPathName,
6085 IN AFSNameArrayHdr *RelatedNameArray,
6087 OUT AFSFileInfoCB *FileInfo)
6090 NTSTATUS ntStatus = STATUS_SUCCESS;
6091 AFSDirEnumEntry *pDirEntry = NULL;
6092 UNICODE_STRING uniFullPathName = {0};
6093 AFSNameArrayHdr *pNameArray = NULL;
6094 AFSVolumeCB *pVolumeCB = NULL;
6095 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6096 AFSVolumeCB *pNewVolumeCB = NULL;
6097 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6098 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6099 AFSDirectoryCB *pNewParentDirEntry = NULL;
6100 WCHAR *pwchBuffer = NULL;
6101 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6102 ULONG ulNameDifference = 0;
6109 // Retrieve a target name for the entry
6112 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6115 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6118 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6120 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6125 if( !NT_SUCCESS( ntStatus) ||
6126 pDirEntry->TargetNameLength == 0)
6129 if( pDirEntry != NULL)
6132 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6135 try_return( ntStatus);
6138 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6141 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6145 // Update the target name
6148 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6149 &DirectoryCB->Flags,
6150 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6151 (USHORT)pDirEntry->TargetNameLength);
6153 if( !NT_SUCCESS( ntStatus))
6156 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6158 try_return( ntStatus);
6162 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6166 // Need to pass the full path in for parsing.
6169 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
6172 uniFullPathName.Length = 0;
6173 uniFullPathName.MaximumLength = ParentPathName->Length +
6175 DirectoryCB->NameInformation.TargetName.Length;
6177 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6178 uniFullPathName.MaximumLength,
6179 AFS_NAME_BUFFER_SIX_TAG);
6181 if( uniFullPathName.Buffer == NULL)
6184 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6186 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6189 pwchBuffer = uniFullPathName.Buffer;
6191 RtlZeroMemory( uniFullPathName.Buffer,
6192 uniFullPathName.MaximumLength);
6194 RtlCopyMemory( uniFullPathName.Buffer,
6195 ParentPathName->Buffer,
6196 ParentPathName->Length);
6198 uniFullPathName.Length = ParentPathName->Length;
6200 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
6201 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
6204 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
6206 uniFullPathName.Length += sizeof( WCHAR);
6209 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
6210 DirectoryCB->NameInformation.TargetName.Buffer,
6211 DirectoryCB->NameInformation.TargetName.Length);
6213 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
6215 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
6216 uniParsedName.MaximumLength = uniParsedName.Length;
6218 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
6220 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6223 // We populate up to the current parent
6226 if( RelatedNameArray != NULL)
6229 pNameArray = AFSInitNameArray( NULL,
6230 RelatedNameArray->MaxElementCount);
6232 if( pNameArray == NULL)
6235 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6238 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
6245 pNameArray = AFSInitNameArray( NULL,
6248 if( pNameArray == NULL)
6251 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6254 ntStatus = AFSPopulateNameArray( pNameArray,
6259 if( !NT_SUCCESS( ntStatus))
6262 try_return( ntStatus);
6265 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
6267 pParentDirEntry = ParentDirectoryCB;
6272 uniFullPathName.Length = 0;
6273 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6275 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6276 uniFullPathName.MaximumLength,
6277 AFS_NAME_BUFFER_SEVEN_TAG);
6279 if( uniFullPathName.Buffer == NULL)
6282 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6284 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6287 pwchBuffer = uniFullPathName.Buffer;
6289 RtlZeroMemory( uniFullPathName.Buffer,
6290 uniFullPathName.MaximumLength);
6292 RtlCopyMemory( uniFullPathName.Buffer,
6293 DirectoryCB->NameInformation.TargetName.Buffer,
6294 DirectoryCB->NameInformation.TargetName.Length);
6296 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6299 // This name should begin with the \afs server so parse it off and check it
6302 FsRtlDissectName( uniFullPathName,
6306 if( RtlCompareUnicodeString( &uniComponentName,
6311 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6313 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
6314 AFS_TRACE_LEVEL_ERROR,
6315 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
6318 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
6321 uniFullPathName = uniRemainingPath;
6323 uniParsedName = uniFullPathName;
6325 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6327 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6333 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6336 if( pNameArray == NULL)
6339 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6342 pVolumeCB = AFSGlobalRoot;
6344 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6348 // Increment the ref count on the volume and dir entry for correct processing below
6351 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
6353 lCount = AFSVolumeIncrement( pVolumeCB,
6354 VolumeReferenceReason);
6356 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6357 AFS_TRACE_LEVEL_VERBOSE,
6358 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
6360 VolumeReferenceReason,
6363 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6365 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6366 AFS_TRACE_LEVEL_VERBOSE,
6367 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6368 &pParentDirEntry->NameInformation.FileName,
6373 ntStatus = AFSLocateNameEntry( NULL,
6378 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
6382 &NewVolumeReferenceReason,
6383 &pNewParentDirEntry,
6387 if ( pNewVolumeCB != NULL)
6390 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6391 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6392 // the reference on pVolumeCB that was held prior to the call.
6393 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6394 // will be released second.
6397 lCount = AFSVolumeDecrement( pVolumeCB,
6398 VolumeReferenceReason);
6400 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6401 AFS_TRACE_LEVEL_VERBOSE,
6402 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
6404 VolumeReferenceReason,
6407 pVolumeCB = pNewVolumeCB;
6409 pNewVolumeCB = NULL;
6411 VolumeReferenceReason = NewVolumeReferenceReason;
6413 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6417 // AFSLocateNameEntry does not alter the reference count of
6418 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6419 // a reference held.
6422 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6424 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6425 AFS_TRACE_LEVEL_VERBOSE,
6426 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
6427 &pParentDirEntry->NameInformation.FileName,
6431 pParentDirEntry = pNewParentDirEntry;
6433 pNewParentDirEntry = NULL;
6435 if( !NT_SUCCESS( ntStatus) ||
6436 ntStatus == STATUS_REPARSE)
6439 try_return( ntStatus);
6443 // Store off the information
6446 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6449 // Check for the mount point being returned
6452 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
6453 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6456 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6458 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
6461 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6464 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6469 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6473 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6475 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6477 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6479 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6481 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6483 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6487 if( pDirEntry != NULL)
6490 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6493 if( pDirectoryEntry != NULL)
6496 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6498 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6499 AFS_TRACE_LEVEL_VERBOSE,
6500 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6501 &pDirectoryEntry->NameInformation.FileName,
6506 ASSERT( lCount >= 0);
6509 if ( pParentDirEntry != NULL)
6512 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6514 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6515 AFS_TRACE_LEVEL_VERBOSE,
6516 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6517 &pParentDirEntry->NameInformation.FileName,
6522 ASSERT( lCount >= 0);
6525 if( pVolumeCB != NULL)
6528 lCount = AFSVolumeDecrement( pVolumeCB,
6529 VolumeReferenceReason);
6531 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6532 AFS_TRACE_LEVEL_VERBOSE,
6533 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
6535 VolumeReferenceReason,
6539 if( pNameArray != NULL)
6542 AFSFreeNameArray( pNameArray);
6545 if( pwchBuffer != NULL)
6549 // Always free the buffer that we allocated as AFSLocateNameEntry
6550 // will not free it. If uniFullPathName.Buffer was allocated by
6551 // AFSLocateNameEntry, then we must free that as well.
6552 // Check that the uniFullPathName.Buffer in the string is not the same
6553 // offset by the length of the server name
6556 if( uniFullPathName.Length > 0 &&
6557 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6560 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6563 AFSExFreePoolWithTag( pwchBuffer, 0);
6571 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6572 IN ULONGLONG HashIndex)
6575 NTSTATUS ntStatus = STATUS_SUCCESS;
6576 AFSObjectInfoCB *pObjectInfo = NULL;
6582 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6583 sizeof( AFSObjectInfoCB),
6584 AFS_OBJECT_INFO_TAG);
6586 if( pObjectInfo == NULL)
6589 try_return( pObjectInfo);
6592 RtlZeroMemory( pObjectInfo,
6593 sizeof( AFSObjectInfoCB));
6595 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6596 sizeof( AFSNonPagedObjectInfoCB),
6597 AFS_NP_OBJECT_INFO_TAG);
6599 if( pObjectInfo->NonPagedInfo == NULL)
6602 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6604 try_return( pObjectInfo = NULL);
6607 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6609 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6611 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6613 if( ParentObjectInfo != NULL)
6616 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6618 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6620 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6622 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6623 AFS_OBJECT_REFERENCE_CHILD);
6625 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6626 AFS_TRACE_LEVEL_VERBOSE,
6627 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6633 // Initialize the access time
6636 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6641 ASSERT( ParentObjectInfo);
6644 // Insert the entry into the object tree and list
6647 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6649 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6652 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6657 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6658 &pObjectInfo->TreeEntry);
6660 ASSERT( NT_SUCCESS( ntStatus));
6664 // And the object list in the volume
6667 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6670 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6675 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6677 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6680 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6683 // Indicate the object is in the hash tree and linked list in the volume
6686 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6698 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6704 if ( ObjectInfo->ObjectReferenceCount == 0)
6707 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6710 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6715 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6718 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6723 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6725 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6730 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6732 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6738 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6742 LONG lCount, lCount2;
6744 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6747 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6752 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6754 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6756 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6759 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6762 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6764 ASSERT( lCount2 >= 0);
6766 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6772 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6773 IN AFSFileID *FileId)
6775 DWORD ntStatus = STATUS_SUCCESS;
6777 AFSObjectInfoCB *pObjectInfo = NULL;
6780 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6783 pObjectInfo = &VolumeCB->ObjectInformation;
6788 AFSAcquireExcl( VolumeCB->ObjectInfoTree.TreeLock,
6791 ullIndex = AFSCreateLowIndex( FileId);
6793 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6795 (AFSBTreeEntry **)&pObjectInfo);
6797 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6800 if ( NT_SUCCESS( ntStatus)) {
6802 lCount = AFSObjectInfoIncrement( pObjectInfo,
6803 AFS_OBJECT_REFERENCE_FIND);
6805 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6806 AFS_TRACE_LEVEL_VERBOSE,
6807 "AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
6816 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6820 lCount = AFSObjectInfoDecrement( *ppObjectInfo,
6821 AFS_OBJECT_REFERENCE_FIND);
6823 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6824 AFS_TRACE_LEVEL_VERBOSE,
6825 "AFSReleaseObjectInfo Decrement count on object %p Cnt %d\n",
6829 *ppObjectInfo = NULL;
6833 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6836 BOOLEAN bAcquiredTreeLock = FALSE;
6837 AFSObjectInfoCB *pObjectInfo = NULL;
6838 BOOLEAN bHeldInService;
6839 AFSObjectInfoCB * pParentObjectInfo = NULL;
6843 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
6847 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6848 // embedded in the VolumeCB.
6856 pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
6860 if ( pObjectInfo == NULL)
6866 ASSERT( *ppObjectInfo == NULL);
6868 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6870 bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6872 if( !ExIsResourceAcquiredExclusiveLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6875 ASSERT( !ExIsResourceAcquiredLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6877 AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6880 bAcquiredTreeLock = TRUE;
6883 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6886 pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
6887 &pObjectInfo->ParentFileId);
6891 // Remove it from the tree and list if it was inserted
6894 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6897 AFSRemoveHashEntry( &pObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6898 &pObjectInfo->TreeEntry);
6901 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6904 if( pObjectInfo->ListEntry.fLink == NULL)
6907 pObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6909 if( pObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6912 pObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6918 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6921 if( pObjectInfo->ListEntry.bLink == NULL)
6924 pObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6926 if( pObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6929 pObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6935 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6939 if( pParentObjectInfo != NULL)
6942 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6944 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6945 AFS_OBJECT_REFERENCE_CHILD);
6947 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6948 AFS_TRACE_LEVEL_VERBOSE,
6949 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6953 AFSReleaseObjectInfo( &pParentObjectInfo);
6956 if( bAcquiredTreeLock)
6959 AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6965 FileId = pObjectInfo->FileId;
6968 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6970 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6972 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6974 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6977 // Release the fid in the service
6983 AFSReleaseFid( &FileId);
6990 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6991 OUT AFSDirectoryCB **TargetDirEntry)
6994 NTSTATUS ntStatus = STATUS_SUCCESS;
6995 AFSDirEnumEntry *pDirEntry = NULL;
6996 UNICODE_STRING uniFullPathName = {0};
6997 AFSNameArrayHdr *pNameArray = NULL;
6998 AFSVolumeCB *pVolumeCB = NULL;
6999 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7000 AFSVolumeCB *pNewVolumeCB = NULL;
7001 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7002 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7003 AFSDirectoryCB *pNewParentDirEntry = NULL;
7004 WCHAR *pwchBuffer = NULL;
7005 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
7006 ULONG ulNameDifference = 0;
7013 ntStatus = AFSRetrieveValidAuthGroup( NULL,
7014 DirectoryCB->ObjectInformation,
7018 if( !NT_SUCCESS( ntStatus))
7020 try_return( ntStatus);
7024 // Retrieve a target name for the entry
7027 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
7030 if( DirectoryCB->NameInformation.TargetName.Length == 0)
7033 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7035 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
7040 if( !NT_SUCCESS( ntStatus) ||
7041 pDirEntry->TargetNameLength == 0)
7044 if( pDirEntry != NULL)
7047 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
7050 try_return( ntStatus);
7053 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
7056 if( DirectoryCB->NameInformation.TargetName.Length == 0)
7060 // Update the target name
7063 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
7064 &DirectoryCB->Flags,
7065 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
7066 (USHORT)pDirEntry->TargetNameLength);
7068 if( !NT_SUCCESS( ntStatus))
7071 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7073 try_return( ntStatus);
7077 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
7081 // Need to pass the full path in for parsing.
7084 uniFullPathName.Length = 0;
7085 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
7087 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7088 uniFullPathName.MaximumLength,
7089 AFS_NAME_BUFFER_EIGHT_TAG);
7091 if( uniFullPathName.Buffer == NULL)
7094 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7096 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7099 pwchBuffer = uniFullPathName.Buffer;
7101 RtlZeroMemory( uniFullPathName.Buffer,
7102 uniFullPathName.MaximumLength);
7104 RtlCopyMemory( uniFullPathName.Buffer,
7105 DirectoryCB->NameInformation.TargetName.Buffer,
7106 DirectoryCB->NameInformation.TargetName.Length);
7108 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
7111 // This name should begin with the \afs server so parse it off and chech it
7114 FsRtlDissectName( uniFullPathName,
7118 if( RtlCompareUnicodeString( &uniComponentName,
7124 // Try evaluating the full path
7127 uniFullPathName.Buffer = pwchBuffer;
7129 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
7131 uniFullPathName.MaximumLength = uniFullPathName.Length;
7136 uniFullPathName = uniRemainingPath;
7139 uniParsedName = uniFullPathName;
7141 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
7143 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
7149 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7152 if( pNameArray == NULL)
7155 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7158 pVolumeCB = AFSGlobalRoot;
7160 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7162 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
7164 lCount = AFSVolumeIncrement( pVolumeCB,
7165 VolumeReferenceReason);
7167 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7168 AFS_TRACE_LEVEL_VERBOSE,
7169 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
7171 VolumeReferenceReason,
7174 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
7176 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7177 AFS_TRACE_LEVEL_VERBOSE,
7178 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7179 &pParentDirEntry->NameInformation.FileName,
7184 ntStatus = AFSLocateNameEntry( NULL,
7193 &VolumeReferenceReason,
7194 &pNewParentDirEntry,
7198 if ( pNewVolumeCB != NULL)
7201 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
7202 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
7203 // the reference on pVolumeCB that was held prior to the call.
7204 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
7205 // will be released second.
7208 lCount = AFSVolumeDecrement( pVolumeCB,
7209 VolumeReferenceReason);
7211 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7212 AFS_TRACE_LEVEL_VERBOSE,
7213 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
7215 VolumeReferenceReason,
7218 pVolumeCB = pNewVolumeCB;
7220 pNewVolumeCB = NULL;
7222 VolumeReferenceReason = NewVolumeReferenceReason;
7224 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
7228 // AFSLocateNameEntry does not alter the reference count of
7229 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
7230 // a reference held.
7233 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
7235 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7236 AFS_TRACE_LEVEL_VERBOSE,
7237 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
7238 &pParentDirEntry->NameInformation.FileName,
7242 pParentDirEntry = pNewParentDirEntry;
7244 pNewParentDirEntry = NULL;
7246 if( !NT_SUCCESS( ntStatus) ||
7247 ntStatus == STATUS_REPARSE)
7252 try_return( ntStatus);
7256 // Pass back the target dir entry for this request
7257 // The caller must release the DirOpenReferenceCount
7260 *TargetDirEntry = pDirectoryEntry;
7262 pDirectoryEntry = NULL;
7266 if( pDirectoryEntry != NULL)
7269 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
7271 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7272 AFS_TRACE_LEVEL_VERBOSE,
7273 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7274 &pDirectoryEntry->NameInformation.FileName,
7279 ASSERT( lCount >= 0);
7282 if ( pParentDirEntry != NULL)
7285 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
7287 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7288 AFS_TRACE_LEVEL_VERBOSE,
7289 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7290 &pParentDirEntry->NameInformation.FileName,
7295 ASSERT( lCount >= 0);
7298 if( pDirEntry != NULL)
7301 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
7304 if( pVolumeCB != NULL)
7307 lCount = AFSVolumeDecrement( pVolumeCB,
7308 VolumeReferenceReason);
7310 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7311 AFS_TRACE_LEVEL_VERBOSE,
7312 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
7314 VolumeReferenceReason,
7318 if( pNameArray != NULL)
7321 AFSFreeNameArray( pNameArray);
7324 if( pwchBuffer != NULL)
7328 // Always free the buffer that we allocated as AFSLocateNameEntry
7329 // will not free it. If uniFullPathName.Buffer was allocated by
7330 // AFSLocateNameEntry, then we must free that as well.
7331 // Check that the uniFullPathName.Buffer in the string is not the same
7332 // offset by the length of the server name
7335 if( uniFullPathName.Length > 0 &&
7336 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
7339 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
7342 AFSExFreePoolWithTag( pwchBuffer, 0);
7350 AFSCleanupFcb( IN AFSFcb *Fcb,
7351 IN BOOLEAN ForceFlush)
7354 NTSTATUS ntStatus = STATUS_SUCCESS;
7355 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
7356 LARGE_INTEGER liTime;
7357 IO_STATUS_BLOCK stIoStatus;
7362 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7364 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7366 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
7369 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
7370 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7373 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7374 AFS_TRACE_LEVEL_VERBOSE,
7375 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
7376 &Fcb->NPFcb->Resource,
7377 PsGetCurrentThread()));
7379 AFSAcquireShared( &Fcb->NPFcb->Resource,
7382 if( Fcb->OpenReferenceCount > 0)
7385 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7386 AFS_TRACE_LEVEL_VERBOSE,
7387 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7388 &Fcb->NPFcb->SectionObjectResource,
7389 PsGetCurrentThread()));
7391 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
7397 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7402 if( !NT_SUCCESS( stIoStatus.Status))
7405 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7406 AFS_TRACE_LEVEL_ERROR,
7407 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7408 Fcb->ObjectInformation->FileId.Cell,
7409 Fcb->ObjectInformation->FileId.Volume,
7410 Fcb->ObjectInformation->FileId.Vnode,
7411 Fcb->ObjectInformation->FileId.Unique,
7413 stIoStatus.Information));
7415 ntStatus = stIoStatus.Status;
7418 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7421 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7427 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7428 AFS_TRACE_LEVEL_WARNING,
7429 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
7430 Fcb->ObjectInformation->FileId.Cell,
7431 Fcb->ObjectInformation->FileId.Volume,
7432 Fcb->ObjectInformation->FileId.Vnode,
7433 Fcb->ObjectInformation->FileId.Unique));
7435 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7439 __except( EXCEPTION_EXECUTE_HANDLER)
7442 ntStatus = GetExceptionCode();
7446 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7447 Fcb->ObjectInformation->FileId.Cell,
7448 Fcb->ObjectInformation->FileId.Volume,
7449 Fcb->ObjectInformation->FileId.Vnode,
7450 Fcb->ObjectInformation->FileId.Unique,
7453 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7456 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7457 AFS_TRACE_LEVEL_VERBOSE,
7458 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7459 &Fcb->NPFcb->SectionObjectResource,
7460 PsGetCurrentThread()));
7462 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7465 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7466 AFS_TRACE_LEVEL_VERBOSE,
7467 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
7468 &Fcb->NPFcb->Resource,
7469 PsGetCurrentThread()));
7471 AFSReleaseResource( &Fcb->NPFcb->Resource);
7474 // Wait for any currently running flush or release requests to complete
7477 AFSWaitOnQueuedFlushes( Fcb);
7480 // Now perform another flush on the file
7483 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7487 AFSReleaseExtentsWithFlush( Fcb,
7493 if( Fcb->OpenReferenceCount == 0 ||
7494 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7495 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7498 AFSTearDownFcbExtents( Fcb,
7502 try_return( ntStatus);
7505 KeQueryTickCount( &liTime);
7508 // First up are there dirty extents in the cache to flush?
7511 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7512 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7516 // The file has been marked as invalid. Dump it
7519 AFSTearDownFcbExtents( Fcb,
7522 else if( ForceFlush ||
7523 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7524 Fcb->Specific.File.ExtentCount) &&
7525 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7526 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7528 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7530 Fcb->OpenReferenceCount == 0)
7533 AFSReleaseExtentsWithFlush( Fcb,
7540 // If there are extents and they haven't been used recently *and*
7541 // are not being used
7545 ( 0 != Fcb->Specific.File.ExtentCount &&
7546 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7547 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7548 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7551 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7552 AFS_TRACE_LEVEL_VERBOSE,
7553 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7554 &Fcb->NPFcb->SectionObjectResource,
7555 PsGetCurrentThread()));
7557 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7563 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7568 if( !NT_SUCCESS( stIoStatus.Status))
7571 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7572 AFS_TRACE_LEVEL_ERROR,
7573 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7574 Fcb->ObjectInformation->FileId.Cell,
7575 Fcb->ObjectInformation->FileId.Volume,
7576 Fcb->ObjectInformation->FileId.Vnode,
7577 Fcb->ObjectInformation->FileId.Unique,
7579 stIoStatus.Information));
7581 ntStatus = stIoStatus.Status;
7585 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7588 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7594 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7595 AFS_TRACE_LEVEL_WARNING,
7596 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7597 Fcb->ObjectInformation->FileId.Cell,
7598 Fcb->ObjectInformation->FileId.Volume,
7599 Fcb->ObjectInformation->FileId.Vnode,
7600 Fcb->ObjectInformation->FileId.Unique));
7602 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7606 __except( EXCEPTION_EXECUTE_HANDLER)
7609 ntStatus = GetExceptionCode();
7613 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7614 Fcb->ObjectInformation->FileId.Cell,
7615 Fcb->ObjectInformation->FileId.Volume,
7616 Fcb->ObjectInformation->FileId.Vnode,
7617 Fcb->ObjectInformation->FileId.Unique,
7621 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7622 AFS_TRACE_LEVEL_VERBOSE,
7623 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7624 &Fcb->NPFcb->SectionObjectResource,
7625 PsGetCurrentThread()));
7627 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7629 if( Fcb->OpenReferenceCount <= 0)
7633 // Tear em down we'll not be needing them again
7636 AFSTearDownFcbExtents( Fcb,
7643 ntStatus = STATUS_RETRY;
7656 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7657 IN UNICODE_STRING *NewFileName)
7660 NTSTATUS ntStatus = STATUS_SUCCESS;
7661 WCHAR *pTmpBuffer = NULL;
7666 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7669 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7672 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7674 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7676 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7680 // OK, we need to allocate a new name buffer
7683 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7684 NewFileName->Length,
7685 AFS_NAME_BUFFER_NINE_TAG);
7687 if( pTmpBuffer == NULL)
7690 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7693 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7695 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7697 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7700 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7702 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7703 NewFileName->Buffer,
7704 NewFileName->Length);
7715 AFSReadCacheFile( IN void *ReadBuffer,
7716 IN LARGE_INTEGER *ReadOffset,
7717 IN ULONG RequestedDataLength,
7718 IN OUT PULONG BytesRead)
7721 NTSTATUS ntStatus = STATUS_SUCCESS;
7724 PIO_STACK_LOCATION pIoStackLocation = NULL;
7725 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7726 FILE_OBJECT *pCacheFileObject = NULL;
7731 pCacheFileObject = AFSReferenceCacheFileObject();
7733 if( pCacheFileObject == NULL)
7735 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7738 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7741 // Initialize the event
7744 KeInitializeEvent( &kEvent,
7745 SynchronizationEvent,
7749 // Allocate an irp for this request. This could also come from a
7750 // private pool, for instance.
7753 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7759 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7763 // Build the IRP's main body
7766 pIrp->UserBuffer = ReadBuffer;
7768 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7769 pIrp->RequestorMode = KernelMode;
7770 pIrp->Flags |= IRP_READ_OPERATION;
7773 // Set up the I/O stack location.
7776 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7777 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7778 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7779 pIoStackLocation->FileObject = pCacheFileObject;
7780 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7782 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7785 // Set the completion routine.
7788 IoSetCompletionRoutine( pIrp,
7796 // Send it to the FSD
7799 ntStatus = IoCallDriver( pTargetDeviceObject,
7802 if( NT_SUCCESS( ntStatus))
7809 ntStatus = KeWaitForSingleObject( &kEvent,
7815 if( NT_SUCCESS( ntStatus))
7818 ntStatus = pIrp->IoStatus.Status;
7820 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7826 if( pCacheFileObject != NULL)
7828 AFSReleaseCacheFileObject( pCacheFileObject);
7834 if( pIrp->MdlAddress != NULL)
7837 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7840 MmUnlockPages( pIrp->MdlAddress);
7843 IoFreeMdl( pIrp->MdlAddress);
7846 pIrp->MdlAddress = NULL;
7860 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7865 UNREFERENCED_PARAMETER(Irp);
7866 UNREFERENCED_PARAMETER(DeviceObject);
7867 KEVENT *pEvent = (KEVENT *)Context;
7873 return STATUS_MORE_PROCESSING_REQUIRED;
7877 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7880 BOOLEAN bIsEmpty = FALSE;
7881 AFSDirectoryCB *pDirEntry = NULL;
7886 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7891 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7894 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7896 while( pDirEntry != NULL)
7899 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7900 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7908 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7913 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7920 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7921 IN AFSDirectoryCB *DirEntry)
7924 NTSTATUS ntStatus = STATUS_SUCCESS;
7929 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7932 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7933 AFS_TRACE_LEVEL_VERBOSE,
7934 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7936 &DirEntry->NameInformation.FileName));
7938 try_return( ntStatus);
7941 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7944 // Remove the entry from the parent tree
7947 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7948 AFS_TRACE_LEVEL_VERBOSE,
7949 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7951 &DirEntry->NameInformation.FileName));
7953 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7956 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7957 AFS_TRACE_LEVEL_VERBOSE,
7958 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7960 &DirEntry->NameInformation.FileName));
7962 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7965 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7969 // From the short name tree
7972 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7973 AFS_TRACE_LEVEL_VERBOSE,
7974 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7976 &DirEntry->NameInformation.FileName));
7978 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7981 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7984 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7985 AFS_TRACE_LEVEL_VERBOSE,
7986 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7988 &DirEntry->NameInformation.FileName));
7990 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7992 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
8003 AFSGetAuthenticationId()
8006 LARGE_INTEGER liAuthId = {0,0};
8007 NTSTATUS ntStatus = STATUS_SUCCESS;
8008 PACCESS_TOKEN hToken = NULL;
8009 PTOKEN_STATISTICS pTokenInfo = NULL;
8010 BOOLEAN bCopyOnOpen = FALSE;
8011 BOOLEAN bEffectiveOnly = FALSE;
8012 BOOLEAN bPrimaryToken = FALSE;
8013 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
8018 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
8021 &stImpersonationLevel);
8026 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
8031 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
8032 AFS_TRACE_LEVEL_ERROR,
8033 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
8035 try_return( ntStatus);
8038 bPrimaryToken = TRUE;
8041 ntStatus = SeQueryInformationToken( hToken,
8043 (PVOID *)&pTokenInfo);
8045 if( !NT_SUCCESS( ntStatus))
8048 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
8049 AFS_TRACE_LEVEL_ERROR,
8050 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
8053 try_return( ntStatus);
8056 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
8057 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
8059 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
8060 AFS_TRACE_LEVEL_VERBOSE,
8061 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
8062 liAuthId.QuadPart));
8072 PsDereferenceImpersonationToken( hToken);
8077 PsDereferencePrimaryToken( hToken);
8081 if( pTokenInfo != NULL)
8084 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
8092 AFSUnwindFileInfo( IN AFSFcb *Fcb,
8096 UNREFERENCED_PARAMETER(Fcb);
8097 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
8099 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
8102 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
8104 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
8107 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
8109 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
8112 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
8114 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
8117 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
8119 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
8126 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
8129 BOOLEAN bIsValid = TRUE;
8131 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
8133 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
8135 while( pCurrentDirEntry != NULL)
8138 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
8142 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
8147 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8148 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
8151 if( pDirEntry == NULL)
8158 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
8161 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
8164 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
8166 ObjectInfo->Specific.Directory.DirectoryNodeCount);
8168 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
8177 AFSReferenceCacheFileObject()
8180 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8181 FILE_OBJECT *pCacheFileObject = NULL;
8183 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
8186 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
8188 if( pCacheFileObject != NULL)
8190 ObReferenceObject( pCacheFileObject);
8193 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
8195 return pCacheFileObject;
8199 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
8202 ASSERT( CacheFileObject != NULL);
8204 ObDereferenceObject( CacheFileObject);
8210 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
8213 NTSTATUS ntStatus = STATUS_SUCCESS;
8214 AFSDeviceExt *pControlDevExt = NULL;
8215 ULONG ulTimeIncrement = 0;
8221 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
8223 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
8225 AFSServerName = LibraryInit->AFSServerName;
8227 AFSMountRootName = LibraryInit->AFSMountRootName;
8229 AFSDebugFlags = LibraryInit->AFSDebugFlags;
8232 // Callbacks in the framework
8235 AFSProcessRequest = LibraryInit->AFSProcessRequest;
8237 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
8239 AFSDebugTraceFnc = AFSDbgLogMsg;
8241 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
8243 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
8245 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
8247 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
8249 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
8251 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
8253 if( LibraryInit->AFSCacheBaseAddress != NULL)
8256 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
8258 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
8260 AFSLibCacheLength = LibraryInit->AFSCacheLength;
8264 // Initialize some flush parameters
8267 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
8269 ulTimeIncrement = KeQueryTimeIncrement();
8271 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
8272 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
8273 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
8274 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
8275 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
8278 // Initialize the global root entry
8281 ntStatus = AFSInitVolume( NULL,
8282 &LibraryInit->GlobalRootFid,
8283 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
8286 if( !NT_SUCCESS( ntStatus))
8289 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8290 AFS_TRACE_LEVEL_ERROR,
8291 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
8294 try_return( ntStatus);
8297 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
8300 if( !NT_SUCCESS( ntStatus))
8303 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8304 AFS_TRACE_LEVEL_ERROR,
8305 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
8308 lCount = AFSVolumeDecrement( AFSGlobalRoot,
8309 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
8311 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8312 AFS_TRACE_LEVEL_VERBOSE,
8313 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8317 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8319 try_return( ntStatus);
8323 // Update the node type code to AFS_ROOT_ALL
8326 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
8328 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
8331 // Invalidate all known volumes since contact with the service and therefore
8332 // the file server was lost.
8335 AFSInvalidateAllVolumes();
8338 // Drop the locks acquired above
8341 AFSInitVolumeWorker( AFSGlobalRoot);
8343 lCount = AFSVolumeDecrement( AFSGlobalRoot,
8344 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
8346 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8347 AFS_TRACE_LEVEL_VERBOSE,
8348 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8352 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8354 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
8368 NTSTATUS ntStatus = STATUS_SUCCESS;
8369 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
8375 if( AFSGlobalDotDirEntry != NULL)
8378 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
8379 AFS_OBJECT_REFERENCE_GLOBAL);
8381 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8382 AFS_TRACE_LEVEL_VERBOSE,
8383 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
8384 AFSGlobalDotDirEntry->ObjectInformation,
8387 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
8389 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
8391 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
8393 ExFreePool( AFSGlobalDotDirEntry);
8395 AFSGlobalDotDirEntry = NULL;
8398 if( AFSGlobalDotDotDirEntry != NULL)
8401 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
8402 AFS_OBJECT_REFERENCE_GLOBAL);
8404 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8405 AFS_TRACE_LEVEL_VERBOSE,
8406 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
8407 AFSGlobalDotDotDirEntry->ObjectInformation,
8410 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
8412 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
8414 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
8416 ExFreePool( AFSGlobalDotDotDirEntry);
8418 AFSGlobalDotDotDirEntry = NULL;
8421 if( AFSSpecialShareNames != NULL)
8424 pDirNode = AFSSpecialShareNames;
8426 while( pDirNode != NULL)
8429 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
8431 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
8432 AFS_OBJECT_REFERENCE_GLOBAL);
8434 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8435 AFS_TRACE_LEVEL_VERBOSE,
8436 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
8437 pDirNode->ObjectInformation,
8440 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
8442 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
8444 ExFreePool( pDirNode->NonPaged);
8446 ExFreePool( pDirNode);
8448 pDirNode = pLastDirNode;
8451 AFSSpecialShareNames = NULL;
8459 AFSDefaultLogMsg( IN ULONG Subsystem,
8465 UNREFERENCED_PARAMETER(Subsystem);
8466 UNREFERENCED_PARAMETER(Level);
8467 NTSTATUS ntStatus = STATUS_SUCCESS;
8469 char chDebugBuffer[ 256];
8474 va_start( va_args, Format);
8476 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8481 if( NT_SUCCESS( ntStatus))
8483 DbgPrint( chDebugBuffer);
8493 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8494 IN ULONG InputBufferLength,
8495 IN AFSStatusInfoCB *StatusInfo,
8496 OUT ULONG *ReturnLength)
8499 NTSTATUS ntStatus = STATUS_SUCCESS;
8500 AFSVolumeCB *pVolumeCB = NULL;
8501 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8502 AFSVolumeCB *pNewVolumeCB = NULL;
8503 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8504 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8505 AFSObjectInfoCB *pObjectInfo = NULL;
8506 ULONGLONG ullIndex = 0;
8507 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8508 AFSNameArrayHdr *pNameArray = NULL;
8509 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8510 AFSDirectoryCB *pNewParentDirEntry = NULL;
8517 // If we are given a FID then look up the entry by that, otherwise
8521 if( GetStatusInfo->FileID.Cell != 0 &&
8522 GetStatusInfo->FileID.Volume != 0 &&
8523 GetStatusInfo->FileID.Vnode != 0 &&
8524 GetStatusInfo->FileID.Unique != 0)
8527 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8530 // Locate the volume node
8533 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8535 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8537 (AFSBTreeEntry **)&pVolumeCB);
8539 if( pVolumeCB != NULL)
8542 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8544 lCount = AFSVolumeIncrement( pVolumeCB,
8545 VolumeReferenceReason);
8547 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8548 AFS_TRACE_LEVEL_VERBOSE,
8549 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
8551 VolumeReferenceReason,
8555 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8557 if( !NT_SUCCESS( ntStatus) ||
8560 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8563 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8566 pObjectInfo = &pVolumeCB->ObjectInformation;
8568 lCount = AFSObjectInfoIncrement( pObjectInfo,
8569 AFS_OBJECT_REFERENCE_STATUS);
8571 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8572 AFS_TRACE_LEVEL_VERBOSE,
8573 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8580 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8583 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8585 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8587 (AFSBTreeEntry **)&pObjectInfo);
8589 if( pObjectInfo != NULL)
8593 // Reference the node so it won't be torn down
8596 lCount = AFSObjectInfoIncrement( pObjectInfo,
8597 AFS_OBJECT_REFERENCE_STATUS);
8599 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8600 AFS_TRACE_LEVEL_VERBOSE,
8601 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8606 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8608 if( !NT_SUCCESS( ntStatus) ||
8609 pObjectInfo == NULL)
8611 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8618 if( GetStatusInfo->FileNameLength == 0 ||
8619 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8621 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8624 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8625 uniFullPathName.MaximumLength = uniFullPathName.Length;
8627 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8630 // This name should begin with the \afs server so parse it off and check it
8633 FsRtlDissectName( uniFullPathName,
8637 if( RtlCompareUnicodeString( &uniComponentName,
8641 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8642 AFS_TRACE_LEVEL_ERROR,
8643 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8646 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8649 uniFullPathName = uniRemainingPath;
8651 uniParsedName = uniFullPathName;
8657 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8660 if( pNameArray == NULL)
8662 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8665 pVolumeCB = AFSGlobalRoot;
8667 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8670 // Increment the ref count on the volume and dir entry for correct processing below
8673 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8675 lCount = AFSVolumeIncrement( pVolumeCB,
8676 VolumeReferenceReason);
8678 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8679 AFS_TRACE_LEVEL_VERBOSE,
8680 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8682 VolumeReferenceReason,
8685 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8687 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8688 AFS_TRACE_LEVEL_VERBOSE,
8689 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8690 &pParentDirEntry->NameInformation.FileName,
8695 ntStatus = AFSLocateNameEntry( NULL,
8700 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8701 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8705 &NewVolumeReferenceReason,
8706 &pNewParentDirEntry,
8710 if ( pNewVolumeCB != NULL)
8714 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8715 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8716 // the reference on pVolumeCB that was held prior to the call.
8717 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8718 // will be released second.
8721 lCount = AFSVolumeDecrement( pVolumeCB,
8722 VolumeReferenceReason);
8724 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8725 AFS_TRACE_LEVEL_VERBOSE,
8726 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8728 VolumeReferenceReason,
8731 pVolumeCB = pNewVolumeCB;
8733 pNewVolumeCB = NULL;
8735 VolumeReferenceReason = NewVolumeReferenceReason;
8737 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8741 // AFSLocateNameEntry does not alter the reference count of
8742 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8743 // a reference held.
8746 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8748 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8749 AFS_TRACE_LEVEL_VERBOSE,
8750 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8751 &pParentDirEntry->NameInformation.FileName,
8755 pParentDirEntry = pNewParentDirEntry;
8757 pNewParentDirEntry = NULL;
8759 if( !NT_SUCCESS( ntStatus) ||
8760 ntStatus == STATUS_REPARSE)
8765 try_return( ntStatus);
8768 pObjectInfo = pDirectoryEntry->ObjectInformation;
8770 lCount = AFSObjectInfoIncrement( pObjectInfo,
8771 AFS_OBJECT_REFERENCE_STATUS);
8773 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8774 AFS_TRACE_LEVEL_VERBOSE,
8775 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8781 // At this point we have an object info block, return the information
8784 StatusInfo->FileId = pObjectInfo->FileId;
8786 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8788 StatusInfo->Expiration = pObjectInfo->Expiration;
8790 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8792 StatusInfo->FileType = pObjectInfo->FileType;
8794 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8796 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8798 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8800 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8802 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8804 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8806 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8808 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8810 StatusInfo->EaSize = pObjectInfo->EaSize;
8812 StatusInfo->Links = pObjectInfo->Links;
8815 // Return the information length
8818 *ReturnLength = sizeof( AFSStatusInfoCB);
8822 if( pDirectoryEntry != NULL)
8825 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8827 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8828 AFS_TRACE_LEVEL_VERBOSE,
8829 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8830 &pDirectoryEntry->NameInformation.FileName,
8835 ASSERT( lCount >= 0);
8838 if ( pParentDirEntry != NULL)
8841 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8843 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8844 AFS_TRACE_LEVEL_VERBOSE,
8845 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8846 &pParentDirEntry->NameInformation.FileName,
8851 ASSERT( lCount >= 0);
8854 if( pObjectInfo != NULL)
8857 lCount = AFSObjectInfoDecrement( pObjectInfo,
8858 AFS_OBJECT_REFERENCE_STATUS);
8860 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8861 AFS_TRACE_LEVEL_VERBOSE,
8862 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8867 if( pVolumeCB != NULL)
8870 lCount = AFSVolumeDecrement( pVolumeCB,
8871 VolumeReferenceReason);
8873 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8874 AFS_TRACE_LEVEL_VERBOSE,
8875 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8877 VolumeReferenceReason,
8881 if( pNameArray != NULL)
8884 AFSFreeNameArray( pNameArray);
8892 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8893 IN UNICODE_STRING *ComponentName)
8896 NTSTATUS ntStatus = STATUS_SUCCESS;
8897 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8898 AFSDirectoryCB *pDirEntry = NULL;
8906 // Search for the entry in the parent
8909 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8910 AFS_TRACE_LEVEL_VERBOSE_2,
8911 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8914 ulCRC = AFSGenerateCRC( ComponentName,
8917 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8920 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8924 if( pDirEntry == NULL)
8928 // Missed so perform a case insensitive lookup
8931 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8932 AFS_TRACE_LEVEL_VERBOSE_2,
8933 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8936 ulCRC = AFSGenerateCRC( ComponentName,
8939 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8943 if( pDirEntry == NULL)
8947 // OK, if this component is a valid short name then try
8948 // a lookup in the short name tree
8951 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8952 RtlIsNameLegalDOS8Dot3( ComponentName,
8957 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8958 AFS_TRACE_LEVEL_VERBOSE_2,
8959 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8962 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8969 if( pDirEntry != NULL)
8971 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8973 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8974 AFS_TRACE_LEVEL_VERBOSE,
8975 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8976 &pDirEntry->NameInformation.FileName,
8981 ASSERT( lCount >= 0);
8984 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8986 if( pDirEntry == NULL)
8989 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8990 AFS_TRACE_LEVEL_VERBOSE_2,
8991 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8993 STATUS_OBJECT_NAME_NOT_FOUND));
8995 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8999 // We have the symlink object but previously failed to process it so return access
9003 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
9004 AFS_TRACE_LEVEL_VERBOSE_2,
9005 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
9008 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
9010 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
9012 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
9013 AFS_TRACE_LEVEL_VERBOSE,
9014 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
9015 &pDirEntry->NameInformation.FileName,
9020 ASSERT( lCount >= 0);
9031 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
9032 OUT UNICODE_STRING *ComponentName)
9035 NTSTATUS ntStatus = STATUS_SUCCESS;
9036 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
9038 uniFullPathName = *FullPathName;
9043 FsRtlDissectName( uniFullPathName,
9047 if( uniRemainingPath.Length == 0)
9052 uniFullPathName = uniRemainingPath;
9055 if( uniComponentName.Length > 0)
9057 *ComponentName = uniComponentName;
9064 AFSDumpTraceFiles_Default()
9070 AFSValidNameFormat( IN UNICODE_STRING *FileName)
9073 BOOLEAN bIsValidName = TRUE;
9079 while( usIndex < FileName->Length/sizeof( WCHAR))
9082 if( FileName->Buffer[ usIndex] == L':' ||
9083 FileName->Buffer[ usIndex] == L'*' ||
9084 FileName->Buffer[ usIndex] == L'?' ||
9085 FileName->Buffer[ usIndex] == L'"' ||
9086 FileName->Buffer[ usIndex] == L'<' ||
9087 FileName->Buffer[ usIndex] == L'>')
9089 bIsValidName = FALSE;
9097 return bIsValidName;
9101 AFSCreateDefaultSecurityDescriptor()
9104 NTSTATUS ntStatus = STATUS_SUCCESS;
9106 ULONG ulSACLSize = 0;
9107 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
9108 ULONG ulACESize = 0;
9109 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
9110 ULONG ulSDLength = 0;
9111 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
9112 PSID pWorldSID = NULL;
9113 ULONG *pulSubAuthority = NULL;
9114 ULONG ulWorldSIDLEngth = 0;
9119 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
9121 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
9123 AFS_GENERIC_MEMORY_29_TAG);
9125 if( pWorldSID == NULL)
9127 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
9129 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9132 RtlZeroMemory( pWorldSID,
9135 RtlInitializeSid( pWorldSID,
9136 &SeWorldSidAuthority,
9139 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
9140 *pulSubAuthority = SECURITY_WORLD_RID;
9142 if( AFSRtlSetSaclSecurityDescriptor == NULL)
9145 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
9150 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
9152 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
9154 AFS_GENERIC_MEMORY_29_TAG);
9159 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
9161 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9164 RtlZeroMemory( pACE,
9167 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
9168 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
9169 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
9170 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
9172 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
9174 SeExports->SeLowMandatorySid);
9176 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
9177 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
9179 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
9181 AFS_GENERIC_MEMORY_29_TAG);
9186 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
9188 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9191 ntStatus = RtlCreateAcl( pSACL,
9195 if( !NT_SUCCESS( ntStatus))
9198 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
9201 try_return( ntStatus);
9204 ntStatus = RtlAddAce( pSACL,
9208 pACE->Header.AceSize);
9210 if( !NT_SUCCESS( ntStatus))
9213 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
9216 try_return( ntStatus);
9220 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
9221 sizeof( SECURITY_DESCRIPTOR),
9222 AFS_GENERIC_MEMORY_27_TAG);
9224 if( pSecurityDescr == NULL)
9227 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9229 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9232 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
9233 SECURITY_DESCRIPTOR_REVISION);
9235 if( !NT_SUCCESS( ntStatus))
9238 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
9241 try_return( ntStatus);
9244 if( AFSRtlSetSaclSecurityDescriptor != NULL)
9246 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
9251 if( !NT_SUCCESS( ntStatus))
9254 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
9257 try_return( ntStatus);
9262 // Add in the group and owner to the SD
9265 if( AFSRtlSetGroupSecurityDescriptor != NULL)
9267 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
9271 if( !NT_SUCCESS( ntStatus))
9274 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
9277 try_return( ntStatus);
9281 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
9285 if( !NT_SUCCESS( ntStatus))
9288 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
9291 try_return( ntStatus);
9294 if( !RtlValidSecurityDescriptor( pSecurityDescr))
9297 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
9299 try_return( ntStatus = STATUS_INVALID_PARAMETER);
9302 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
9304 AFS_GENERIC_MEMORY_27_TAG);
9306 if( pRelativeSecurityDescr == NULL)
9309 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9311 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9314 ulSDLength = PAGE_SIZE;
9316 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
9317 pRelativeSecurityDescr,
9320 if( !NT_SUCCESS( ntStatus))
9323 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
9326 try_return( ntStatus);
9329 AFSDefaultSD = pRelativeSecurityDescr;
9333 if( !NT_SUCCESS( ntStatus))
9336 if( pRelativeSecurityDescr != NULL)
9338 ExFreePool( pRelativeSecurityDescr);
9342 if( pSecurityDescr != NULL)
9344 ExFreePool( pSecurityDescr);
9357 if( pWorldSID != NULL)
9359 ExFreePool( pWorldSID);
9367 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
9368 OUT UNICODE_STRING *ParentPath)
9371 *ParentPath = *FullFileName;
9374 // If the final character is a \, jump over it
9377 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
9379 ParentPath->Length -= sizeof( WCHAR);
9382 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
9384 ParentPath->Length -= sizeof( WCHAR);
9388 // And the separator
9391 ParentPath->Length -= sizeof( WCHAR);
9397 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
9398 IN AFSObjectInfoCB *ObjectInfo,
9399 IN BOOLEAN WriteAccess,
9400 OUT GUID *AuthGroup)
9403 NTSTATUS ntStatus = STATUS_SUCCESS;
9404 GUID stAuthGroup, stZeroAuthGroup;
9405 BOOLEAN bFoundAuthGroup = FALSE;
9406 AFSCcb *pCcb = NULL;
9412 RtlZeroMemory( &stAuthGroup,
9415 RtlZeroMemory( &stZeroAuthGroup,
9421 if( ObjectInfo != NULL &&
9422 ObjectInfo->Fcb != NULL)
9424 pFcb = ObjectInfo->Fcb;
9431 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
9434 pCcb = Fcb->CcbListHead;
9436 while( pCcb != NULL)
9440 pCcb->GrantedAccess & FILE_WRITE_DATA)
9442 RtlCopyMemory( &stAuthGroup,
9446 bFoundAuthGroup = TRUE;
9450 else if( pCcb->GrantedAccess & FILE_READ_DATA)
9453 // At least get the read-only access
9456 RtlCopyMemory( &stAuthGroup,
9460 bFoundAuthGroup = TRUE;
9463 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9466 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9469 if( !bFoundAuthGroup)
9472 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9473 (ULONGLONG)PsGetCurrentThreadId(),
9476 if( RtlCompareMemory( &stZeroAuthGroup,
9478 sizeof( GUID)) == sizeof( GUID))
9481 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9483 try_return( ntStatus = STATUS_ACCESS_DENIED);
9487 RtlCopyMemory( AuthGroup,
9500 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9501 IN ULONG InvalidateReason)
9504 NTSTATUS ntStatus = STATUS_SUCCESS;
9507 ULONG ulProcessCount = 0;
9514 switch( InvalidateReason)
9517 case AFS_INVALIDATE_DELETED:
9520 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9521 ObjectInfo->Fcb != NULL)
9524 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9527 ObjectInfo->Links = 0;
9529 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9531 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9536 // Clear out the extents
9537 // And get rid of them (note this involves waiting
9538 // for any writes or reads to the cache to complete)
9541 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9544 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9550 case AFS_INVALIDATE_DATA_VERSION:
9553 LARGE_INTEGER liCurrentOffset = {0,0};
9554 LARGE_INTEGER liFlushLength = {0,0};
9555 ULONG ulFlushLength = 0;
9556 BOOLEAN bLocked = FALSE;
9557 BOOLEAN bExtentsLocked = FALSE;
9558 BOOLEAN bCleanExtents = FALSE;
9560 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9561 ObjectInfo->Fcb != NULL)
9564 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9569 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9570 AFS_TRACE_LEVEL_VERBOSE,
9571 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9572 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9573 PsGetCurrentThread()));
9575 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9578 bExtentsLocked = TRUE;
9581 // There are several possibilities here:
9583 // 0. If there are no extents or all of the extents are dirty, do nothing.
9585 // 1. There could be nothing dirty and an open reference count of zero
9586 // in which case we can just tear down all of the extents without
9587 // holding any resources.
9589 // 2. There could be nothing dirty and a non-zero open reference count
9590 // in which case we can issue a CcPurge against the entire file
9591 // while holding just the Fcb Resource.
9593 // 3. There can be dirty extents in which case we need to identify
9594 // the non-dirty ranges and then perform a CcPurge on just the
9595 // non-dirty ranges while holding just the Fcb Resource.
9598 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9601 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9604 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9606 bExtentsLocked = FALSE;
9608 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9611 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9615 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9621 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9622 AFS_TRACE_LEVEL_VERBOSE,
9623 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9624 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9625 PsGetCurrentThread()));
9627 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9630 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9637 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9638 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9644 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9645 AFS_TRACE_LEVEL_WARNING,
9646 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9647 ObjectInfo->FileId.Cell,
9648 ObjectInfo->FileId.Volume,
9649 ObjectInfo->FileId.Vnode,
9650 ObjectInfo->FileId.Unique));
9652 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9657 bCleanExtents = TRUE;
9660 __except( EXCEPTION_EXECUTE_HANDLER)
9663 ntStatus = GetExceptionCode();
9667 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9668 ObjectInfo->FileId.Cell,
9669 ObjectInfo->FileId.Volume,
9670 ObjectInfo->FileId.Vnode,
9671 ObjectInfo->FileId.Unique,
9674 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9677 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9678 AFS_TRACE_LEVEL_VERBOSE,
9679 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9680 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9681 PsGetCurrentThread()));
9683 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9689 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9691 bExtentsLocked = FALSE;
9693 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9694 AFS_TRACE_LEVEL_VERBOSE,
9695 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9696 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9697 PsGetCurrentThread()));
9699 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9702 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9707 // Must build a list of non-dirty ranges from the beginning of the file
9708 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9709 // ranges. In all but the most extreme random data write scenario there will
9710 // be significantly fewer.
9712 // For each range we need offset and size.
9715 AFSByteRange * ByteRangeList = NULL;
9716 ULONG ulByteRangeCount = 0;
9718 BOOLEAN bPurgeOnClose = FALSE;
9723 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9726 if ( ByteRangeList != NULL ||
9727 ulByteRangeCount == 0)
9730 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9737 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9739 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9740 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9741 &ByteRangeList[ulIndex].FileOffset,
9746 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9747 AFS_TRACE_LEVEL_WARNING,
9748 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9749 ObjectInfo->FileId.Cell,
9750 ObjectInfo->FileId.Volume,
9751 ObjectInfo->FileId.Vnode,
9752 ObjectInfo->FileId.Unique));
9754 bPurgeOnClose = TRUE;
9759 bCleanExtents = TRUE;
9762 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9764 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9766 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9773 // We couldn't allocate the memory to build the purge list
9774 // so just walk the extent list while holding the ExtentsList Resource.
9775 // This could deadlock but we do not have much choice.
9778 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9780 bExtentsLocked = TRUE;
9782 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9786 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9790 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9792 while( ulProcessCount < ulCount)
9794 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9796 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9798 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9799 &pEntry->FileOffset,
9804 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9805 AFS_TRACE_LEVEL_WARNING,
9806 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9807 ObjectInfo->FileId.Cell,
9808 ObjectInfo->FileId.Volume,
9809 ObjectInfo->FileId.Vnode,
9810 ObjectInfo->FileId.Unique));
9812 bPurgeOnClose = TRUE;
9817 bCleanExtents = TRUE;
9821 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9824 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9826 while( liFlushLength.QuadPart > 0)
9829 if( liFlushLength.QuadPart > 512 * 1024000)
9831 ulFlushLength = 512 * 1024000;
9835 ulFlushLength = liFlushLength.LowPart;
9838 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9844 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9845 AFS_TRACE_LEVEL_WARNING,
9846 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9847 ObjectInfo->FileId.Cell,
9848 ObjectInfo->FileId.Volume,
9849 ObjectInfo->FileId.Vnode,
9850 ObjectInfo->FileId.Unique));
9852 bPurgeOnClose = TRUE;
9857 bCleanExtents = TRUE;
9860 liFlushLength.QuadPart -= ulFlushLength;
9864 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9872 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9878 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9879 AFS_TRACE_LEVEL_WARNING,
9880 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9881 ObjectInfo->FileId.Cell,
9882 ObjectInfo->FileId.Volume,
9883 ObjectInfo->FileId.Vnode,
9884 ObjectInfo->FileId.Unique));
9886 bPurgeOnClose = TRUE;
9891 bCleanExtents = TRUE;
9898 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9902 __except( EXCEPTION_EXECUTE_HANDLER)
9905 ntStatus = GetExceptionCode();
9909 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9910 ObjectInfo->FileId.Cell,
9911 ObjectInfo->FileId.Volume,
9912 ObjectInfo->FileId.Vnode,
9913 ObjectInfo->FileId.Unique,
9917 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9918 AFS_TRACE_LEVEL_VERBOSE,
9919 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9920 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9921 PsGetCurrentThread()));
9923 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9927 if ( bExtentsLocked)
9930 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9936 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9942 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9952 // Destroy the reference passed in by the caller to AFSInvalidateObject
9953 // or AFSQueueInvalidateObject
9956 lCount = AFSObjectInfoDecrement( ObjectInfo,
9957 AFS_OBJECT_REFERENCE_INVALIDATION);
9959 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9960 AFS_TRACE_LEVEL_VERBOSE,
9961 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",