2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSGeneric.cpp
39 #include "AFSCommon.h"
42 // Function: AFSExceptionFilter
46 // This function is the exception handler
50 // A status is returned for the function
54 AFSExceptionFilter( IN CHAR *FunctionString,
56 IN PEXCEPTION_POINTERS ExceptPtrs)
59 PEXCEPTION_RECORD ExceptRec;
65 ExceptRec = ExceptPtrs->ExceptionRecord;
67 Context = ExceptPtrs->ContextRecord;
71 "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
75 ExceptRec->ExceptionCode,
76 ExceptRec->ExceptionAddress,
77 (void *)AFSExceptionFilter);
79 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
81 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
82 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
84 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
86 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
89 KeBugCheck( (ULONG)-2);
97 __except( EXCEPTION_EXECUTE_HANDLER)
103 return EXCEPTION_EXECUTE_HANDLER;
107 // Function: AFSLibExAllocatePoolWithTag()
109 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
110 // is configured on, then bugcheck the system if
111 // a memory allocation fails. The routine should be
112 // used for all memory allocations that are to be freed
113 // when the library is unloaded. Memory allocations that
114 // are to survive library unload and reload should be
115 // performed using AFSExAllocatePoolWithTag() which is
116 // provided by the AFS Framework.
119 // POOL_TYPE PoolType - Paged or NonPaged
120 // SIZE_T NumberOfBytes - requested allocation size
121 // ULONG Tag - Pool Allocation Tag to be applied for tracking
124 // void * - the memory allocation
128 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
129 IN SIZE_T NumberOfBytes,
133 void *pBuffer = NULL;
135 pBuffer = ExAllocatePoolWithTag( PoolType,
142 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
145 KeBugCheck( (ULONG)-2);
152 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
156 PsGetCurrentThread());
166 // Function: AFSAcquireExcl()
168 // Purpose: Called to acquire a resource exclusive with optional wait
171 // PERESOURCE Resource - Resource to acquire
172 // BOOLEAN Wait - Whether to block
175 // BOOLEAN - Whether the mask was acquired
179 AFSAcquireExcl( IN PERESOURCE Resource,
183 BOOLEAN bStatus = FALSE;
186 // Normal kernel APCs must be disabled before calling
187 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
190 KeEnterCriticalRegion();
192 bStatus = ExAcquireResourceExclusiveLite( Resource,
198 KeLeaveCriticalRegion();
205 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
209 BOOLEAN bStatus = FALSE;
211 KeEnterCriticalRegion();
213 bStatus = ExAcquireSharedStarveExclusive( Resource,
219 KeLeaveCriticalRegion();
226 // Function: AFSAcquireShared()
228 // Purpose: Called to acquire a resource shared with optional wait
231 // PERESOURCE Resource - Resource to acquire
232 // BOOLEAN Wait - Whether to block
235 // BOOLEAN - Whether the mask was acquired
239 AFSAcquireShared( IN PERESOURCE Resource,
243 BOOLEAN bStatus = FALSE;
245 KeEnterCriticalRegion();
247 bStatus = ExAcquireResourceSharedLite( Resource,
253 KeLeaveCriticalRegion();
260 // Function: AFSReleaseResource()
262 // Purpose: Called to release a resource
265 // PERESOURCE Resource - Resource to release
272 AFSReleaseResource( IN PERESOURCE Resource)
275 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
276 AFS_TRACE_LEVEL_VERBOSE,
277 "AFSReleaseResource Releasing lock %08lX Thread %08lX\n",
279 PsGetCurrentThread());
281 ExReleaseResourceLite( Resource);
283 KeLeaveCriticalRegion();
289 AFSConvertToShared( IN PERESOURCE Resource)
292 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
293 AFS_TRACE_LEVEL_VERBOSE,
294 "AFSConvertToShared Converting lock %08lX Thread %08lX\n",
296 PsGetCurrentThread());
298 ExConvertExclusiveToSharedLite( Resource);
304 // Function: AFSCompleteRequest
308 // This function completes irps
312 // A status is returned for the function
316 AFSCompleteRequest( IN PIRP Irp,
320 Irp->IoStatus.Status = Status;
322 IoCompleteRequest( Irp,
329 // Function: AFSGenerateCRC
333 // Given a device and filename this function generates a CRC
337 // A status is returned for the function
341 AFSGenerateCRC( IN PUNICODE_STRING FileName,
342 IN BOOLEAN UpperCaseName)
346 NTSTATUS ntStatus = STATUS_SUCCESS;
348 ntStatus = RtlHashUnicodeString( FileName,
350 HASH_STRING_ALGORITHM_DEFAULT,
353 if( !NT_SUCCESS( ntStatus))
362 AFSLockSystemBuffer( IN PIRP Irp,
366 NTSTATUS Status = STATUS_SUCCESS;
367 void *pAddress = NULL;
369 if( Irp->MdlAddress != NULL)
372 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
375 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
378 pAddress = Irp->AssociatedIrp.SystemBuffer;
380 else if( Irp->UserBuffer != NULL)
383 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
389 if( Irp->MdlAddress != NULL)
393 // Lock the new Mdl in memory.
398 PIO_STACK_LOCATION pIoStack;
399 pIoStack = IoGetCurrentIrpStackLocation( Irp);
402 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
403 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
405 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
408 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
411 AFSDumpTraceFilesFnc();
413 IoFreeMdl( Irp->MdlAddress );
414 Irp->MdlAddress = NULL;
424 AFSLockUserBuffer( IN void *UserBuffer,
425 IN ULONG BufferLength,
429 NTSTATUS ntStatus = STATUS_SUCCESS;
430 void *pAddress = NULL;
436 pMdl = IoAllocateMdl( UserBuffer,
445 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
449 // Lock the new Mdl in memory.
455 MmProbeAndLockPages( pMdl,
459 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
462 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
465 AFSDumpTraceFilesFnc();
487 AFSMapToService( IN PIRP Irp,
491 NTSTATUS ntStatus = STATUS_SUCCESS;
492 void *pMappedBuffer = NULL;
493 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
499 if( pDevExt->Specific.Control.ServiceProcess == NULL)
502 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
505 if( Irp->MdlAddress == NULL)
508 if( AFSLockSystemBuffer( Irp,
512 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
517 // Attach to the service process for mapping
520 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
521 (PRKAPC_STATE)&stApcState);
523 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
530 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
537 return pMappedBuffer;
541 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
545 NTSTATUS ntStatus = STATUS_SUCCESS;
546 void *pMappedBuffer = NULL;
547 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
553 if( pDevExt->Specific.Control.ServiceProcess == NULL)
556 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
563 // Attach to the service process for mapping
566 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
567 (PRKAPC_STATE)&stApcState);
569 MmUnmapLockedPages( MappedBuffer,
572 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
584 AFSInitializeLibraryDevice()
587 NTSTATUS ntStatus = STATUS_SUCCESS;
588 AFSDeviceExt *pDeviceExt = NULL;
593 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
596 // The PIOCtl file name
599 RtlInitUnicodeString( &AFSPIOCtlName,
600 AFS_PIOCTL_FILE_INTERFACE_NAME);
603 // And the global root share name
606 RtlInitUnicodeString( &AFSGlobalRootName,
607 AFS_GLOBAL_ROOT_SHARE_NAME);
615 AFSRemoveLibraryDevice()
618 NTSTATUS ntStatus = STATUS_SUCCESS;
629 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
633 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
634 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
636 AFSCompleteRequest( Irp,
643 AFSInitializeGlobalDirectoryEntries()
646 NTSTATUS ntStatus = STATUS_SUCCESS;
647 AFSDirectoryCB *pDirNode = NULL;
648 ULONG ulEntryLength = 0;
649 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
650 AFSObjectInfoCB *pObjectInfoCB = NULL;
651 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
658 // Initialize the global . entry
661 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
664 if( pObjectInfoCB == NULL)
667 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
668 AFS_TRACE_LEVEL_ERROR,
669 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
672 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
675 lCount = AFSObjectInfoIncrement( pObjectInfoCB);
677 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
678 AFS_TRACE_LEVEL_VERBOSE,
679 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
683 ntStatus = STATUS_SUCCESS;
685 ulEntryLength = sizeof( AFSDirectoryCB) +
688 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
692 if( pDirNode == NULL)
695 AFSDeleteObjectInfo( pObjectInfoCB);
697 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
698 AFS_TRACE_LEVEL_ERROR,
699 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
701 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
704 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
705 sizeof( AFSNonPagedDirectoryCB),
706 AFS_DIR_ENTRY_NP_TAG);
708 if( pNonPagedDirEntry == NULL)
711 ExFreePool( pDirNode);
713 AFSDeleteObjectInfo( pObjectInfoCB);
715 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
716 AFS_TRACE_LEVEL_ERROR,
717 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
719 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
722 RtlZeroMemory( pDirNode,
725 RtlZeroMemory( pNonPagedDirEntry,
726 sizeof( AFSNonPagedDirectoryCB));
728 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
730 pDirNode->NonPaged = pNonPagedDirEntry;
732 pDirNode->ObjectInformation = pObjectInfoCB;
738 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
740 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
743 // Setup the names in the entry
746 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
748 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
750 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
752 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
755 // Populate the rest of the data
758 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
760 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
762 AFSGlobalDotDirEntry = pDirNode;
768 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
771 if( pObjectInfoCB == NULL)
774 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
775 AFS_TRACE_LEVEL_ERROR,
776 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
779 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
782 lCount = AFSObjectInfoIncrement( pObjectInfoCB);
784 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
785 AFS_TRACE_LEVEL_VERBOSE,
786 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
790 ntStatus = STATUS_SUCCESS;
792 ulEntryLength = sizeof( AFSDirectoryCB) +
793 ( 2 * sizeof( WCHAR));
795 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
799 if( pDirNode == NULL)
802 AFSDeleteObjectInfo( pObjectInfoCB);
804 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
807 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
808 sizeof( AFSNonPagedDirectoryCB),
809 AFS_DIR_ENTRY_NP_TAG);
811 if( pNonPagedDirEntry == NULL)
814 ExFreePool( pDirNode);
816 AFSDeleteObjectInfo( pObjectInfoCB);
818 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
821 RtlZeroMemory( pDirNode,
824 RtlZeroMemory( pNonPagedDirEntry,
825 sizeof( AFSNonPagedDirectoryCB));
827 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
829 pDirNode->NonPaged = pNonPagedDirEntry;
831 pDirNode->ObjectInformation = pObjectInfoCB;
837 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
839 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
842 // Setup the names in the entry
845 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
847 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
849 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
851 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
853 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
856 // Populate the rest of the data
859 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
861 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
863 AFSGlobalDotDotDirEntry = pDirNode;
867 if( !NT_SUCCESS( ntStatus))
870 if( AFSGlobalDotDirEntry != NULL)
873 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
875 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
877 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
879 ExFreePool( AFSGlobalDotDirEntry);
881 AFSGlobalDotDirEntry = NULL;
884 if( AFSGlobalDotDotDirEntry != NULL)
887 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
889 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
891 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
893 ExFreePool( AFSGlobalDotDotDirEntry);
895 AFSGlobalDotDotDirEntry = NULL;
904 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
905 IN PUNICODE_STRING FileName,
906 IN PUNICODE_STRING TargetName,
907 IN AFSDirEnumEntry *DirEnumEntry,
911 AFSDirectoryCB *pDirNode = NULL;
912 NTSTATUS ntStatus = STATUS_SUCCESS;
913 ULONG ulEntryLength = 0;
914 AFSDirEnumEntry *pDirEnumCB = NULL;
915 AFSFileID stTargetFileID;
917 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
918 AFSObjectInfoCB *pObjectInfoCB = NULL;
919 BOOLEAN bAllocatedObjectCB = FALSE;
920 ULONGLONG ullIndex = 0;
921 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
927 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
928 AFS_TRACE_LEVEL_VERBOSE,
929 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
931 ParentObjectInfo->FileId.Cell,
932 ParentObjectInfo->FileId.Volume,
933 ParentObjectInfo->FileId.Vnode,
934 ParentObjectInfo->FileId.Unique);
937 // First thing is to locate/create our object information block
941 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
944 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
946 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
948 (AFSBTreeEntry **)&pObjectInfoCB);
950 if( !NT_SUCCESS( ntStatus) ||
951 pObjectInfoCB == NULL)
955 // Allocate our object info cb
958 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
961 if( pObjectInfoCB == NULL)
964 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
966 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
969 bAllocatedObjectCB = TRUE;
971 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
972 AFS_TRACE_LEVEL_VERBOSE,
973 "AFSInitDirEntry initialized object %08lX Parent Object %08lX for %wZ\n",
979 lCount = AFSObjectInfoIncrement( pObjectInfoCB);
981 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
982 AFS_TRACE_LEVEL_VERBOSE,
983 "AFSInitDirEntry Increment count on object %08lX Cnt %d\n",
987 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
989 ntStatus = STATUS_SUCCESS;
991 ulEntryLength = sizeof( AFSDirectoryCB) +
994 if( TargetName != NULL)
997 ulEntryLength += TargetName->Length;
1000 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1004 if( pDirNode == NULL)
1007 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1010 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1011 sizeof( AFSNonPagedDirectoryCB),
1012 AFS_DIR_ENTRY_NP_TAG);
1014 if( pNonPagedDirEntry == NULL)
1017 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1020 RtlZeroMemory( pDirNode,
1023 RtlZeroMemory( pNonPagedDirEntry,
1024 sizeof( AFSNonPagedDirectoryCB));
1026 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1028 pDirNode->NonPaged = pNonPagedDirEntry;
1030 pDirNode->ObjectInformation = pObjectInfoCB;
1033 // Set valid entry and NOT_IN_PARENT flag
1036 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1038 pDirNode->FileIndex = FileIndex;
1041 // Setup the names in the entry
1044 if( FileName->Length > 0)
1047 pDirNode->NameInformation.FileName.Length = FileName->Length;
1049 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1051 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1053 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1055 pDirNode->NameInformation.FileName.Length);
1058 // Create a CRC for the file
1061 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1064 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1068 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1069 AFS_TRACE_LEVEL_VERBOSE,
1070 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1073 ParentObjectInfo->FileId.Cell,
1074 ParentObjectInfo->FileId.Volume,
1075 ParentObjectInfo->FileId.Vnode,
1076 ParentObjectInfo->FileId.Unique);
1078 if( TargetName != NULL &&
1079 TargetName->Length > 0)
1082 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1084 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1086 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1087 sizeof( AFSDirectoryCB) +
1088 pDirNode->NameInformation.FileName.Length);
1090 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1092 pDirNode->NameInformation.TargetName.Length);
1096 // If we allocated the object information cb then update the information
1099 if( bAllocatedObjectCB)
1103 // Populate the rest of the data
1106 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1108 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1110 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1112 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1114 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1116 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1118 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1120 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1122 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1124 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1126 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1129 pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1132 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1133 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1136 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1139 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1142 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1143 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1147 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1148 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1149 pObjectInfoCB->TargetFileId.Unique == 0 &&
1150 pDirNode->NameInformation.TargetName.Length == 0)
1154 // This will ensure we perform a validation on the node
1157 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1160 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1163 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1168 // Object specific information
1171 pObjectInfoCB->Links = DirEnumEntry->Links;
1173 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1175 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1179 if( !NT_SUCCESS( ntStatus))
1182 if( pNonPagedDirEntry != NULL)
1185 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1187 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1190 if( pDirNode != NULL)
1193 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1199 // Dereference our object info block if we have one
1202 if( pObjectInfoCB != NULL)
1205 lCount = AFSObjectInfoDecrement( pObjectInfoCB);
1207 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1208 AFS_TRACE_LEVEL_VERBOSE,
1209 "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
1213 if( bAllocatedObjectCB)
1216 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1218 AFSDeleteObjectInfo( pObjectInfoCB);
1228 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1229 IN BOOLEAN DirectoryEntry)
1232 BOOLEAN bReturn = TRUE;
1233 ACCESS_MASK stAccessMask = 0;
1236 // Get rid of anything we don't know about
1239 DesiredAccess = (DesiredAccess &
1245 ACCESS_SYSTEM_SECURITY |
1249 FILE_READ_ATTRIBUTES |
1250 FILE_WRITE_ATTRIBUTES |
1251 FILE_LIST_DIRECTORY |
1257 // Our 'read only' access mask. These are the accesses we will
1258 // allow for a read only file
1261 stAccessMask = DELETE |
1266 ACCESS_SYSTEM_SECURITY |
1270 FILE_READ_ATTRIBUTES |
1271 FILE_WRITE_ATTRIBUTES |
1273 FILE_LIST_DIRECTORY |
1277 // For a directory, add in the directory specific accesses
1283 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1288 if( FlagOn( DesiredAccess, ~stAccessMask))
1292 // A write access is set ...
1302 AFSEvaluateNode( IN GUID *AuthGroup,
1303 IN AFSDirectoryCB *DirEntry)
1306 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1307 NTSTATUS ntStatus = STATUS_SUCCESS;
1308 AFSDirEnumEntry *pDirEntry = NULL;
1309 UNICODE_STRING uniTargetName;
1314 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1319 if( !NT_SUCCESS( ntStatus))
1322 try_return( ntStatus);
1325 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1327 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1329 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1331 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1333 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1335 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1337 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1339 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1341 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1343 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1345 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1347 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1350 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1353 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1354 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1357 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1360 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1362 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1365 // If we have a target name then see if it needs updating ...
1368 if( pDirEntry->TargetNameLength > 0)
1372 // Update the target name information if needed
1375 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1377 uniTargetName.MaximumLength = uniTargetName.Length;
1379 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1381 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1384 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1385 RtlCompareUnicodeString( &uniTargetName,
1386 &DirEntry->NameInformation.TargetName,
1391 // Update the target name
1394 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1396 uniTargetName.Buffer,
1397 uniTargetName.Length);
1399 if( !NT_SUCCESS( ntStatus))
1402 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1404 try_return( ntStatus);
1408 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1413 if( pDirEntry != NULL)
1416 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1424 AFSValidateSymLink( IN GUID *AuthGroup,
1425 IN AFSDirectoryCB *DirEntry)
1428 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1429 NTSTATUS ntStatus = STATUS_SUCCESS;
1430 AFSDirEnumEntry *pDirEntry = NULL;
1431 UNICODE_STRING uniTargetName;
1436 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1441 if( !NT_SUCCESS( ntStatus))
1444 try_return( ntStatus);
1447 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1448 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1451 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1454 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1456 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1458 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1461 // Update the target name information if needed
1464 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1466 uniTargetName.MaximumLength = uniTargetName.Length;
1468 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1470 if( uniTargetName.Length > 0)
1473 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1476 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1477 RtlCompareUnicodeString( &uniTargetName,
1478 &DirEntry->NameInformation.TargetName,
1483 // Update the target name
1486 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1488 uniTargetName.Buffer,
1489 uniTargetName.Length);
1491 if( !NT_SUCCESS( ntStatus))
1494 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1496 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1500 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1504 // If the FileType is the same then nothing to do since it IS
1508 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1511 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1513 try_return( ntStatus = STATUS_SUCCESS);
1516 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1518 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1520 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1522 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1524 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1526 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1528 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1530 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1532 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1535 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1538 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1539 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1542 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1545 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1547 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1551 if( pDirEntry != NULL)
1554 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1562 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1566 NTSTATUS ntStatus = STATUS_SUCCESS;
1567 IO_STATUS_BLOCK stIoStatus;
1570 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1571 AFS_TRACE_LEVEL_VERBOSE,
1572 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1573 (*ppObjectInfo)->FileType,
1574 (*ppObjectInfo)->FileId.Cell,
1575 (*ppObjectInfo)->FileId.Volume,
1576 (*ppObjectInfo)->FileId.Vnode,
1577 (*ppObjectInfo)->FileId.Unique,
1580 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1581 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1582 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1585 // We only act on the mount point itself, not the target. If the
1586 // node has been deleted then mark it as such otherwise indicate
1587 // it requires verification
1590 if( Reason == AFS_INVALIDATE_DELETED)
1592 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1597 if( Reason == AFS_INVALIDATE_FLUSHED)
1600 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1602 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1605 (*ppObjectInfo)->Expiration.QuadPart = 0;
1607 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1609 (*ppObjectInfo)->TargetFileId.Unique = 0;
1611 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1612 AFS_TRACE_LEVEL_VERBOSE,
1613 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1614 (*ppObjectInfo)->FileId.Cell,
1615 (*ppObjectInfo)->FileId.Volume,
1616 (*ppObjectInfo)->FileId.Vnode,
1617 (*ppObjectInfo)->FileId.Unique);
1619 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1622 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1624 if( Reason == AFS_INVALIDATE_CREDS)
1626 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1629 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1630 Reason == AFS_INVALIDATE_FLUSHED)
1632 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1636 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1639 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1642 FILE_ACTION_MODIFIED);
1644 try_return( ntStatus);
1648 // Depending on the reason for invalidation then perform work on the node
1654 case AFS_INVALIDATE_DELETED:
1658 // Mark this node as invalid
1661 (*ppObjectInfo)->Links = 0;
1663 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1665 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1666 AFS_TRACE_LEVEL_VERBOSE,
1667 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1668 (*ppObjectInfo)->FileId.Cell,
1669 (*ppObjectInfo)->FileId.Volume,
1670 (*ppObjectInfo)->FileId.Vnode,
1671 (*ppObjectInfo)->FileId.Unique);
1673 if( (*ppObjectInfo)->ParentObjectInformation != NULL)
1676 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1677 AFS_TRACE_LEVEL_VERBOSE,
1678 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1679 (*ppObjectInfo)->ParentObjectInformation->FileId.Cell,
1680 (*ppObjectInfo)->ParentObjectInformation->FileId.Volume,
1681 (*ppObjectInfo)->ParentObjectInformation->FileId.Vnode,
1682 (*ppObjectInfo)->ParentObjectInformation->FileId.Unique);
1684 SetFlag( (*ppObjectInfo)->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1686 (*ppObjectInfo)->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1688 (*ppObjectInfo)->ParentObjectInformation->Expiration.QuadPart = 0;
1691 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1693 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1697 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1700 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1703 FILE_ACTION_REMOVED);
1705 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1708 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1714 case AFS_INVALIDATE_FLUSHED:
1717 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1718 (*ppObjectInfo)->Fcb != NULL)
1721 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1722 AFS_TRACE_LEVEL_VERBOSE,
1723 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1724 (*ppObjectInfo)->FileId.Cell,
1725 (*ppObjectInfo)->FileId.Volume,
1726 (*ppObjectInfo)->FileId.Vnode,
1727 (*ppObjectInfo)->FileId.Unique);
1729 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1735 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1740 if( !NT_SUCCESS( stIoStatus.Status))
1743 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1744 AFS_TRACE_LEVEL_ERROR,
1745 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1746 (*ppObjectInfo)->FileId.Cell,
1747 (*ppObjectInfo)->FileId.Volume,
1748 (*ppObjectInfo)->FileId.Vnode,
1749 (*ppObjectInfo)->FileId.Unique,
1751 stIoStatus.Information);
1753 ntStatus = stIoStatus.Status;
1757 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1760 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1766 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1767 AFS_TRACE_LEVEL_WARNING,
1768 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1769 (*ppObjectInfo)->FileId.Cell,
1770 (*ppObjectInfo)->FileId.Volume,
1771 (*ppObjectInfo)->FileId.Vnode,
1772 (*ppObjectInfo)->FileId.Unique);
1774 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1778 __except( EXCEPTION_EXECUTE_HANDLER)
1781 ntStatus = GetExceptionCode();
1785 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1786 (*ppObjectInfo)->FileId.Cell,
1787 (*ppObjectInfo)->FileId.Volume,
1788 (*ppObjectInfo)->FileId.Vnode,
1789 (*ppObjectInfo)->FileId.Unique,
1792 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1795 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1798 // Clear out the extents
1799 // Get rid of them (note this involves waiting
1800 // for any writes or reads to the cache to complete)
1803 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1807 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1810 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1813 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1814 AFS_TRACE_LEVEL_VERBOSE,
1815 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1816 (*ppObjectInfo)->FileId.Cell,
1817 (*ppObjectInfo)->FileId.Volume,
1818 (*ppObjectInfo)->FileId.Vnode,
1819 (*ppObjectInfo)->FileId.Unique);
1821 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1824 // Fall through to the default processing
1830 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1832 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1836 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1839 if( Reason == AFS_INVALIDATE_CREDS)
1841 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1844 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1846 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1850 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1853 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1856 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1859 FILE_ACTION_MODIFIED);
1864 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1867 FILE_ACTION_MODIFIED);
1871 // Indicate this node requires re-evaluation for the remaining reasons
1874 (*ppObjectInfo)->Expiration.QuadPart = 0;
1876 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1877 AFS_TRACE_LEVEL_VERBOSE,
1878 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1879 (*ppObjectInfo)->FileId.Cell,
1880 (*ppObjectInfo)->FileId.Volume,
1881 (*ppObjectInfo)->FileId.Vnode,
1882 (*ppObjectInfo)->FileId.Unique);
1884 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1886 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1887 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1888 ( Reason == AFS_INVALIDATE_CALLBACK ||
1889 Reason == AFS_INVALIDATE_EXPIRED))
1891 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1892 AFS_INVALIDATE_DATA_VERSION)))
1895 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1909 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1912 NTSTATUS ntStatus = STATUS_SUCCESS;
1913 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1914 AFSVolumeCB *pVolumeCB = NULL;
1915 AFSFcb *pTargetDcb = NULL;
1916 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1917 AFSDirectoryCB *pCurrentDirEntry = NULL;
1918 BOOLEAN bIsChild = FALSE;
1919 ULONGLONG ullIndex = 0;
1920 AFSObjectInfoCB *pObjectInfo = NULL;
1926 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1927 AFS_TRACE_LEVEL_VERBOSE,
1928 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1929 InvalidateCB->FileID.Cell,
1930 InvalidateCB->FileID.Volume,
1931 InvalidateCB->FileID.Vnode,
1932 InvalidateCB->FileID.Unique,
1933 InvalidateCB->FileType,
1934 InvalidateCB->WholeVolume,
1935 InvalidateCB->Reason);
1938 // Need to locate the Fcb for the directory to purge
1941 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1942 AFS_TRACE_LEVEL_VERBOSE,
1943 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1944 &pDevExt->Specific.RDR.VolumeTreeLock,
1945 PsGetCurrentThread());
1948 // Starve any exclusive waiters on this paticular call
1951 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1954 // Locate the volume node
1957 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1959 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1961 (AFSBTreeEntry **)&pVolumeCB);
1963 if( pVolumeCB != NULL)
1966 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1968 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1969 AFS_TRACE_LEVEL_VERBOSE,
1970 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1975 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1977 if( !NT_SUCCESS( ntStatus) ||
1981 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1982 AFS_TRACE_LEVEL_WARNING,
1983 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1984 InvalidateCB->FileID.Cell,
1985 InvalidateCB->FileID.Volume,
1986 InvalidateCB->FileID.Vnode,
1987 InvalidateCB->FileID.Unique,
1990 try_return( ntStatus = STATUS_SUCCESS);
1994 // If this is a whole volume invalidation then go do it now
1997 if( InvalidateCB->WholeVolume)
2000 ntStatus = AFSInvalidateVolume( pVolumeCB,
2001 InvalidateCB->Reason);
2003 try_return( ntStatus);
2006 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
2009 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2012 pObjectInfo = &pVolumeCB->ObjectInformation;
2017 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2019 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2021 (AFSBTreeEntry **)&pObjectInfo);
2024 if( pObjectInfo != NULL)
2028 // Reference the node so it won't be torn down
2031 lCount = AFSObjectInfoIncrement( pObjectInfo);
2033 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2034 AFS_TRACE_LEVEL_VERBOSE,
2035 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
2040 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2042 if( !NT_SUCCESS( ntStatus) ||
2043 pObjectInfo == NULL)
2046 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2047 AFS_TRACE_LEVEL_VERBOSE,
2048 "AFSInvalidateCache Invalidation FAILURE Unable to locate object 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);
2058 AFSInvalidateObject( &pObjectInfo,
2059 InvalidateCB->Reason);
2063 if( pObjectInfo != NULL)
2066 lCount = AFSObjectInfoDecrement( pObjectInfo);
2068 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2069 AFS_TRACE_LEVEL_VERBOSE,
2070 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
2075 if ( pVolumeCB != NULL)
2078 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2080 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2081 AFS_TRACE_LEVEL_VERBOSE,
2082 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
2092 AFSIsChildOfParent( IN AFSFcb *Dcb,
2096 BOOLEAN bIsChild = FALSE;
2097 AFSFcb *pCurrentFcb = Fcb;
2099 while( pCurrentFcb != NULL)
2102 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2110 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2118 AFSCreateHighIndex( IN AFSFileID *FileID)
2121 ULONGLONG ullIndex = 0;
2123 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2130 AFSCreateLowIndex( IN AFSFileID *FileID)
2133 ULONGLONG ullIndex = 0;
2135 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2141 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2142 IN ACCESS_MASK GrantedAccess,
2143 IN BOOLEAN DirectoryEntry)
2146 BOOLEAN bAccessGranted = TRUE;
2149 // Check if we are asking for read/write and granted only read only
2150 // NOTE: There will be more checks here
2153 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2155 AFSCheckForReadOnlyAccess( GrantedAccess,
2159 bAccessGranted = FALSE;
2162 return bAccessGranted;
2166 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2169 NTSTATUS ntStatus = STATUS_SUCCESS;
2170 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2176 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2178 if( AFSGlobalRoot == NULL)
2185 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2188 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2195 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2202 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2203 IN UNICODE_STRING *SubstituteName,
2204 IN ULONG StringIndex)
2207 NTSTATUS ntStatus = STATUS_SUCCESS;
2208 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2209 AFSSysNameCB *pSysName = NULL;
2210 ERESOURCE *pSysNameLock = NULL;
2213 UNICODE_STRING uniSysName;
2220 if( IoIs32bitProcess( NULL))
2223 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2225 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2230 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2232 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2236 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2238 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2242 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2243 AFS_TRACE_LEVEL_VERBOSE,
2244 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2246 PsGetCurrentThread());
2248 AFSAcquireShared( pSysNameLock,
2252 // Find where we are in the list
2255 while( pSysName != NULL &&
2256 ulIndex < StringIndex)
2259 pSysName = pSysName->fLink;
2264 if( pSysName == NULL)
2267 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2270 RtlInitUnicodeString( &uniSysName,
2273 // If it is a full component of @SYS then just substitue the
2277 if( RtlCompareUnicodeString( &uniSysName,
2282 SubstituteName->Length = pSysName->SysName.Length;
2283 SubstituteName->MaximumLength = SubstituteName->Length;
2285 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2286 SubstituteName->Length,
2287 AFS_SUBST_BUFFER_TAG);
2289 if( SubstituteName->Buffer == NULL)
2292 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2295 RtlCopyMemory( SubstituteName->Buffer,
2296 pSysName->SysName.Buffer,
2297 pSysName->SysName.Length);
2304 while( ComponentName->Buffer[ usIndex] != L'@')
2310 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2311 SubstituteName->MaximumLength = SubstituteName->Length;
2313 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2314 SubstituteName->Length,
2315 AFS_SUBST_BUFFER_TAG);
2317 if( SubstituteName->Buffer == NULL)
2320 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2323 RtlCopyMemory( SubstituteName->Buffer,
2324 ComponentName->Buffer,
2325 usIndex * sizeof( WCHAR));
2327 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2328 pSysName->SysName.Buffer,
2329 pSysName->SysName.Length);
2334 AFSReleaseResource( pSysNameLock);
2341 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2342 IN OUT UNICODE_STRING *ComponentName,
2343 IN UNICODE_STRING *SubstituteName,
2344 IN OUT UNICODE_STRING *RemainingPath,
2345 IN BOOLEAN FreePathName)
2348 NTSTATUS ntStatus = STATUS_SUCCESS;
2349 UNICODE_STRING uniPathName;
2350 USHORT usPrefixNameLen = 0;
2351 SHORT sNameLenDelta = 0;
2357 // If the passed in name can handle the additional length
2358 // then just moves things around
2361 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2363 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2365 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2368 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2371 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2372 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2373 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2376 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2377 SubstituteName->Buffer,
2378 SubstituteName->Length);
2380 FullPathName->Length += sNameLenDelta;
2382 ComponentName->Length += sNameLenDelta;
2384 ComponentName->MaximumLength = ComponentName->Length;
2386 if ( RemainingPath->Buffer)
2389 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2392 try_return( ntStatus);
2396 // Need to re-allocate the buffer
2399 uniPathName.Length = FullPathName->Length -
2400 ComponentName->Length +
2401 SubstituteName->Length;
2403 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2405 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2406 uniPathName.MaximumLength,
2407 AFS_NAME_BUFFER_FOUR_TAG);
2409 if( uniPathName.Buffer == NULL)
2412 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2415 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2417 usPrefixNameLen *= sizeof( WCHAR);
2419 RtlZeroMemory( uniPathName.Buffer,
2420 uniPathName.MaximumLength);
2422 RtlCopyMemory( uniPathName.Buffer,
2423 FullPathName->Buffer,
2426 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2427 SubstituteName->Buffer,
2428 SubstituteName->Length);
2430 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2433 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2434 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2435 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2438 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2440 ComponentName->Length += sNameLenDelta;
2442 ComponentName->MaximumLength = ComponentName->Length;
2444 if ( RemainingPath->Buffer)
2447 RemainingPath->Buffer = uniPathName.Buffer
2448 + (RemainingPath->Buffer - FullPathName->Buffer)
2449 + sNameLenDelta/sizeof( WCHAR);
2454 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2457 *FullPathName = uniPathName;
2468 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2472 NTSTATUS ntStatus = STATUS_SUCCESS;
2473 AFSObjectInfoCB *pCurrentObject = NULL;
2474 AFSObjectInfoCB *pNextObject = NULL;
2476 AFSFcb *pFcb = NULL;
2482 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2483 AFS_TRACE_LEVEL_VERBOSE,
2484 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2485 VolumeCB->ObjectInformation.FileId.Cell,
2486 VolumeCB->ObjectInformation.FileId.Volume,
2487 VolumeCB->ObjectInformation.FileId.Vnode,
2488 VolumeCB->ObjectInformation.FileId.Unique,
2492 // Depending on the reason for invalidation then perform work on the node
2498 case AFS_INVALIDATE_DELETED:
2502 // Mark this volume as invalid
2505 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2507 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2514 // Invalidate the volume root directory
2517 pCurrentObject = &VolumeCB->ObjectInformation;
2519 if ( pCurrentObject )
2522 lCount = AFSObjectInfoIncrement( pCurrentObject);
2524 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2525 AFS_TRACE_LEVEL_VERBOSE,
2526 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2530 AFSInvalidateObject( &pCurrentObject,
2533 if ( pCurrentObject)
2536 lCount = AFSObjectInfoDecrement( pCurrentObject);
2538 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2539 AFS_TRACE_LEVEL_VERBOSE,
2540 "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
2547 // Apply invalidation to all other volume objects
2550 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2553 pCurrentObject = VolumeCB->ObjectInfoListHead;
2555 if ( pCurrentObject)
2559 // Reference the node so it won't be torn down
2562 lCount = AFSObjectInfoIncrement( pCurrentObject);
2564 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2565 AFS_TRACE_LEVEL_VERBOSE,
2566 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2571 while( pCurrentObject != NULL)
2574 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2580 // Reference the node so it won't be torn down
2583 lCount = AFSObjectInfoIncrement( pNextObject);
2585 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2586 AFS_TRACE_LEVEL_VERBOSE,
2587 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2592 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2594 AFSInvalidateObject( &pCurrentObject,
2597 if ( pCurrentObject )
2600 lCount = AFSObjectInfoDecrement( pCurrentObject);
2602 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2603 AFS_TRACE_LEVEL_VERBOSE,
2604 "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
2609 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2612 pCurrentObject = pNextObject;
2615 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2622 AFSInvalidateAllVolumes( VOID)
2624 AFSVolumeCB *pVolumeCB = NULL;
2625 AFSVolumeCB *pNextVolumeCB = NULL;
2626 AFSDeviceExt *pRDRDeviceExt = NULL;
2629 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2631 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2632 AFS_TRACE_LEVEL_VERBOSE,
2633 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %08lX SHARED %08lX\n",
2634 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2635 PsGetCurrentThread());
2637 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2640 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2645 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2646 AFS_TRACE_LEVEL_VERBOSE,
2647 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %08lX SHARED %08lX\n",
2648 pVolumeCB->ObjectInfoTree.TreeLock,
2649 PsGetCurrentThread());
2651 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
2653 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2654 AFS_TRACE_LEVEL_VERBOSE,
2655 "AFSInvalidateAllVolumes Increment count on volume %08lX Cnt %d\n",
2660 while( pVolumeCB != NULL)
2663 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2668 lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
2670 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2671 AFS_TRACE_LEVEL_VERBOSE,
2672 "AFSInvalidateAllVolumes Increment count on volume %08lX Cnt %d\n",
2677 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2679 // do I need to hold the volume lock here?
2681 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2683 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2686 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2688 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2689 AFS_TRACE_LEVEL_VERBOSE,
2690 "AFSInvalidateAllVolumes Decrement count on volume %08lX Cnt %d\n",
2694 pVolumeCB = pNextVolumeCB;
2697 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2701 AFSVerifyEntry( IN GUID *AuthGroup,
2702 IN AFSDirectoryCB *DirEntry)
2705 NTSTATUS ntStatus = STATUS_SUCCESS;
2706 AFSDirEnumEntry *pDirEnumEntry = NULL;
2707 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2708 IO_STATUS_BLOCK stIoStatus;
2713 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2714 AFS_TRACE_LEVEL_VERBOSE_2,
2715 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2716 &DirEntry->NameInformation.FileName,
2717 pObjectInfo->FileId.Cell,
2718 pObjectInfo->FileId.Volume,
2719 pObjectInfo->FileId.Vnode,
2720 pObjectInfo->FileId.Unique);
2722 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2727 if( !NT_SUCCESS( ntStatus))
2730 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2731 AFS_TRACE_LEVEL_ERROR,
2732 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2733 &DirEntry->NameInformation.FileName,
2734 pObjectInfo->FileId.Cell,
2735 pObjectInfo->FileId.Volume,
2736 pObjectInfo->FileId.Vnode,
2737 pObjectInfo->FileId.Unique,
2740 try_return( ntStatus);
2744 // Check the data version of the file
2747 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2749 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2752 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2753 AFS_TRACE_LEVEL_VERBOSE,
2754 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2755 pObjectInfo->DataVersion.QuadPart,
2756 &DirEntry->NameInformation.FileName,
2757 pObjectInfo->FileId.Cell,
2758 pObjectInfo->FileId.Volume,
2759 pObjectInfo->FileId.Vnode,
2760 pObjectInfo->FileId.Unique);
2763 // We are ok, just get out
2766 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2768 try_return( ntStatus = STATUS_SUCCESS);
2773 // New data version so we will need to process the node based on the type
2776 switch( pDirEnumEntry->FileType)
2779 case AFS_FILE_TYPE_MOUNTPOINT:
2783 // For a mount point we need to ensure the target is the same
2786 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2787 &pDirEnumEntry->TargetFileId))
2793 // Update the metadata for the entry
2796 ntStatus = AFSUpdateMetaData( DirEntry,
2799 if( NT_SUCCESS( ntStatus))
2802 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2808 case AFS_FILE_TYPE_SYMLINK:
2812 // Update the metadata for the entry
2815 ntStatus = AFSUpdateMetaData( DirEntry,
2818 if( NT_SUCCESS( ntStatus))
2821 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2827 case AFS_FILE_TYPE_FILE:
2829 FILE_OBJECT * pCCFileObject = NULL;
2830 BOOLEAN bPurgeExtents = FALSE;
2832 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
2835 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2836 AFS_TRACE_LEVEL_VERBOSE,
2837 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
2838 &DirEntry->NameInformation.FileName,
2839 pObjectInfo->FileId.Cell,
2840 pObjectInfo->FileId.Volume,
2841 pObjectInfo->FileId.Vnode,
2842 pObjectInfo->FileId.Unique,
2843 pObjectInfo->DataVersion.LowPart,
2844 pDirEnumEntry->DataVersion.LowPart
2847 bPurgeExtents = TRUE;
2850 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2853 bPurgeExtents = TRUE;
2855 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2856 AFS_TRACE_LEVEL_VERBOSE,
2857 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2858 &DirEntry->NameInformation.FileName,
2859 pObjectInfo->FileId.Cell,
2860 pObjectInfo->FileId.Volume,
2861 pObjectInfo->FileId.Vnode,
2862 pObjectInfo->FileId.Unique);
2864 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2867 if( pObjectInfo->Fcb != NULL)
2870 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2871 AFS_TRACE_LEVEL_VERBOSE,
2872 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2873 &DirEntry->NameInformation.FileName,
2874 pObjectInfo->FileId.Cell,
2875 pObjectInfo->FileId.Volume,
2876 pObjectInfo->FileId.Vnode,
2877 pObjectInfo->FileId.Unique);
2879 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2885 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2890 if( !NT_SUCCESS( stIoStatus.Status))
2893 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2894 AFS_TRACE_LEVEL_ERROR,
2895 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2896 &DirEntry->NameInformation.FileName,
2897 pObjectInfo->FileId.Cell,
2898 pObjectInfo->FileId.Volume,
2899 pObjectInfo->FileId.Vnode,
2900 pObjectInfo->FileId.Unique,
2902 stIoStatus.Information);
2904 ntStatus = stIoStatus.Status;
2907 if ( bPurgeExtents &&
2908 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
2911 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2917 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2918 AFS_TRACE_LEVEL_WARNING,
2919 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2920 &DirEntry->NameInformation.FileName,
2921 pObjectInfo->FileId.Cell,
2922 pObjectInfo->FileId.Volume,
2923 pObjectInfo->FileId.Vnode,
2924 pObjectInfo->FileId.Unique);
2926 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2930 __except( EXCEPTION_EXECUTE_HANDLER)
2932 ntStatus = GetExceptionCode();
2936 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2937 &DirEntry->NameInformation.FileName,
2938 pObjectInfo->FileId.Cell,
2939 pObjectInfo->FileId.Volume,
2940 pObjectInfo->FileId.Vnode,
2941 pObjectInfo->FileId.Unique,
2944 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
2947 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
2951 AFSFlushExtents( pObjectInfo->Fcb,
2956 // Reacquire the Fcb to purge the cache
2959 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2960 AFS_TRACE_LEVEL_VERBOSE,
2961 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2962 &pObjectInfo->Fcb->NPFcb->Resource,
2963 PsGetCurrentThread());
2965 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2969 // Update the metadata for the entry
2972 ntStatus = AFSUpdateMetaData( DirEntry,
2975 if( !NT_SUCCESS( ntStatus))
2978 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2979 AFS_TRACE_LEVEL_ERROR,
2980 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2981 &DirEntry->NameInformation.FileName,
2982 pObjectInfo->FileId.Cell,
2983 pObjectInfo->FileId.Volume,
2984 pObjectInfo->FileId.Vnode,
2985 pObjectInfo->FileId.Unique,
2992 // Update file sizes
2995 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2996 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2997 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2999 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3000 AFS_TRACE_LEVEL_VERBOSE,
3001 "AFSVerifyEntry Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
3002 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3003 PsGetCurrentThread());
3005 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3008 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3010 if ( pCCFileObject != NULL)
3012 CcSetFileSizes( pCCFileObject,
3013 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3016 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3017 AFS_TRACE_LEVEL_VERBOSE,
3018 "AFSVerifyEntry Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
3019 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3020 PsGetCurrentThread());
3022 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3024 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3030 // Update the metadata for the entry
3033 ntStatus = AFSUpdateMetaData( DirEntry,
3036 if( !NT_SUCCESS( ntStatus))
3039 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3040 AFS_TRACE_LEVEL_ERROR,
3041 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3042 &DirEntry->NameInformation.FileName,
3043 pObjectInfo->FileId.Cell,
3044 pObjectInfo->FileId.Volume,
3045 pObjectInfo->FileId.Vnode,
3046 pObjectInfo->FileId.Unique,
3052 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3053 AFS_TRACE_LEVEL_WARNING,
3054 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3055 &DirEntry->NameInformation.FileName,
3056 pObjectInfo->FileId.Cell,
3057 pObjectInfo->FileId.Volume,
3058 pObjectInfo->FileId.Vnode,
3059 pObjectInfo->FileId.Unique);
3062 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3067 case AFS_FILE_TYPE_DIRECTORY:
3070 AFSFcb *pCurrentFcb = NULL;
3071 AFSDirectoryCB *pCurrentDirEntry = NULL;
3074 // For a directory or root entry flush the content of
3075 // the directory enumeration.
3078 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3081 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3082 AFS_TRACE_LEVEL_VERBOSE_2,
3083 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3084 &DirEntry->NameInformation.FileName,
3085 pObjectInfo->FileId.Cell,
3086 pObjectInfo->FileId.Volume,
3087 pObjectInfo->FileId.Vnode,
3088 pObjectInfo->FileId.Unique);
3090 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3093 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3096 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3098 if ( !NT_SUCCESS( ntStatus))
3101 try_return( ntStatus);
3106 // Update the metadata for the entry
3109 ntStatus = AFSUpdateMetaData( DirEntry,
3112 if( NT_SUCCESS( ntStatus))
3115 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3121 case AFS_FILE_TYPE_DFSLINK:
3124 UNICODE_STRING uniTargetName;
3127 // For a DFS link need to check the target name has not changed
3130 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3132 uniTargetName.MaximumLength = uniTargetName.Length;
3134 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3136 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3139 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3140 RtlCompareUnicodeString( &uniTargetName,
3141 &DirEntry->NameInformation.TargetName,
3146 // Update the target name
3149 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3151 uniTargetName.Buffer,
3152 uniTargetName.Length);
3154 if( !NT_SUCCESS( ntStatus))
3157 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3163 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3166 // Update the metadata for the entry
3169 ntStatus = AFSUpdateMetaData( DirEntry,
3172 if( NT_SUCCESS( ntStatus))
3175 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3183 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3184 AFS_TRACE_LEVEL_WARNING,
3185 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3186 pObjectInfo->FileType,
3187 &DirEntry->NameInformation.FileName,
3188 pObjectInfo->FileId.Cell,
3189 pObjectInfo->FileId.Volume,
3190 pObjectInfo->FileId.Vnode,
3191 pObjectInfo->FileId.Unique);
3198 if( pDirEnumEntry != NULL)
3201 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3209 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3212 NTSTATUS ntStatus = STATUS_SUCCESS;
3213 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3214 ULONGLONG ullIndex = 0;
3215 AFSVolumeCB *pVolumeCB = NULL;
3216 AFSFcb *pFcb = NULL;
3217 AFSObjectInfoCB *pCurrentObject = NULL;
3223 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3224 AFS_TRACE_LEVEL_VERBOSE,
3225 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3226 VolumeStatus->Online,
3227 VolumeStatus->FileID.Cell,
3228 VolumeStatus->FileID.Volume);
3231 // Need to locate the Fcb for the directory to purge
3234 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3235 AFS_TRACE_LEVEL_VERBOSE,
3236 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3237 &pDevExt->Specific.RDR.VolumeTreeLock,
3238 PsGetCurrentThread());
3240 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3243 // Locate the volume node
3246 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3248 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3250 (AFSBTreeEntry **)&pVolumeCB);
3252 if( pVolumeCB != NULL)
3255 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3257 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3258 AFS_TRACE_LEVEL_VERBOSE,
3259 "AFSSetVolumeState Increment count on volume %08lX Cnt %d\n",
3263 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3266 // Set the volume state accordingly
3269 if( VolumeStatus->Online)
3272 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3277 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3280 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3283 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3285 while( pCurrentObject != NULL)
3288 if( VolumeStatus->Online)
3291 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3293 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3295 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3300 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3303 pFcb = pCurrentObject->Fcb;
3306 !(VolumeStatus->Online) &&
3307 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3310 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3311 AFS_TRACE_LEVEL_ERROR,
3312 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3313 VolumeStatus->FileID.Cell,
3314 VolumeStatus->FileID.Volume);
3317 // Clear out the extents
3320 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3321 AFS_TRACE_LEVEL_VERBOSE,
3322 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3323 &pFcb->NPFcb->Specific.File.ExtentsResource,
3324 PsGetCurrentThread());
3326 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3329 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3331 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3335 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3336 AFS_TRACE_LEVEL_VERBOSE,
3337 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3338 &pFcb->NPFcb->Specific.File.ExtentsResource,
3339 PsGetCurrentThread());
3341 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3344 // And get rid of them (note this involves waiting
3345 // for any writes or reads to the cache to complete)
3348 AFSTearDownFcbExtents( pFcb,
3352 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3355 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3357 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3359 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3360 AFS_TRACE_LEVEL_VERBOSE,
3361 "AFSSetVolumeState Decrement count on volume %08lX Cnt %d\n",
3368 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3376 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3379 NTSTATUS ntStatus = STATUS_SUCCESS;
3384 if( AFSGlobalRoot == NULL)
3387 try_return( ntStatus);
3390 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3394 // Set the network state according to the information
3397 if( NetworkStatus->Online)
3400 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3405 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3408 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3419 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3423 NTSTATUS ntStatus = STATUS_SUCCESS;
3424 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3425 BOOLEAN bAcquiredLock = FALSE;
3426 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3427 AFSFcb *pFcb = NULL;
3432 AFSDbgLogMsg( 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 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3444 AFS_TRACE_LEVEL_VERBOSE,
3445 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX 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 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3464 AFS_TRACE_LEVEL_ERROR,
3465 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX 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)
3495 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3496 AFS_TRACE_LEVEL_VERBOSE,
3497 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3499 &pCurrentDirEntry->NameInformation.FileName);
3501 AFSDeleteDirEntry( ObjectInfo,
3507 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3509 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3510 AFS_TRACE_LEVEL_VERBOSE,
3511 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3513 pCurrentDirEntry->DirOpenReferenceCount);
3516 // We pull the short name from the parent tree since it could change below
3519 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3522 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3523 AFS_TRACE_LEVEL_VERBOSE,
3524 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3526 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3527 &pCurrentDirEntry->NameInformation.FileName);
3529 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3532 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3537 pCurrentDirEntry = pNextDirEntry;
3541 // Reget the directory contents
3544 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3547 if ( !NT_SUCCESS( ntStatus))
3549 try_return( ntStatus);
3553 // Now start again and tear down any entries not valid
3556 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3558 while( pCurrentDirEntry != NULL)
3561 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3563 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3566 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3567 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3568 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3571 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3574 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3576 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3577 AFS_TRACE_LEVEL_VERBOSE,
3578 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3580 &pCurrentDirEntry->NameInformation.FileName);
3582 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3587 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3590 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3591 AFS_TRACE_LEVEL_VERBOSE,
3592 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3594 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3595 &pCurrentDirEntry->NameInformation.FileName);
3599 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3601 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3602 AFS_TRACE_LEVEL_VERBOSE,
3603 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3605 &pCurrentDirEntry->NameInformation.FileName);
3610 pCurrentDirEntry = pNextDirEntry;
3615 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3616 AFS_TRACE_LEVEL_VERBOSE,
3617 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3619 pCurrentDirEntry->DirOpenReferenceCount);
3621 if( pCurrentDirEntry->DirOpenReferenceCount <= 0)
3624 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3625 AFS_TRACE_LEVEL_VERBOSE,
3626 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3627 &pCurrentDirEntry->NameInformation.FileName,
3628 ObjectInfo->FileId.Cell,
3629 ObjectInfo->FileId.Volume,
3630 ObjectInfo->FileId.Vnode,
3631 ObjectInfo->FileId.Unique);
3633 AFSDeleteDirEntry( ObjectInfo,
3639 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3640 AFS_TRACE_LEVEL_VERBOSE,
3641 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3643 &pCurrentDirEntry->NameInformation.FileName,
3644 ObjectInfo->FileId.Cell,
3645 ObjectInfo->FileId.Volume,
3646 ObjectInfo->FileId.Vnode,
3647 ObjectInfo->FileId.Unique);
3649 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3651 AFSRemoveNameEntry( ObjectInfo,
3655 pCurrentDirEntry = pNextDirEntry;
3659 if( !AFSValidateDirList( ObjectInfo))
3662 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3671 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3679 AFSIsVolumeFID( IN AFSFileID *FileID)
3682 BOOLEAN bIsVolume = FALSE;
3684 if( FileID->Vnode == 1 &&
3685 FileID->Unique == 1)
3695 AFSIsFinalNode( IN AFSFcb *Fcb)
3698 BOOLEAN bIsFinalNode = FALSE;
3700 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3701 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3702 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3703 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3704 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3707 bIsFinalNode = TRUE;
3712 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3713 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3716 return bIsFinalNode;
3720 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3721 IN AFSDirEnumEntry *DirEnumEntry)
3724 NTSTATUS ntStatus = STATUS_SUCCESS;
3725 UNICODE_STRING uniTargetName;
3726 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3731 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3733 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3735 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3737 pObjectInfo->FileType = DirEnumEntry->FileType;
3739 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3741 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3743 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3745 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3747 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3749 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3751 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3753 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3756 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3759 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3760 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3763 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3766 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3768 pObjectInfo->Links = DirEnumEntry->Links;
3770 if( DirEnumEntry->TargetNameLength > 0 &&
3771 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3772 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3776 // Update the target name information if needed
3779 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3781 uniTargetName.MaximumLength = uniTargetName.Length;
3783 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3785 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3788 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3789 RtlCompareUnicodeString( &uniTargetName,
3790 &DirEntry->NameInformation.TargetName,
3795 // Update the target name
3798 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3800 uniTargetName.Buffer,
3801 uniTargetName.Length);
3803 if( !NT_SUCCESS( ntStatus))
3806 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3808 try_return( ntStatus);
3812 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3814 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3815 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3818 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3821 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3822 DirEntry->NameInformation.TargetName.Buffer != NULL)
3824 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3827 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3829 DirEntry->NameInformation.TargetName.Length = 0;
3830 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3831 DirEntry->NameInformation.TargetName.Buffer = NULL;
3833 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3845 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3847 IN BOOLEAN FastCall,
3848 IN BOOLEAN bSafeToPurge)
3851 NTSTATUS ntStatus = STATUS_SUCCESS;
3852 LARGE_INTEGER liSystemTime;
3853 AFSDirEnumEntry *pDirEnumEntry = NULL;
3854 AFSFcb *pCurrentFcb = NULL;
3855 BOOLEAN bReleaseFcb = FALSE;
3856 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3862 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3866 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3867 AFS_TRACE_LEVEL_VERBOSE_2,
3868 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3869 &DirEntry->NameInformation.FileName,
3870 pObjectInfo->FileId.Cell,
3871 pObjectInfo->FileId.Volume,
3872 pObjectInfo->FileId.Vnode,
3873 pObjectInfo->FileId.Unique,
3877 // If this is a fake node then bail since the service knows nothing about it
3880 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3883 try_return( ntStatus);
3887 // This routine ensures that the current entry is valid by:
3889 // 1) Checking that the expiration time is non-zero and after where we
3893 KeQuerySystemTime( &liSystemTime);
3895 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3896 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3897 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3898 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3901 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3902 AFS_TRACE_LEVEL_VERBOSE_2,
3903 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3904 &DirEntry->NameInformation.FileName,
3905 pObjectInfo->FileId.Cell,
3906 pObjectInfo->FileId.Volume,
3907 pObjectInfo->FileId.Vnode,
3908 pObjectInfo->FileId.Unique);
3910 try_return( ntStatus);
3914 // This node requires updating
3917 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3922 if( !NT_SUCCESS( ntStatus))
3925 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3926 AFS_TRACE_LEVEL_ERROR,
3927 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3929 &DirEntry->NameInformation.FileName,
3930 pObjectInfo->FileId.Cell,
3931 pObjectInfo->FileId.Volume,
3932 pObjectInfo->FileId.Vnode,
3933 pObjectInfo->FileId.Unique,
3937 // Failed validation of node so return access-denied
3940 try_return( ntStatus);
3943 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3944 AFS_TRACE_LEVEL_VERBOSE,
3945 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3947 &DirEntry->NameInformation.FileName,
3948 pObjectInfo->FileId.Cell,
3949 pObjectInfo->FileId.Volume,
3950 pObjectInfo->FileId.Vnode,
3951 pObjectInfo->FileId.Unique,
3952 pObjectInfo->DataVersion.QuadPart,
3953 pDirEnumEntry->DataVersion.QuadPart,
3954 pDirEnumEntry->FileType);
3958 // Based on the file type, process the node
3961 switch( pDirEnumEntry->FileType)
3964 case AFS_FILE_TYPE_MOUNTPOINT:
3968 // Update the metadata for the entry
3971 ntStatus = AFSUpdateMetaData( DirEntry,
3974 if( NT_SUCCESS( ntStatus))
3977 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3983 case AFS_FILE_TYPE_SYMLINK:
3984 case AFS_FILE_TYPE_DFSLINK:
3988 // Update the metadata for the entry
3991 ntStatus = AFSUpdateMetaData( DirEntry,
3994 if( NT_SUCCESS( ntStatus))
3997 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4003 case AFS_FILE_TYPE_FILE:
4006 BOOLEAN bPurgeExtents = FALSE;
4009 // For a file where the data version has become invalid we need to
4010 // fail any current extent requests and purge the cache for the file
4011 // Can't hold the Fcb resource while doing this
4014 if( pObjectInfo->Fcb != NULL &&
4015 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4016 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4019 pCurrentFcb = pObjectInfo->Fcb;
4021 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4024 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4025 AFS_TRACE_LEVEL_VERBOSE,
4026 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
4027 &pCurrentFcb->NPFcb->Resource,
4028 PsGetCurrentThread());
4030 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4036 if( pCurrentFcb != NULL)
4039 IO_STATUS_BLOCK stIoStatus;
4041 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4042 AFS_TRACE_LEVEL_VERBOSE_2,
4043 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4044 &DirEntry->NameInformation.FileName,
4045 pObjectInfo->FileId.Cell,
4046 pObjectInfo->FileId.Volume,
4047 pObjectInfo->FileId.Vnode,
4048 pObjectInfo->FileId.Unique);
4050 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4053 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4054 AFS_TRACE_LEVEL_VERBOSE,
4055 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4056 &DirEntry->NameInformation.FileName,
4057 pObjectInfo->FileId.Cell,
4058 pObjectInfo->FileId.Volume,
4059 pObjectInfo->FileId.Vnode,
4060 pObjectInfo->FileId.Unique,
4061 pObjectInfo->DataVersion.LowPart,
4062 pDirEnumEntry->DataVersion.LowPart
4065 bPurgeExtents = TRUE;
4071 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4073 bPurgeExtents = TRUE;
4075 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4076 AFS_TRACE_LEVEL_VERBOSE,
4077 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4078 &DirEntry->NameInformation.FileName,
4079 pObjectInfo->FileId.Cell,
4080 pObjectInfo->FileId.Volume,
4081 pObjectInfo->FileId.Vnode,
4082 pObjectInfo->FileId.Unique);
4084 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4087 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4088 AFS_TRACE_LEVEL_VERBOSE,
4089 "AFSValidateEntry Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
4090 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4091 PsGetCurrentThread());
4093 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4097 // Release Fcb->Resource to avoid Trend Micro deadlock
4100 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
4105 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4110 if( !NT_SUCCESS( stIoStatus.Status))
4113 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4114 AFS_TRACE_LEVEL_ERROR,
4115 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4116 &DirEntry->NameInformation.FileName,
4117 pObjectInfo->FileId.Cell,
4118 pObjectInfo->FileId.Volume,
4119 pObjectInfo->FileId.Vnode,
4120 pObjectInfo->FileId.Unique,
4122 stIoStatus.Information);
4124 ntStatus = stIoStatus.Status;
4127 if ( bPurgeExtents &&
4128 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4131 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4137 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
4138 AFS_TRACE_LEVEL_WARNING,
4139 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4140 &DirEntry->NameInformation.FileName,
4141 pObjectInfo->FileId.Cell,
4142 pObjectInfo->FileId.Volume,
4143 pObjectInfo->FileId.Vnode,
4144 pObjectInfo->FileId.Unique);
4146 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4150 __except( EXCEPTION_EXECUTE_HANDLER)
4152 ntStatus = GetExceptionCode();
4156 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4157 &DirEntry->NameInformation.FileName,
4158 pObjectInfo->FileId.Cell,
4159 pObjectInfo->FileId.Volume,
4160 pObjectInfo->FileId.Vnode,
4161 pObjectInfo->FileId.Unique,
4164 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4167 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4168 AFS_TRACE_LEVEL_VERBOSE,
4169 "AFSValidateEntry Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
4170 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4171 PsGetCurrentThread());
4173 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4175 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4184 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4189 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4191 bReleaseFcb = FALSE;
4193 if ( bPurgeExtents &&
4196 AFSFlushExtents( pCurrentFcb,
4203 // Update the metadata for the entry but only if it is safe to do so.
4204 // If it was determined that a data version change has occurred or
4205 // that a pending data verification was required, do not update the
4206 // ObjectInfo meta data or the FileObject size information. That
4207 // way it is consistent for the next time that the data is verified
4211 if ( !(bPurgeExtents && bSafeToPurge))
4214 ntStatus = AFSUpdateMetaData( DirEntry,
4217 if( !NT_SUCCESS( ntStatus))
4220 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4221 AFS_TRACE_LEVEL_ERROR,
4222 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4223 &DirEntry->NameInformation.FileName,
4224 pObjectInfo->FileId.Cell,
4225 pObjectInfo->FileId.Volume,
4226 pObjectInfo->FileId.Vnode,
4227 pObjectInfo->FileId.Unique,
4233 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4236 // Update file sizes
4239 if( pObjectInfo->Fcb != NULL)
4241 FILE_OBJECT *pCCFileObject;
4243 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4244 AFS_TRACE_LEVEL_VERBOSE,
4245 "AFSValidateEntry Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
4246 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4247 PsGetCurrentThread());
4249 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4252 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4254 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4255 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4256 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4258 if ( pCCFileObject != NULL)
4260 CcSetFileSizes( pCCFileObject,
4261 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4264 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4265 AFS_TRACE_LEVEL_VERBOSE,
4266 "AFSValidateEntry Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
4267 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4268 PsGetCurrentThread());
4270 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4276 case AFS_FILE_TYPE_DIRECTORY:
4279 AFSDirectoryCB *pCurrentDirEntry = NULL;
4281 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4285 // For a directory or root entry flush the content of
4286 // the directory enumeration.
4289 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4290 AFS_TRACE_LEVEL_VERBOSE,
4291 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4292 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4293 PsGetCurrentThread());
4295 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4298 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4299 AFS_TRACE_LEVEL_VERBOSE_2,
4300 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4301 &DirEntry->NameInformation.FileName,
4302 pObjectInfo->FileId.Cell,
4303 pObjectInfo->FileId.Volume,
4304 pObjectInfo->FileId.Vnode,
4305 pObjectInfo->FileId.Unique);
4307 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4310 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4313 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4316 if( !NT_SUCCESS( ntStatus))
4319 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4320 AFS_TRACE_LEVEL_ERROR,
4321 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4322 &DirEntry->NameInformation.FileName,
4323 pObjectInfo->FileId.Cell,
4324 pObjectInfo->FileId.Volume,
4325 pObjectInfo->FileId.Vnode,
4326 pObjectInfo->FileId.Unique,
4334 // Update the metadata for the entry
4337 ntStatus = AFSUpdateMetaData( DirEntry,
4340 if( NT_SUCCESS( ntStatus))
4343 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4351 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4352 AFS_TRACE_LEVEL_WARNING,
4353 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4354 pObjectInfo->FileType,
4356 &DirEntry->NameInformation.FileName,
4357 pObjectInfo->FileId.Cell,
4358 pObjectInfo->FileId.Volume,
4359 pObjectInfo->FileId.Vnode,
4360 pObjectInfo->FileId.Unique);
4370 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4373 if( pDirEnumEntry != NULL)
4376 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4384 AFSInitializeSpecialShareNameList()
4387 NTSTATUS ntStatus = STATUS_SUCCESS;
4388 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4389 AFSObjectInfoCB *pObjectInfoCB = NULL;
4390 UNICODE_STRING uniShareName;
4391 ULONG ulEntryLength = 0;
4392 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4397 RtlInitUnicodeString( &uniShareName,
4400 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4403 if( pObjectInfoCB == NULL)
4406 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4409 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4410 AFS_TRACE_LEVEL_VERBOSE,
4411 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
4414 pObjectInfoCB->ObjectReferenceCount = 1;
4416 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4418 ulEntryLength = sizeof( AFSDirectoryCB) +
4419 uniShareName.Length;
4421 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4425 if( pDirNode == NULL)
4428 AFSDeleteObjectInfo( pObjectInfoCB);
4430 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4433 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4434 sizeof( AFSNonPagedDirectoryCB),
4435 AFS_DIR_ENTRY_NP_TAG);
4437 if( pNonPagedDirEntry == NULL)
4440 ExFreePool( pDirNode);
4442 AFSDeleteObjectInfo( pObjectInfoCB);
4444 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4447 RtlZeroMemory( pDirNode,
4450 RtlZeroMemory( pNonPagedDirEntry,
4451 sizeof( AFSNonPagedDirectoryCB));
4453 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4455 pDirNode->NonPaged = pNonPagedDirEntry;
4457 pDirNode->ObjectInformation = pObjectInfoCB;
4463 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4465 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4467 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4469 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4471 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4472 uniShareName.Buffer,
4473 pDirNode->NameInformation.FileName.Length);
4475 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4478 AFSSpecialShareNames = pDirNode;
4480 pLastDirNode = pDirNode;
4483 RtlInitUnicodeString( &uniShareName,
4486 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4489 if( pObjectInfoCB == NULL)
4492 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4495 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4496 AFS_TRACE_LEVEL_VERBOSE,
4497 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4500 pObjectInfoCB->ObjectReferenceCount = 1;
4502 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4504 ulEntryLength = sizeof( AFSDirectoryCB) +
4505 uniShareName.Length;
4507 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4511 if( pDirNode == NULL)
4514 AFSDeleteObjectInfo( pObjectInfoCB);
4516 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4519 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4520 sizeof( AFSNonPagedDirectoryCB),
4521 AFS_DIR_ENTRY_NP_TAG);
4523 if( pNonPagedDirEntry == NULL)
4526 ExFreePool( pDirNode);
4528 AFSDeleteObjectInfo( pObjectInfoCB);
4530 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4533 RtlZeroMemory( pDirNode,
4536 RtlZeroMemory( pNonPagedDirEntry,
4537 sizeof( AFSNonPagedDirectoryCB));
4539 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4541 pDirNode->NonPaged = pNonPagedDirEntry;
4543 pDirNode->ObjectInformation = pObjectInfoCB;
4549 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4551 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4553 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4555 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4557 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4558 uniShareName.Buffer,
4559 pDirNode->NameInformation.FileName.Length);
4561 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4564 pLastDirNode->ListEntry.fLink = pDirNode;
4566 pDirNode->ListEntry.bLink = pLastDirNode;
4570 if( !NT_SUCCESS( ntStatus))
4573 if( AFSSpecialShareNames != NULL)
4576 pDirNode = AFSSpecialShareNames;
4578 while( pDirNode != NULL)
4581 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4583 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4585 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4587 ExFreePool( pDirNode->NonPaged);
4589 ExFreePool( pDirNode);
4591 pDirNode = pLastDirNode;
4594 AFSSpecialShareNames = NULL;
4603 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4604 IN UNICODE_STRING *SecondaryName)
4607 AFSDirectoryCB *pDirectoryCB = NULL;
4608 ULONGLONG ullHash = 0;
4609 UNICODE_STRING uniFullShareName;
4615 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4616 AFS_TRACE_LEVEL_VERBOSE_2,
4617 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4621 uniFullShareName = *ShareName;
4624 // Generate our hash value
4627 ullHash = AFSGenerateCRC( &uniFullShareName,
4631 // Loop through our special share names to see if this is one of them
4634 pDirectoryCB = AFSSpecialShareNames;
4636 while( pDirectoryCB != NULL)
4639 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4645 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4649 return pDirectoryCB;
4653 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4657 // Block on the queue flush event
4660 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4670 AFSWaitOnQueuedReleases()
4673 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4676 // Block on the queue flush event
4679 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4689 AFSIsEqualFID( IN AFSFileID *FileId1,
4690 IN AFSFileID *FileId2)
4693 BOOLEAN bIsEqual = FALSE;
4695 if( FileId1->Hash == FileId2->Hash &&
4696 FileId1->Unique == FileId2->Unique &&
4697 FileId1->Vnode == FileId2->Vnode &&
4698 FileId1->Volume == FileId2->Volume &&
4699 FileId1->Cell == FileId2->Cell)
4709 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4712 NTSTATUS ntStatus = STATUS_SUCCESS;
4713 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4718 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4721 // Reset the directory list information
4724 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4726 while( pCurrentDirEntry != NULL)
4729 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4731 if( pCurrentDirEntry->DirOpenReferenceCount <= 0)
4734 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4735 AFS_TRACE_LEVEL_VERBOSE,
4736 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4738 &pCurrentDirEntry->NameInformation.FileName);
4740 AFSDeleteDirEntry( ObjectInfoCB,
4746 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4747 AFS_TRACE_LEVEL_VERBOSE,
4748 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4750 &pCurrentDirEntry->NameInformation.FileName);
4752 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4754 AFSRemoveNameEntry( ObjectInfoCB,
4758 pCurrentDirEntry = pNextDirEntry;
4761 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4763 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4765 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4767 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4769 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4771 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4773 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4774 AFS_TRACE_LEVEL_VERBOSE,
4775 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4776 ObjectInfoCB->FileId.Cell,
4777 ObjectInfoCB->FileId.Volume,
4778 ObjectInfoCB->FileId.Vnode,
4779 ObjectInfoCB->FileId.Unique);
4786 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4789 NTSTATUS ntStatus = STATUS_SUCCESS;
4790 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4791 UNICODE_STRING uniFullName;
4796 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4797 AFS_TRACE_LEVEL_VERBOSE,
4798 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4799 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4800 PsGetCurrentThread());
4802 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4805 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4808 try_return( ntStatus);
4812 // Initialize the root information
4815 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4818 // Enumerate the shares in the volume
4821 ntStatus = AFSEnumerateDirectory( AuthGroup,
4822 &AFSGlobalRoot->ObjectInformation,
4825 if( !NT_SUCCESS( ntStatus))
4828 try_return( ntStatus);
4831 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4834 // Indicate the node is initialized
4837 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4839 uniFullName.MaximumLength = PAGE_SIZE;
4840 uniFullName.Length = 0;
4842 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4843 uniFullName.MaximumLength,
4844 AFS_GENERIC_MEMORY_12_TAG);
4846 if( uniFullName.Buffer == NULL)
4850 // Reset the directory content
4853 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4855 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4857 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4861 // Populate our list of entries in the NP enumeration list
4864 while( pDirGlobalDirNode != NULL)
4867 uniFullName.Buffer[ 0] = L'\\';
4868 uniFullName.Buffer[ 1] = L'\\';
4870 uniFullName.Length = 2 * sizeof( WCHAR);
4872 RtlCopyMemory( &uniFullName.Buffer[ 2],
4873 AFSServerName.Buffer,
4874 AFSServerName.Length);
4876 uniFullName.Length += AFSServerName.Length;
4878 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4880 uniFullName.Length += sizeof( WCHAR);
4882 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4883 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4884 pDirGlobalDirNode->NameInformation.FileName.Length);
4886 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4888 AFSAddConnectionEx( &uniFullName,
4889 RESOURCEDISPLAYTYPE_SHARE,
4892 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4895 AFSExFreePoolWithTag( uniFullName.Buffer, 0);
4899 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4906 AFSIsRelativeName( IN UNICODE_STRING *Name)
4909 BOOLEAN bIsRelative = FALSE;
4911 if( Name->Length > 0 &&
4912 Name->Buffer[ 0] != L'\\')
4922 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
4924 UNICODE_STRING uniTempName;
4925 BOOLEAN bIsAbsolute = FALSE;
4928 // An absolute AFS path must begin with \afs\... or equivalent
4931 if ( Name->Length == 0 ||
4932 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
4933 Name->Buffer[ 0] != L'\\' ||
4934 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
4940 uniTempName.Length = AFSMountRootName.Length;
4941 uniTempName.MaximumLength = AFSMountRootName.Length;
4943 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4944 uniTempName.MaximumLength,
4945 AFS_NAME_BUFFER_TWO_TAG);
4947 if( uniTempName.Buffer == NULL)
4953 RtlCopyMemory( uniTempName.Buffer,
4955 AFSMountRootName.Length);
4957 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
4961 AFSExFreePoolWithTag( uniTempName.Buffer,
4962 AFS_NAME_BUFFER_TWO_TAG);
4969 AFSUpdateName( IN UNICODE_STRING *Name)
4974 while( usIndex < Name->Length/sizeof( WCHAR))
4977 if( Name->Buffer[ usIndex] == L'/')
4980 Name->Buffer[ usIndex] = L'\\';
4990 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4991 IN OUT ULONG *Flags,
4992 IN WCHAR *NameBuffer,
4993 IN USHORT NameLength)
4996 NTSTATUS ntStatus = STATUS_SUCCESS;
4997 WCHAR *pTmpBuffer = NULL;
5003 // If we have enough space then just move in the name otherwise
5004 // allocate a new buffer
5007 if( TargetName->Length < NameLength)
5010 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5012 AFS_NAME_BUFFER_FIVE_TAG);
5014 if( pTmpBuffer == NULL)
5017 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5020 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5023 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5026 TargetName->MaximumLength = NameLength;
5028 TargetName->Buffer = pTmpBuffer;
5030 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5033 TargetName->Length = NameLength;
5035 RtlCopyMemory( TargetName->Buffer,
5037 TargetName->Length);
5040 // Update the name in the buffer
5043 AFSUpdateName( TargetName);
5054 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
5055 IN ULONG InitialElementCount)
5058 AFSNameArrayHdr *pNameArray = NULL;
5059 AFSNameArrayCB *pCurrentElement = NULL;
5060 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5066 if( InitialElementCount == 0)
5069 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
5072 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
5073 sizeof( AFSNameArrayHdr) +
5074 (InitialElementCount * sizeof( AFSNameArrayCB)),
5075 AFS_NAME_ARRAY_TAG);
5077 if( pNameArray == NULL)
5080 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5081 AFS_TRACE_LEVEL_ERROR,
5082 "AFSInitNameArray Failed to allocate name array\n");
5084 try_return( pNameArray);
5087 RtlZeroMemory( pNameArray,
5088 sizeof( AFSNameArrayHdr) +
5089 (InitialElementCount * sizeof( AFSNameArrayCB)));
5091 pNameArray->MaxElementCount = InitialElementCount;
5093 if( DirectoryCB != NULL)
5096 pCurrentElement = &pNameArray->ElementArray[ 0];
5098 pNameArray->CurrentEntry = pCurrentElement;
5100 pNameArray->Count = 1;
5102 pNameArray->LinkCount = 0;
5104 lCount = InterlockedIncrement( &DirectoryCB->DirOpenReferenceCount);
5106 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5107 AFS_TRACE_LEVEL_VERBOSE,
5108 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
5109 &DirectoryCB->NameInformation.FileName,
5113 pCurrentElement->DirectoryCB = DirectoryCB;
5115 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5117 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5119 if( pCurrentElement->FileId.Vnode == 1)
5122 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5125 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5126 AFS_TRACE_LEVEL_VERBOSE,
5127 "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5129 pCurrentElement->DirectoryCB,
5130 pCurrentElement->FileId.Cell,
5131 pCurrentElement->FileId.Volume,
5132 pCurrentElement->FileId.Vnode,
5133 pCurrentElement->FileId.Unique,
5134 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5135 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5147 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
5148 IN UNICODE_STRING *Path,
5149 IN AFSDirectoryCB *DirectoryCB)
5152 NTSTATUS ntStatus = STATUS_SUCCESS;
5153 AFSNameArrayCB *pCurrentElement = NULL;
5154 UNICODE_STRING uniComponentName, uniRemainingPath;
5155 AFSObjectInfoCB *pCurrentObject = NULL;
5156 ULONG ulTotalCount = 0;
5158 USHORT usLength = 0;
5164 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5165 AFS_TRACE_LEVEL_VERBOSE,
5166 "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5170 DirectoryCB->ObjectInformation->FileId.Cell,
5171 DirectoryCB->ObjectInformation->FileId.Volume,
5172 DirectoryCB->ObjectInformation->FileId.Vnode,
5173 DirectoryCB->ObjectInformation->FileId.Unique,
5174 &DirectoryCB->NameInformation.FileName,
5175 DirectoryCB->ObjectInformation->FileType);
5178 // Init some info in the header
5181 pCurrentElement = &NameArray->ElementArray[ 0];
5183 NameArray->CurrentEntry = pCurrentElement;
5186 // The first entry points at the root
5189 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
5191 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->DirOpenReferenceCount);
5193 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5194 AFS_TRACE_LEVEL_VERBOSE,
5195 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
5196 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5197 pCurrentElement->DirectoryCB,
5200 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
5202 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
5204 pCurrentElement->Flags = 0;
5206 if( pCurrentElement->FileId.Vnode == 1)
5209 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5212 NameArray->Count = 1;
5214 NameArray->LinkCount = 0;
5216 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5217 AFS_TRACE_LEVEL_VERBOSE,
5218 "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5220 pCurrentElement->DirectoryCB,
5221 pCurrentElement->FileId.Cell,
5222 pCurrentElement->FileId.Volume,
5223 pCurrentElement->FileId.Vnode,
5224 pCurrentElement->FileId.Unique,
5225 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5226 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5229 // If the root is the parent then we are done ...
5232 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
5234 try_return( ntStatus);
5246 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
5247 IN AFSNameArrayHdr *RelatedNameArray,
5248 IN AFSDirectoryCB *DirectoryCB)
5251 NTSTATUS ntStatus = STATUS_SUCCESS;
5252 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
5253 UNICODE_STRING uniComponentName, uniRemainingPath;
5254 AFSObjectInfoCB *pObjectInfo = NULL;
5255 ULONG ulTotalCount = 0;
5257 USHORT usLength = 0;
5263 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5264 AFS_TRACE_LEVEL_VERBOSE,
5265 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5269 DirectoryCB->ObjectInformation->FileId.Cell,
5270 DirectoryCB->ObjectInformation->FileId.Volume,
5271 DirectoryCB->ObjectInformation->FileId.Vnode,
5272 DirectoryCB->ObjectInformation->FileId.Unique,
5273 &DirectoryCB->NameInformation.FileName,
5274 DirectoryCB->ObjectInformation->FileType);
5277 // Init some info in the header
5280 pCurrentElement = &NameArray->ElementArray[ 0];
5282 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5284 NameArray->Count = 0;
5286 NameArray->LinkCount = RelatedNameArray->LinkCount;
5289 // Populate the name array with the data from the related array
5295 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5297 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5299 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5301 pCurrentElement->Flags = 0;
5303 if( pCurrentElement->FileId.Vnode == 1)
5306 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5309 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->DirOpenReferenceCount);
5311 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5312 AFS_TRACE_LEVEL_VERBOSE,
5313 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
5314 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5315 pCurrentElement->DirectoryCB,
5318 lCount = InterlockedIncrement( &NameArray->Count);
5320 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5321 AFS_TRACE_LEVEL_VERBOSE,
5322 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5325 pCurrentElement->DirectoryCB,
5326 pCurrentElement->FileId.Cell,
5327 pCurrentElement->FileId.Volume,
5328 pCurrentElement->FileId.Vnode,
5329 pCurrentElement->FileId.Unique,
5330 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5331 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5333 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5334 NameArray->Count == RelatedNameArray->Count)
5346 pCurrentRelatedElement++;
5349 NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
5356 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5359 NTSTATUS ntStatus = STATUS_SUCCESS;
5360 AFSNameArrayCB *pCurrentElement = NULL;
5361 LONG lCount, lElement;
5366 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5367 AFS_TRACE_LEVEL_VERBOSE,
5368 "AFSFreeNameArray [NA:%p]\n",
5371 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5374 pCurrentElement = &NameArray->ElementArray[ lElement];
5376 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->DirOpenReferenceCount);
5378 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5379 AFS_TRACE_LEVEL_VERBOSE,
5380 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
5381 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5382 pCurrentElement->DirectoryCB,
5385 ASSERT( lCount >= 0);
5388 AFSExFreePoolWithTag( NameArray, AFS_NAME_ARRAY_TAG);
5395 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5396 IN AFSDirectoryCB *DirectoryCB)
5399 NTSTATUS ntStatus = STATUS_SUCCESS;
5400 AFSNameArrayCB *pCurrentElement = NULL;
5406 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5407 AFS_TRACE_LEVEL_VERBOSE,
5408 "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5411 DirectoryCB->ObjectInformation->FileId.Cell,
5412 DirectoryCB->ObjectInformation->FileId.Volume,
5413 DirectoryCB->ObjectInformation->FileId.Vnode,
5414 DirectoryCB->ObjectInformation->FileId.Unique,
5415 &DirectoryCB->NameInformation.FileName,
5416 DirectoryCB->ObjectInformation->FileType);
5418 if( NameArray->Count == NameArray->MaxElementCount)
5421 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5422 AFS_TRACE_LEVEL_ERROR,
5423 "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
5426 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5429 for ( lCount = 0; lCount < NameArray->Count; lCount++)
5432 if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
5433 &DirectoryCB->ObjectInformation->FileId) )
5436 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5437 AFS_TRACE_LEVEL_WARNING,
5438 "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
5441 STATUS_ACCESS_DENIED);
5443 try_return( ntStatus = STATUS_ACCESS_DENIED);
5447 if( NameArray->Count > 0)
5450 NameArray->CurrentEntry++;
5454 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5457 pCurrentElement = NameArray->CurrentEntry;
5459 lCount = InterlockedIncrement( &NameArray->Count);
5461 lCount = InterlockedIncrement( &DirectoryCB->DirOpenReferenceCount);
5463 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5464 AFS_TRACE_LEVEL_VERBOSE,
5465 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
5466 &DirectoryCB->NameInformation.FileName,
5470 ASSERT( lCount >= 2);
5472 pCurrentElement->DirectoryCB = DirectoryCB;
5474 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5476 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5478 pCurrentElement->Flags = 0;
5480 if( pCurrentElement->FileId.Vnode == 1)
5483 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5486 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5487 AFS_TRACE_LEVEL_VERBOSE,
5488 "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5490 NameArray->Count - 1,
5491 pCurrentElement->DirectoryCB,
5492 pCurrentElement->FileId.Cell,
5493 pCurrentElement->FileId.Volume,
5494 pCurrentElement->FileId.Vnode,
5495 pCurrentElement->FileId.Unique,
5496 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5497 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5508 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5511 AFSDirectoryCB *pDirectoryCB = NULL;
5512 AFSNameArrayCB *pCurrentElement = NULL;
5513 BOOLEAN bVolumeRoot = FALSE;
5519 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5520 AFS_TRACE_LEVEL_VERBOSE,
5521 "AFSBackupEntry [NA:%p]\n",
5524 if( NameArray->Count == 0)
5527 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5528 AFS_TRACE_LEVEL_ERROR,
5529 "AFSBackupEntry [NA:%p] No more entries\n",
5532 try_return( pCurrentElement);
5535 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->DirOpenReferenceCount);
5537 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5538 AFS_TRACE_LEVEL_VERBOSE,
5539 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5540 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5541 NameArray->CurrentEntry->DirectoryCB,
5544 ASSERT( lCount >= 0);
5546 NameArray->CurrentEntry->DirectoryCB = NULL;
5548 lCount = InterlockedDecrement( &NameArray->Count);
5552 NameArray->CurrentEntry = NULL;
5554 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5555 AFS_TRACE_LEVEL_ERROR,
5556 "AFSBackupEntry [NA:%p] No more entries\n",
5562 bVolumeRoot = BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5564 NameArray->CurrentEntry--;
5566 pCurrentElement = NameArray->CurrentEntry;
5568 pDirectoryCB = pCurrentElement->DirectoryCB;
5570 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5571 AFS_TRACE_LEVEL_VERBOSE,
5572 "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5574 NameArray->Count - 1,
5575 pCurrentElement->DirectoryCB,
5576 pCurrentElement->FileId.Cell,
5577 pCurrentElement->FileId.Volume,
5578 pCurrentElement->FileId.Vnode,
5579 pCurrentElement->FileId.Unique,
5580 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5581 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5584 // If the entry we are removing is a volume root,
5585 // we must remove the mount point entry as well.
5586 // If the NameArray was constructed by checking the
5587 // share name via the service, the name array can
5588 // contain two volume roots in sequence without a
5589 // mount point separating them.
5593 !BooleanFlagOn( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT))
5596 pDirectoryCB = AFSBackupEntry( NameArray);
5606 return pDirectoryCB;
5610 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5613 AFSDirectoryCB *pDirEntry = NULL;
5614 AFSNameArrayCB *pElement = NULL;
5619 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5620 AFS_TRACE_LEVEL_VERBOSE,
5621 "AFSGetParentEntry [NA:%p]\n",
5624 if( NameArray->Count == 0 ||
5625 NameArray->Count == 1)
5628 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5629 AFS_TRACE_LEVEL_ERROR,
5630 "AFSGetParentEntry [NA:%p] No more entries\n",
5633 try_return( pDirEntry = NULL);
5636 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5638 pDirEntry = pElement->DirectoryCB;
5640 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5641 AFS_TRACE_LEVEL_VERBOSE,
5642 "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5644 NameArray->Count - 2,
5645 pElement->DirectoryCB,
5646 pElement->FileId.Cell,
5647 pElement->FileId.Volume,
5648 pElement->FileId.Vnode,
5649 pElement->FileId.Unique,
5650 &pElement->DirectoryCB->NameInformation.FileName,
5651 pElement->DirectoryCB->ObjectInformation->FileType);
5662 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5663 IN AFSDirectoryCB *DirectoryCB)
5666 AFSNameArrayCB *pCurrentElement = NULL;
5667 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5668 LONG lCount, lElement;
5673 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5674 AFS_TRACE_LEVEL_VERBOSE,
5675 "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5678 DirectoryCB->ObjectInformation->FileId.Cell,
5679 DirectoryCB->ObjectInformation->FileId.Volume,
5680 DirectoryCB->ObjectInformation->FileId.Vnode,
5681 DirectoryCB->ObjectInformation->FileId.Unique,
5682 &DirectoryCB->NameInformation.FileName,
5683 DirectoryCB->ObjectInformation->FileType);
5685 // Dereference previous name array contents
5688 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5691 pCurrentElement = &NameArray->ElementArray[ lElement];
5693 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->DirOpenReferenceCount);
5695 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5696 AFS_TRACE_LEVEL_VERBOSE,
5697 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5698 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5699 pCurrentElement->DirectoryCB,
5702 ASSERT( lCount >= 0);
5705 RtlZeroMemory( NameArray,
5706 sizeof( AFSNameArrayHdr) +
5707 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5709 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5711 if( DirectoryCB != NULL)
5714 pCurrentElement = &NameArray->ElementArray[ 0];
5716 NameArray->CurrentEntry = pCurrentElement;
5718 NameArray->Count = 1;
5720 NameArray->LinkCount = 0;
5722 lCount = InterlockedIncrement( &DirectoryCB->DirOpenReferenceCount);
5724 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5725 AFS_TRACE_LEVEL_VERBOSE,
5726 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5727 &DirectoryCB->NameInformation.FileName,
5731 pCurrentElement->DirectoryCB = DirectoryCB;
5733 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5735 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5737 pCurrentElement->Flags = 0;
5739 if( pCurrentElement->FileId.Vnode == 1)
5742 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5745 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5746 AFS_TRACE_LEVEL_VERBOSE,
5747 "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5749 pCurrentElement->DirectoryCB,
5750 pCurrentElement->FileId.Cell,
5751 pCurrentElement->FileId.Volume,
5752 pCurrentElement->FileId.Vnode,
5753 pCurrentElement->FileId.Unique,
5754 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5755 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5763 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5766 AFSNameArrayCB *pCurrentElement = NULL;
5768 pCurrentElement = &NameArray->ElementArray[ 0];
5770 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5772 while( pCurrentElement->DirectoryCB != NULL)
5775 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5776 pCurrentElement->FileId.Cell,
5777 pCurrentElement->FileId.Volume,
5778 pCurrentElement->FileId.Vnode,
5779 pCurrentElement->FileId.Unique,
5780 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5785 AFSPrint("AFSDumpNameArray End\n\n");
5791 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5796 // Depending on the type of node, set the event
5799 switch( Fcb->Header.NodeTypeCode)
5802 case AFS_DIRECTORY_FCB:
5807 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5817 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5823 // Depending on the type of node, set the event
5826 switch( Fcb->Header.NodeTypeCode)
5829 case AFS_DIRECTORY_FCB:
5834 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5836 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5846 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5849 BOOLEAN bIsInProcess = FALSE;
5854 if( ObjectInfo->Fcb == NULL)
5857 try_return( bIsInProcess);
5860 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5863 case AFS_DIRECTORY_FCB:
5868 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5871 bIsInProcess = TRUE;
5883 return bIsInProcess;
5887 AFSVerifyVolume( IN ULONGLONG ProcessId,
5888 IN AFSVolumeCB *VolumeCB)
5891 NTSTATUS ntStatus = STATUS_SUCCESS;
5898 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5901 NTSTATUS ntStatus = STATUS_SUCCESS;
5902 AFSObjectInfoCB *pObjectInfoCB = NULL;
5903 AFSDirectoryCB *pDirNode = NULL;
5904 ULONG ulEntryLength = 0;
5905 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5911 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5914 if( pObjectInfoCB == NULL)
5917 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5920 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5921 AFS_TRACE_LEVEL_VERBOSE,
5922 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5925 pObjectInfoCB->ObjectReferenceCount = 1;
5927 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5929 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5931 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5933 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5937 if( pDirNode == NULL)
5940 AFSDeleteObjectInfo( pObjectInfoCB);
5942 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5945 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5946 sizeof( AFSNonPagedDirectoryCB),
5947 AFS_DIR_ENTRY_NP_TAG);
5949 if( pNonPagedDirEntry == NULL)
5952 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5955 RtlZeroMemory( pDirNode,
5958 RtlZeroMemory( pNonPagedDirEntry,
5959 sizeof( AFSNonPagedDirectoryCB));
5961 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5963 pDirNode->NonPaged = pNonPagedDirEntry;
5965 pDirNode->ObjectInformation = pObjectInfoCB;
5967 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5973 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5975 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5977 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5979 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5981 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5982 AFSPIOCtlName.Buffer,
5983 pDirNode->NameInformation.FileName.Length);
5985 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5988 if ( InterlockedCompareExchangePointer( (PVOID *)&ObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5991 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5992 AFS_TRACE_LEVEL_WARNING,
5993 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %08lX pFcb %08lX\n",
5994 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5998 // Increment the open reference and handle on the node
6001 lCount = AFSObjectInfoIncrement( pDirNode->ObjectInformation);
6003 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
6004 AFS_TRACE_LEVEL_VERBOSE,
6005 "AFSInitPIOCtlDirectoryCB Increment count on Object %08lX Cnt %d\n",
6006 pDirNode->ObjectInformation,
6009 try_return( ntStatus = STATUS_REPARSE);
6014 if ( ntStatus != STATUS_SUCCESS)
6017 if ( pDirNode != NULL)
6020 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
6023 if( pNonPagedDirEntry != NULL)
6026 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
6028 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
6031 if ( pObjectInfoCB != NULL)
6034 AFSDeleteObjectInfo( pObjectInfoCB);
6043 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
6044 IN AFSDirectoryCB *DirectoryCB,
6045 IN UNICODE_STRING *ParentPathName,
6046 IN AFSNameArrayHdr *RelatedNameArray,
6048 OUT AFSFileInfoCB *FileInfo)
6051 NTSTATUS ntStatus = STATUS_SUCCESS;
6052 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6053 UNICODE_STRING uniFullPathName;
6054 AFSNameArrayHdr *pNameArray = NULL;
6055 AFSVolumeCB *pVolumeCB = NULL;
6056 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6057 WCHAR *pwchBuffer = NULL;
6058 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6059 ULONG ulNameDifference = 0;
6066 // Retrieve a target name for the entry
6069 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6072 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6075 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6077 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6082 if( !NT_SUCCESS( ntStatus) ||
6083 pDirEntry->TargetNameLength == 0)
6086 if( pDirEntry != NULL)
6089 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6092 try_return( ntStatus);
6095 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6098 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6102 // Update the target name
6105 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6106 &DirectoryCB->Flags,
6107 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6108 (USHORT)pDirEntry->TargetNameLength);
6110 if( !NT_SUCCESS( ntStatus))
6113 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6115 try_return( ntStatus);
6119 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6123 // Need to pass the full path in for parsing.
6126 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
6129 uniFullPathName.Length = 0;
6130 uniFullPathName.MaximumLength = ParentPathName->Length +
6132 DirectoryCB->NameInformation.TargetName.Length;
6134 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6135 uniFullPathName.MaximumLength,
6136 AFS_NAME_BUFFER_SIX_TAG);
6138 if( uniFullPathName.Buffer == NULL)
6141 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6143 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6146 pwchBuffer = uniFullPathName.Buffer;
6148 RtlZeroMemory( uniFullPathName.Buffer,
6149 uniFullPathName.MaximumLength);
6151 RtlCopyMemory( uniFullPathName.Buffer,
6152 ParentPathName->Buffer,
6153 ParentPathName->Length);
6155 uniFullPathName.Length = ParentPathName->Length;
6157 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
6158 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
6161 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
6163 uniFullPathName.Length += sizeof( WCHAR);
6166 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
6167 DirectoryCB->NameInformation.TargetName.Buffer,
6168 DirectoryCB->NameInformation.TargetName.Length);
6170 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
6172 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
6173 uniParsedName.MaximumLength = uniParsedName.Length;
6175 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
6177 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6180 // We populate up to the current parent
6183 if( RelatedNameArray != NULL)
6186 pNameArray = AFSInitNameArray( NULL,
6187 RelatedNameArray->MaxElementCount);
6189 if( pNameArray == NULL)
6192 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6195 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
6202 pNameArray = AFSInitNameArray( NULL,
6205 if( pNameArray == NULL)
6208 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6211 ntStatus = AFSPopulateNameArray( pNameArray,
6216 if( !NT_SUCCESS( ntStatus))
6219 try_return( ntStatus);
6222 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
6224 pParentDirEntry = ParentDirectoryCB;
6229 uniFullPathName.Length = 0;
6230 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6232 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6233 uniFullPathName.MaximumLength,
6234 AFS_NAME_BUFFER_SEVEN_TAG);
6236 if( uniFullPathName.Buffer == NULL)
6239 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6241 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6244 pwchBuffer = uniFullPathName.Buffer;
6246 RtlZeroMemory( uniFullPathName.Buffer,
6247 uniFullPathName.MaximumLength);
6249 RtlCopyMemory( uniFullPathName.Buffer,
6250 DirectoryCB->NameInformation.TargetName.Buffer,
6251 DirectoryCB->NameInformation.TargetName.Length);
6253 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6256 // This name should begin with the \afs server so parse it off and check it
6259 FsRtlDissectName( uniFullPathName,
6263 if( RtlCompareUnicodeString( &uniComponentName,
6268 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6270 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6271 AFS_TRACE_LEVEL_ERROR,
6272 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
6275 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
6278 uniFullPathName = uniRemainingPath;
6280 uniParsedName = uniFullPathName;
6282 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6284 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6290 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6293 if( pNameArray == NULL)
6296 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6299 pVolumeCB = AFSGlobalRoot;
6301 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6305 // Increment the ref count on the volume and dir entry for correct processing below
6308 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6310 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6311 AFS_TRACE_LEVEL_VERBOSE,
6312 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
6316 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6318 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6319 AFS_TRACE_LEVEL_VERBOSE,
6320 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6321 &pParentDirEntry->NameInformation.FileName,
6326 ntStatus = AFSLocateNameEntry( NULL,
6331 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
6337 if( !NT_SUCCESS( ntStatus))
6341 // The volume lock was released on failure above
6342 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6345 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6348 if( pVolumeCB != NULL)
6351 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6353 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6354 AFS_TRACE_LEVEL_VERBOSE,
6355 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
6360 if( pDirectoryEntry != NULL)
6363 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6365 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6366 AFS_TRACE_LEVEL_VERBOSE,
6367 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6368 &pDirectoryEntry->NameInformation.FileName,
6373 ASSERT( lCount >= 0);
6378 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6380 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6381 AFS_TRACE_LEVEL_VERBOSE,
6382 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6383 &pParentDirEntry->NameInformation.FileName,
6388 ASSERT( lCount >= 0);
6394 try_return( ntStatus);
6398 // Store off the information
6401 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6404 // Check for the mount point being returned
6407 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
6410 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6412 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
6413 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6416 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6419 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6424 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6428 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6430 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6432 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6434 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6436 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6438 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6441 // Remove the reference made above
6444 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6446 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6447 AFS_TRACE_LEVEL_VERBOSE,
6448 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
6449 &pDirectoryEntry->NameInformation.FileName,
6454 ASSERT( lCount >= 0);
6458 if( pDirEntry != NULL)
6461 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6464 if( pVolumeCB != NULL)
6467 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6469 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6470 AFS_TRACE_LEVEL_VERBOSE,
6471 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
6476 if( pNameArray != NULL)
6479 AFSFreeNameArray( pNameArray);
6482 if( pwchBuffer != NULL)
6486 // Always free the buffer that we allocated as AFSLocateNameEntry
6487 // will not free it. If uniFullPathName.Buffer was allocated by
6488 // AFSLocateNameEntry, then we must free that as well.
6489 // Check that the uniFullPathName.Buffer in the string is not the same
6490 // offset by the length of the server name
6493 if( uniFullPathName.Length > 0 &&
6494 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6497 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6500 AFSExFreePoolWithTag( pwchBuffer, 0);
6508 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6509 IN ULONGLONG HashIndex)
6512 NTSTATUS ntStatus = STATUS_SUCCESS;
6513 AFSObjectInfoCB *pObjectInfo = NULL;
6519 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6520 sizeof( AFSObjectInfoCB),
6521 AFS_OBJECT_INFO_TAG);
6523 if( pObjectInfo == NULL)
6526 try_return( pObjectInfo);
6529 RtlZeroMemory( pObjectInfo,
6530 sizeof( AFSObjectInfoCB));
6532 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6533 sizeof( AFSNonPagedObjectInfoCB),
6534 AFS_NP_OBJECT_INFO_TAG);
6536 if( pObjectInfo->NonPagedInfo == NULL)
6539 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6541 try_return( pObjectInfo = NULL);
6544 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6546 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6548 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6550 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6552 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6554 if( ParentObjectInfo != NULL)
6556 lCount = AFSObjectInfoIncrement( ParentObjectInfo);
6560 // Initialize the access time
6563 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6569 // Insert the entry into the object tree and list
6572 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6574 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6577 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6582 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6583 &pObjectInfo->TreeEntry);
6585 ASSERT( NT_SUCCESS( ntStatus));
6589 // And the object list in the volume
6592 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6595 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6600 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6602 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6605 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6608 // Indicate the object is in the hash tree and linked list in the volume
6611 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6623 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo)
6628 if ( ObjectInfo->ObjectReferenceCount == 0)
6631 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6634 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6639 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6642 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6647 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6649 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6654 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6660 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo)
6665 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6668 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6673 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6675 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6677 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6680 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6683 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6691 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6694 BOOLEAN bAcquiredTreeLock = FALSE;
6697 if ( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_ROOT_VOLUME))
6701 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6702 // embedded in the VolumeCB.
6710 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6713 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6715 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6718 bAcquiredTreeLock = TRUE;
6722 // Remove it from the tree and list if it was inserted
6725 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6728 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6729 &ObjectInfo->TreeEntry);
6732 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6735 if( ObjectInfo->ListEntry.fLink == NULL)
6738 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6740 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6743 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6749 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6752 if( ObjectInfo->ListEntry.bLink == NULL)
6755 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6757 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6760 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6766 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6770 if( ObjectInfo->ParentObjectInformation != NULL)
6773 lCount = AFSObjectInfoDecrement( ObjectInfo->ParentObjectInformation);
6776 if( bAcquiredTreeLock)
6779 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6783 // Release the fid in the service
6786 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6789 AFSReleaseFid( &ObjectInfo->FileId);
6792 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6794 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6796 AFSExFreePoolWithTag( ObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6798 AFSExFreePoolWithTag( ObjectInfo, AFS_OBJECT_INFO_TAG);
6804 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6805 OUT AFSDirectoryCB **TargetDirEntry)
6808 NTSTATUS ntStatus = STATUS_SUCCESS;
6809 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6810 UNICODE_STRING uniFullPathName;
6811 AFSNameArrayHdr *pNameArray = NULL;
6812 AFSVolumeCB *pVolumeCB = NULL;
6813 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6814 WCHAR *pwchBuffer = NULL;
6815 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6816 ULONG ulNameDifference = 0;
6823 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6824 DirectoryCB->ObjectInformation,
6828 if( !NT_SUCCESS( ntStatus))
6830 try_return( ntStatus);
6834 // Retrieve a target name for the entry
6837 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6840 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6843 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6845 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6850 if( !NT_SUCCESS( ntStatus) ||
6851 pDirEntry->TargetNameLength == 0)
6854 if( pDirEntry != NULL)
6857 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6860 try_return( ntStatus);
6863 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6866 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6870 // Update the target name
6873 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6874 &DirectoryCB->Flags,
6875 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6876 (USHORT)pDirEntry->TargetNameLength);
6878 if( !NT_SUCCESS( ntStatus))
6881 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6883 try_return( ntStatus);
6887 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6891 // Need to pass the full path in for parsing.
6894 uniFullPathName.Length = 0;
6895 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6897 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6898 uniFullPathName.MaximumLength,
6899 AFS_NAME_BUFFER_EIGHT_TAG);
6901 if( uniFullPathName.Buffer == NULL)
6904 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6906 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6909 pwchBuffer = uniFullPathName.Buffer;
6911 RtlZeroMemory( uniFullPathName.Buffer,
6912 uniFullPathName.MaximumLength);
6914 RtlCopyMemory( uniFullPathName.Buffer,
6915 DirectoryCB->NameInformation.TargetName.Buffer,
6916 DirectoryCB->NameInformation.TargetName.Length);
6918 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6921 // This name should begin with the \afs server so parse it off and chech it
6924 FsRtlDissectName( uniFullPathName,
6928 if( RtlCompareUnicodeString( &uniComponentName,
6934 // Try evaluating the full path
6937 uniFullPathName.Buffer = pwchBuffer;
6939 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6941 uniFullPathName.MaximumLength = uniFullPathName.Length;
6946 uniFullPathName = uniRemainingPath;
6949 uniParsedName = uniFullPathName;
6951 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6953 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6959 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6962 if( pNameArray == NULL)
6965 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6968 pVolumeCB = AFSGlobalRoot;
6970 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6972 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6974 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6975 AFS_TRACE_LEVEL_VERBOSE,
6976 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6980 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6982 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6983 AFS_TRACE_LEVEL_VERBOSE,
6984 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6985 &pParentDirEntry->NameInformation.FileName,
6990 ntStatus = AFSLocateNameEntry( NULL,
7001 if( !NT_SUCCESS( ntStatus))
7005 // The volume lock was released on failure above
7006 // Except for STATUS_OBJECT_NAME_NOT_FOUND
7009 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
7012 if( pVolumeCB != NULL)
7015 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7017 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7018 AFS_TRACE_LEVEL_VERBOSE,
7019 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
7024 if( pDirectoryEntry != NULL)
7027 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
7029 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7030 AFS_TRACE_LEVEL_VERBOSE,
7031 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7032 &pDirectoryEntry->NameInformation.FileName,
7037 ASSERT( lCount >= 0);
7042 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
7044 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7045 AFS_TRACE_LEVEL_VERBOSE,
7046 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7047 &pParentDirEntry->NameInformation.FileName,
7052 ASSERT( lCount >= 0);
7058 try_return( ntStatus);
7062 // Pass back the target dir entry for this request
7065 *TargetDirEntry = pDirectoryEntry;
7069 if( pDirEntry != NULL)
7072 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
7075 if( pVolumeCB != NULL)
7078 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7080 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7081 AFS_TRACE_LEVEL_VERBOSE,
7082 "AFSEvaluateRootEntry Decrement2 count on volume %08lX Cnt %d\n",
7087 if( pNameArray != NULL)
7090 AFSFreeNameArray( pNameArray);
7093 if( pwchBuffer != NULL)
7097 // Always free the buffer that we allocated as AFSLocateNameEntry
7098 // will not free it. If uniFullPathName.Buffer was allocated by
7099 // AFSLocateNameEntry, then we must free that as well.
7100 // Check that the uniFullPathName.Buffer in the string is not the same
7101 // offset by the length of the server name
7104 if( uniFullPathName.Length > 0 &&
7105 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
7108 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
7111 AFSExFreePoolWithTag( pwchBuffer, 0);
7119 AFSCleanupFcb( IN AFSFcb *Fcb,
7120 IN BOOLEAN ForceFlush)
7123 NTSTATUS ntStatus = STATUS_SUCCESS;
7124 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
7125 LARGE_INTEGER liTime;
7126 IO_STATUS_BLOCK stIoStatus;
7131 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7133 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7135 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
7138 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
7139 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7142 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7143 AFS_TRACE_LEVEL_VERBOSE,
7144 "AFSCleanupEntry Acquiring Fcb lock %08lX SHARED %08lX\n",
7145 &Fcb->NPFcb->Resource,
7146 PsGetCurrentThread());
7148 AFSAcquireShared( &Fcb->NPFcb->Resource,
7151 if( Fcb->OpenReferenceCount > 0)
7154 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7155 AFS_TRACE_LEVEL_VERBOSE,
7156 "AFSCleanupEntry Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
7157 &Fcb->NPFcb->SectionObjectResource,
7158 PsGetCurrentThread());
7160 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
7166 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7171 if( !NT_SUCCESS( stIoStatus.Status))
7174 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7175 AFS_TRACE_LEVEL_ERROR,
7176 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7177 Fcb->ObjectInformation->FileId.Cell,
7178 Fcb->ObjectInformation->FileId.Volume,
7179 Fcb->ObjectInformation->FileId.Vnode,
7180 Fcb->ObjectInformation->FileId.Unique,
7182 stIoStatus.Information);
7184 ntStatus = stIoStatus.Status;
7187 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7190 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7196 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7197 AFS_TRACE_LEVEL_WARNING,
7198 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
7199 Fcb->ObjectInformation->FileId.Cell,
7200 Fcb->ObjectInformation->FileId.Volume,
7201 Fcb->ObjectInformation->FileId.Vnode,
7202 Fcb->ObjectInformation->FileId.Unique);
7204 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7208 __except( EXCEPTION_EXECUTE_HANDLER)
7211 ntStatus = GetExceptionCode();
7215 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7216 Fcb->ObjectInformation->FileId.Cell,
7217 Fcb->ObjectInformation->FileId.Volume,
7218 Fcb->ObjectInformation->FileId.Vnode,
7219 Fcb->ObjectInformation->FileId.Unique,
7222 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7225 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7226 AFS_TRACE_LEVEL_VERBOSE,
7227 "AFSCleanupFcb Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
7228 &Fcb->NPFcb->SectionObjectResource,
7229 PsGetCurrentThread());
7231 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7234 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7235 AFS_TRACE_LEVEL_VERBOSE,
7236 "AFSCleanupEntry Releasing Fcb lock %08lX SHARED %08lX\n",
7237 &Fcb->NPFcb->Resource,
7238 PsGetCurrentThread());
7240 AFSReleaseResource( &Fcb->NPFcb->Resource);
7243 // Wait for any currently running flush or release requests to complete
7246 AFSWaitOnQueuedFlushes( Fcb);
7249 // Now perform another flush on the file
7252 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7256 AFSReleaseExtentsWithFlush( Fcb,
7262 if( Fcb->OpenReferenceCount == 0 ||
7263 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7264 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7267 AFSTearDownFcbExtents( Fcb,
7271 try_return( ntStatus);
7274 KeQueryTickCount( &liTime);
7277 // First up are there dirty extents in the cache to flush?
7280 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7281 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7285 // The file has been marked as invalid. Dump it
7288 AFSTearDownFcbExtents( Fcb,
7291 else if( ForceFlush ||
7292 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7293 Fcb->Specific.File.ExtentCount) &&
7294 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7295 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7297 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7299 Fcb->OpenReferenceCount == 0)
7302 AFSReleaseExtentsWithFlush( Fcb,
7309 // If there are extents and they haven't been used recently *and*
7310 // are not being used
7314 ( 0 != Fcb->Specific.File.ExtentCount &&
7315 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7316 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7317 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7320 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7321 AFS_TRACE_LEVEL_VERBOSE,
7322 "AFSCleanupFcb Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
7323 &Fcb->NPFcb->SectionObjectResource,
7324 PsGetCurrentThread());
7326 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7332 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7337 if( !NT_SUCCESS( stIoStatus.Status))
7340 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7341 AFS_TRACE_LEVEL_ERROR,
7342 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7343 Fcb->ObjectInformation->FileId.Cell,
7344 Fcb->ObjectInformation->FileId.Volume,
7345 Fcb->ObjectInformation->FileId.Vnode,
7346 Fcb->ObjectInformation->FileId.Unique,
7348 stIoStatus.Information);
7350 ntStatus = stIoStatus.Status;
7354 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7357 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7363 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7364 AFS_TRACE_LEVEL_WARNING,
7365 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7366 Fcb->ObjectInformation->FileId.Cell,
7367 Fcb->ObjectInformation->FileId.Volume,
7368 Fcb->ObjectInformation->FileId.Vnode,
7369 Fcb->ObjectInformation->FileId.Unique);
7371 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7375 __except( EXCEPTION_EXECUTE_HANDLER)
7378 ntStatus = GetExceptionCode();
7382 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7383 Fcb->ObjectInformation->FileId.Cell,
7384 Fcb->ObjectInformation->FileId.Volume,
7385 Fcb->ObjectInformation->FileId.Vnode,
7386 Fcb->ObjectInformation->FileId.Unique,
7390 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
7391 AFS_TRACE_LEVEL_VERBOSE,
7392 "AFSCleanupFcb Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
7393 &Fcb->NPFcb->SectionObjectResource,
7394 PsGetCurrentThread());
7396 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7398 if( Fcb->OpenReferenceCount <= 0)
7402 // Tear em down we'll not be needing them again
7405 AFSTearDownFcbExtents( Fcb,
7412 ntStatus = STATUS_RETRY;
7425 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7426 IN UNICODE_STRING *NewFileName)
7429 NTSTATUS ntStatus = STATUS_SUCCESS;
7430 WCHAR *pTmpBuffer = NULL;
7435 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7438 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7441 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7443 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7445 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7449 // OK, we need to allocate a new name buffer
7452 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7453 NewFileName->Length,
7454 AFS_NAME_BUFFER_NINE_TAG);
7456 if( pTmpBuffer == NULL)
7459 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7462 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7464 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7466 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7469 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7471 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7472 NewFileName->Buffer,
7473 NewFileName->Length);
7484 AFSReadCacheFile( IN void *ReadBuffer,
7485 IN LARGE_INTEGER *ReadOffset,
7486 IN ULONG RequestedDataLength,
7487 IN OUT PULONG BytesRead)
7490 NTSTATUS ntStatus = STATUS_SUCCESS;
7493 PIO_STACK_LOCATION pIoStackLocation = NULL;
7494 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7495 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7496 FILE_OBJECT *pCacheFileObject = NULL;
7501 pCacheFileObject = AFSReferenceCacheFileObject();
7503 if( pCacheFileObject == NULL)
7505 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7508 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7511 // Initialize the event
7514 KeInitializeEvent( &kEvent,
7515 SynchronizationEvent,
7519 // Allocate an irp for this request. This could also come from a
7520 // private pool, for instance.
7523 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7529 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7533 // Build the IRP's main body
7536 pIrp->UserBuffer = ReadBuffer;
7538 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7539 pIrp->RequestorMode = KernelMode;
7540 pIrp->Flags |= IRP_READ_OPERATION;
7543 // Set up the I/O stack location.
7546 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7547 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7548 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7549 pIoStackLocation->FileObject = pCacheFileObject;
7550 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7552 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7555 // Set the completion routine.
7558 IoSetCompletionRoutine( pIrp,
7566 // Send it to the FSD
7569 ntStatus = IoCallDriver( pTargetDeviceObject,
7572 if( NT_SUCCESS( ntStatus))
7579 ntStatus = KeWaitForSingleObject( &kEvent,
7585 if( NT_SUCCESS( ntStatus))
7588 ntStatus = pIrp->IoStatus.Status;
7590 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7596 if( pCacheFileObject != NULL)
7598 AFSReleaseCacheFileObject( pCacheFileObject);
7604 if( pIrp->MdlAddress != NULL)
7607 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7610 MmUnlockPages( pIrp->MdlAddress);
7613 IoFreeMdl( pIrp->MdlAddress);
7616 pIrp->MdlAddress = NULL;
7630 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7635 KEVENT *pEvent = (KEVENT *)Context;
7641 return STATUS_MORE_PROCESSING_REQUIRED;
7645 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7648 BOOLEAN bIsEmpty = FALSE;
7649 AFSDirectoryCB *pDirEntry = NULL;
7654 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7659 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7662 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7664 while( pDirEntry != NULL)
7667 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7668 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7676 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7681 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7688 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7689 IN AFSDirectoryCB *DirEntry)
7692 NTSTATUS ntStatus = STATUS_SUCCESS;
7697 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7700 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7701 AFS_TRACE_LEVEL_VERBOSE,
7702 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7704 &DirEntry->NameInformation.FileName);
7706 try_return( ntStatus);
7709 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7712 // Remove the entry from the parent tree
7715 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7716 AFS_TRACE_LEVEL_VERBOSE,
7717 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7719 &DirEntry->NameInformation.FileName);
7721 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7724 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7725 AFS_TRACE_LEVEL_VERBOSE,
7726 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7728 &DirEntry->NameInformation.FileName);
7730 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7733 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7737 // From the short name tree
7740 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7741 AFS_TRACE_LEVEL_VERBOSE,
7742 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7744 &DirEntry->NameInformation.FileName);
7746 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7749 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7752 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7753 AFS_TRACE_LEVEL_VERBOSE,
7754 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7756 &DirEntry->NameInformation.FileName);
7758 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7760 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7771 AFSGetAuthenticationId()
7774 LARGE_INTEGER liAuthId = {0,0};
7775 NTSTATUS ntStatus = STATUS_SUCCESS;
7776 PACCESS_TOKEN hToken = NULL;
7777 PTOKEN_STATISTICS pTokenInfo = NULL;
7778 BOOLEAN bCopyOnOpen = FALSE;
7779 BOOLEAN bEffectiveOnly = FALSE;
7780 BOOLEAN bPrimaryToken = FALSE;
7781 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7786 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7789 &stImpersonationLevel);
7794 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7799 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7800 AFS_TRACE_LEVEL_ERROR,
7801 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7803 try_return( ntStatus);
7806 bPrimaryToken = TRUE;
7809 ntStatus = SeQueryInformationToken( hToken,
7811 (PVOID *)&pTokenInfo);
7813 if( !NT_SUCCESS( ntStatus))
7816 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7817 AFS_TRACE_LEVEL_ERROR,
7818 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7820 try_return( ntStatus);
7823 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7824 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7826 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7827 AFS_TRACE_LEVEL_VERBOSE,
7828 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7839 PsDereferenceImpersonationToken( hToken);
7844 PsDereferencePrimaryToken( hToken);
7848 if( pTokenInfo != NULL)
7851 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7859 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7863 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7865 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7868 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7870 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7873 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7875 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7878 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7880 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7883 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7885 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7892 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7895 BOOLEAN bIsValid = TRUE;
7897 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7899 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7901 while( pCurrentDirEntry != NULL)
7904 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7908 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7913 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7914 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7917 if( pDirEntry == NULL)
7924 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7927 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7930 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7932 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7934 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7943 AFSReferenceCacheFileObject()
7946 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7947 FILE_OBJECT *pCacheFileObject = NULL;
7949 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7952 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7954 if( pCacheFileObject != NULL)
7956 ObReferenceObject( pCacheFileObject);
7959 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7961 return pCacheFileObject;
7965 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7968 ASSERT( CacheFileObject != NULL);
7970 ObDereferenceObject( CacheFileObject);
7976 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7979 NTSTATUS ntStatus = STATUS_SUCCESS;
7980 AFSDeviceExt *pControlDevExt = NULL;
7981 ULONG ulTimeIncrement = 0;
7987 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7989 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7991 AFSServerName = LibraryInit->AFSServerName;
7993 AFSMountRootName = LibraryInit->AFSMountRootName;
7995 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7998 // Callbacks in the framework
8001 AFSProcessRequest = LibraryInit->AFSProcessRequest;
8003 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
8005 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
8007 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
8009 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
8011 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
8013 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
8015 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
8017 if( LibraryInit->AFSCacheBaseAddress != NULL)
8020 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
8022 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
8024 AFSLibCacheLength = LibraryInit->AFSCacheLength;
8028 // Initialize some flush parameters
8031 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
8033 ulTimeIncrement = KeQueryTimeIncrement();
8035 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
8036 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
8037 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
8038 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
8039 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
8042 // Initialize the global root entry
8045 ntStatus = AFSInitVolume( NULL,
8046 &LibraryInit->GlobalRootFid,
8049 if( !NT_SUCCESS( ntStatus))
8052 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8053 AFS_TRACE_LEVEL_ERROR,
8054 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
8057 try_return( ntStatus);
8060 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
8063 if( !NT_SUCCESS( ntStatus))
8066 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8067 AFS_TRACE_LEVEL_ERROR,
8068 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
8071 lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
8073 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8074 AFS_TRACE_LEVEL_VERBOSE,
8075 "AFSInitializeLibrary Increment count on volume %08lX Cnt %d\n",
8079 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8081 try_return( ntStatus);
8085 // Update the node type code to AFS_ROOT_ALL
8088 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
8090 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
8093 // Invalidate all known volumes since contact with the service and therefore
8094 // the file server was lost.
8097 AFSInvalidateAllVolumes();
8100 // Drop the locks acquired above
8103 AFSInitVolumeWorker( AFSGlobalRoot);
8105 lCount = InterlockedDecrement( &AFSGlobalRoot->VolumeReferenceCount);
8107 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8108 AFS_TRACE_LEVEL_VERBOSE,
8109 "AFSInitializeLibrary Decrement count on volume %08lX Cnt %d\n",
8113 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8115 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
8129 NTSTATUS ntStatus = STATUS_SUCCESS;
8130 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
8135 if( AFSGlobalDotDirEntry != NULL)
8138 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
8140 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
8142 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
8144 ExFreePool( AFSGlobalDotDirEntry);
8146 AFSGlobalDotDirEntry = NULL;
8149 if( AFSGlobalDotDotDirEntry != NULL)
8152 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
8154 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
8156 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
8158 ExFreePool( AFSGlobalDotDotDirEntry);
8160 AFSGlobalDotDotDirEntry = NULL;
8163 if( AFSSpecialShareNames != NULL)
8166 pDirNode = AFSSpecialShareNames;
8168 while( pDirNode != NULL)
8171 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
8173 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
8175 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
8177 ExFreePool( pDirNode->NonPaged);
8179 ExFreePool( pDirNode);
8181 pDirNode = pLastDirNode;
8184 AFSSpecialShareNames = NULL;
8192 AFSDefaultLogMsg( IN ULONG Subsystem,
8198 NTSTATUS ntStatus = STATUS_SUCCESS;
8200 char chDebugBuffer[ 256];
8205 va_start( va_args, Format);
8207 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8212 if( NT_SUCCESS( ntStatus))
8214 DbgPrint( chDebugBuffer);
8224 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8225 IN ULONG InputBufferLength,
8226 IN AFSStatusInfoCB *StatusInfo,
8227 OUT ULONG *ReturnLength)
8230 NTSTATUS ntStatus = STATUS_SUCCESS;
8231 AFSFcb *pFcb = NULL;
8232 AFSVolumeCB *pVolumeCB = NULL;
8233 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8234 AFSObjectInfoCB *pObjectInfo = NULL;
8235 ULONGLONG ullIndex = 0;
8236 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8237 AFSNameArrayHdr *pNameArray = NULL;
8238 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8245 // If we are given a FID then look up the entry by that, otherwise
8249 if( GetStatusInfo->FileID.Cell != 0 &&
8250 GetStatusInfo->FileID.Volume != 0 &&
8251 GetStatusInfo->FileID.Vnode != 0 &&
8252 GetStatusInfo->FileID.Unique != 0)
8255 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8258 // Locate the volume node
8261 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8263 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8265 (AFSBTreeEntry **)&pVolumeCB);
8267 if( pVolumeCB != NULL)
8270 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8272 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8273 AFS_TRACE_LEVEL_VERBOSE,
8274 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
8279 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8281 if( !NT_SUCCESS( ntStatus) ||
8284 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8287 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8290 pObjectInfo = &pVolumeCB->ObjectInformation;
8292 lCount = AFSObjectInfoIncrement( pObjectInfo);
8294 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8296 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8297 AFS_TRACE_LEVEL_VERBOSE,
8298 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
8305 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8308 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8310 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8311 AFS_TRACE_LEVEL_VERBOSE,
8312 "AFSGetObjectStatus Decrement2 count on volume %08lX Cnt %d\n",
8316 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8318 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8320 (AFSBTreeEntry **)&pObjectInfo);
8322 if( pObjectInfo != NULL)
8326 // Reference the node so it won't be torn down
8329 lCount = AFSObjectInfoIncrement( pObjectInfo);
8331 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8332 AFS_TRACE_LEVEL_VERBOSE,
8333 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
8338 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8340 if( !NT_SUCCESS( ntStatus) ||
8341 pObjectInfo == NULL)
8343 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8350 if( GetStatusInfo->FileNameLength == 0 ||
8351 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8353 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8356 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8357 uniFullPathName.MaximumLength = uniFullPathName.Length;
8359 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8362 // This name should begin with the \afs server so parse it off and check it
8365 FsRtlDissectName( uniFullPathName,
8369 if( RtlCompareUnicodeString( &uniComponentName,
8373 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8374 AFS_TRACE_LEVEL_ERROR,
8375 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8378 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8381 uniFullPathName = uniRemainingPath;
8383 uniParsedName = uniFullPathName;
8389 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8392 if( pNameArray == NULL)
8394 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8397 pVolumeCB = AFSGlobalRoot;
8399 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8402 // Increment the ref count on the volume and dir entry for correct processing below
8405 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8407 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8408 AFS_TRACE_LEVEL_VERBOSE,
8409 "AFSGetObjectStatus Increment2 count on volume %08lX Cnt %d\n",
8413 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8415 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8416 AFS_TRACE_LEVEL_VERBOSE,
8417 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8418 &pParentDirEntry->NameInformation.FileName,
8423 ntStatus = AFSLocateNameEntry( NULL,
8428 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8429 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8435 if( !NT_SUCCESS( ntStatus))
8439 // The volume lock was released on failure above
8440 // Except for STATUS_OBJECT_NAME_NOT_FOUND
8443 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
8446 if( pVolumeCB != NULL)
8449 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8451 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8452 AFS_TRACE_LEVEL_VERBOSE,
8453 "AFSGetObjectStatus Decrement3 count on volume %08lX Cnt %d\n",
8458 if( pDirectoryEntry != NULL)
8461 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8463 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8464 AFS_TRACE_LEVEL_VERBOSE,
8465 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8466 &pDirectoryEntry->NameInformation.FileName,
8471 ASSERT( lCount >= 0);
8476 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8478 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8479 AFS_TRACE_LEVEL_VERBOSE,
8480 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8481 &pParentDirEntry->NameInformation.FileName,
8486 ASSERT( lCount >= 0);
8492 try_return( ntStatus);
8496 // Remove the reference made above
8499 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8501 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8502 AFS_TRACE_LEVEL_VERBOSE,
8503 "AFSGetObjectStatus Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
8504 &pDirectoryEntry->NameInformation.FileName,
8509 ASSERT( lCount >= 0);
8511 pObjectInfo = pDirectoryEntry->ObjectInformation;
8513 lCount = AFSObjectInfoIncrement( pObjectInfo);
8515 if( pVolumeCB != NULL)
8518 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8520 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8521 AFS_TRACE_LEVEL_VERBOSE,
8522 "AFSGetObjectStatus Decrement4 count on volume %08lX Cnt %d\n",
8529 // At this point we have an object info block, return the information
8532 StatusInfo->FileId = pObjectInfo->FileId;
8534 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8536 StatusInfo->Expiration = pObjectInfo->Expiration;
8538 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8540 StatusInfo->FileType = pObjectInfo->FileType;
8542 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8544 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8546 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8548 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8550 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8552 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8554 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8556 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8558 StatusInfo->EaSize = pObjectInfo->EaSize;
8560 StatusInfo->Links = pObjectInfo->Links;
8563 // Return the information length
8566 *ReturnLength = sizeof( AFSStatusInfoCB);
8570 if( pObjectInfo != NULL)
8573 lCount = AFSObjectInfoDecrement( pObjectInfo);
8576 if( pNameArray != NULL)
8579 AFSFreeNameArray( pNameArray);
8587 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8588 IN UNICODE_STRING *ComponentName)
8591 NTSTATUS ntStatus = STATUS_SUCCESS;
8592 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8593 AFSDirectoryCB *pDirEntry = NULL;
8601 // Search for the entry in the parent
8604 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8605 AFS_TRACE_LEVEL_VERBOSE_2,
8606 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8609 ulCRC = AFSGenerateCRC( ComponentName,
8612 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8615 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8619 if( pDirEntry == NULL)
8623 // Missed so perform a case insensitive lookup
8626 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8627 AFS_TRACE_LEVEL_VERBOSE_2,
8628 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8631 ulCRC = AFSGenerateCRC( ComponentName,
8634 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8638 if( pDirEntry == NULL)
8642 // OK, if this component is a valid short name then try
8643 // a lookup in the short name tree
8646 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8647 RtlIsNameLegalDOS8Dot3( ComponentName,
8652 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8653 AFS_TRACE_LEVEL_VERBOSE_2,
8654 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8657 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8664 if( pDirEntry != NULL)
8666 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8668 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8669 AFS_TRACE_LEVEL_VERBOSE,
8670 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8671 &pDirEntry->NameInformation.FileName,
8676 ASSERT( lCount >= 0);
8679 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8681 if( pDirEntry == NULL)
8684 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8685 AFS_TRACE_LEVEL_VERBOSE_2,
8686 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
8689 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8693 // We have the symlink object but previously failed to process it so return access
8697 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8698 AFS_TRACE_LEVEL_VERBOSE_2,
8699 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8702 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8704 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8706 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8707 AFS_TRACE_LEVEL_VERBOSE,
8708 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8709 &pDirEntry->NameInformation.FileName,
8714 ASSERT( lCount >= 0);
8725 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8726 OUT UNICODE_STRING *ComponentName)
8729 NTSTATUS ntStatus = STATUS_SUCCESS;
8730 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8732 uniFullPathName = *FullPathName;
8737 FsRtlDissectName( uniFullPathName,
8741 if( uniRemainingPath.Length == 0)
8746 uniFullPathName = uniRemainingPath;
8749 if( uniComponentName.Length > 0)
8751 *ComponentName = uniComponentName;
8758 AFSDumpTraceFiles_Default()
8764 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8767 BOOLEAN bIsValidName = TRUE;
8773 while( usIndex < FileName->Length/sizeof( WCHAR))
8776 if( FileName->Buffer[ usIndex] == L':' ||
8777 FileName->Buffer[ usIndex] == L'*' ||
8778 FileName->Buffer[ usIndex] == L'?' ||
8779 FileName->Buffer[ usIndex] == L'"' ||
8780 FileName->Buffer[ usIndex] == L'<' ||
8781 FileName->Buffer[ usIndex] == L'>')
8783 bIsValidName = FALSE;
8791 return bIsValidName;
8795 AFSCreateDefaultSecurityDescriptor()
8798 NTSTATUS ntStatus = STATUS_SUCCESS;
8800 ULONG ulSACLSize = 0;
8801 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8802 ULONG ulACESize = 0;
8803 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8804 ULONG ulSDLength = 0;
8805 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8806 PSID pWorldSID = NULL;
8807 ULONG *pulSubAuthority = NULL;
8808 ULONG ulWorldSIDLEngth = 0;
8813 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8815 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8817 AFS_GENERIC_MEMORY_29_TAG);
8819 if( pWorldSID == NULL)
8821 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8822 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8825 RtlZeroMemory( pWorldSID,
8828 RtlInitializeSid( pWorldSID,
8829 &SeWorldSidAuthority,
8832 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8833 *pulSubAuthority = SECURITY_WORLD_RID;
8835 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8838 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8843 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8845 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8847 AFS_GENERIC_MEMORY_29_TAG);
8852 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8854 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8857 RtlZeroMemory( pACE,
8860 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8861 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8862 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8863 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8865 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8867 SeExports->SeLowMandatorySid);
8869 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8870 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8872 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8874 AFS_GENERIC_MEMORY_29_TAG);
8879 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8881 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8884 ntStatus = RtlCreateAcl( pSACL,
8888 if( !NT_SUCCESS( ntStatus))
8891 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8894 try_return( ntStatus);
8897 ntStatus = RtlAddAce( pSACL,
8901 pACE->Header.AceSize);
8903 if( !NT_SUCCESS( ntStatus))
8906 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8909 try_return( ntStatus);
8913 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8914 sizeof( SECURITY_DESCRIPTOR),
8915 AFS_GENERIC_MEMORY_27_TAG);
8917 if( pSecurityDescr == NULL)
8920 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8922 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8925 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8926 SECURITY_DESCRIPTOR_REVISION);
8928 if( !NT_SUCCESS( ntStatus))
8931 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8934 try_return( ntStatus);
8937 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8939 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8944 if( !NT_SUCCESS( ntStatus))
8947 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8950 try_return( ntStatus);
8955 // Add in the group and owner to the SD
8958 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8960 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8964 if( !NT_SUCCESS( ntStatus))
8967 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8970 try_return( ntStatus);
8974 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8978 if( !NT_SUCCESS( ntStatus))
8981 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8984 try_return( ntStatus);
8987 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8990 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8992 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8995 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8997 AFS_GENERIC_MEMORY_27_TAG);
8999 if( pRelativeSecurityDescr == NULL)
9002 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9004 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9007 ulSDLength = PAGE_SIZE;
9009 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
9010 pRelativeSecurityDescr,
9013 if( !NT_SUCCESS( ntStatus))
9016 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
9019 try_return( ntStatus);
9022 AFSDefaultSD = pRelativeSecurityDescr;
9026 if( !NT_SUCCESS( ntStatus))
9029 if( pRelativeSecurityDescr != NULL)
9031 ExFreePool( pRelativeSecurityDescr);
9035 if( pSecurityDescr != NULL)
9037 ExFreePool( pSecurityDescr);
9050 if( pWorldSID != NULL)
9052 ExFreePool( pWorldSID);
9060 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
9061 OUT UNICODE_STRING *ParentPath)
9066 *ParentPath = *FullFileName;
9069 // If the final character is a \, jump over it
9072 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
9074 ParentPath->Length -= sizeof( WCHAR);
9077 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
9079 ParentPath->Length -= sizeof( WCHAR);
9083 // And the separator
9086 ParentPath->Length -= sizeof( WCHAR);
9092 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
9093 IN AFSObjectInfoCB *ObjectInfo,
9094 IN BOOLEAN WriteAccess,
9095 OUT GUID *AuthGroup)
9098 NTSTATUS ntStatus = STATUS_SUCCESS;
9099 GUID stAuthGroup, stZeroAuthGroup;
9100 BOOLEAN bFoundAuthGroup = FALSE;
9101 AFSCcb *pCcb = NULL;
9107 RtlZeroMemory( &stAuthGroup,
9110 RtlZeroMemory( &stZeroAuthGroup,
9116 if( ObjectInfo != NULL &&
9117 ObjectInfo->Fcb != NULL)
9119 pFcb = ObjectInfo->Fcb;
9126 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
9129 pCcb = Fcb->CcbListHead;
9131 while( pCcb != NULL)
9135 pCcb->GrantedAccess & FILE_WRITE_DATA)
9137 RtlCopyMemory( &stAuthGroup,
9141 bFoundAuthGroup = TRUE;
9145 else if( pCcb->GrantedAccess & FILE_READ_DATA)
9148 // At least get the read-only access
9151 RtlCopyMemory( &stAuthGroup,
9155 bFoundAuthGroup = TRUE;
9158 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9161 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9164 if( !bFoundAuthGroup)
9167 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9168 (ULONGLONG)PsGetCurrentThreadId(),
9171 if( RtlCompareMemory( &stZeroAuthGroup,
9173 sizeof( GUID)) == sizeof( GUID))
9176 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9178 try_return( ntStatus = STATUS_ACCESS_DENIED);
9182 RtlCopyMemory( AuthGroup,
9195 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9196 IN ULONG InvalidateReason)
9199 NTSTATUS ntStatus = STATUS_SUCCESS;
9200 IO_STATUS_BLOCK stIoStatus;
9203 ULONG ulProcessCount = 0;
9209 switch( InvalidateReason)
9212 case AFS_INVALIDATE_DELETED:
9215 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9216 ObjectInfo->Fcb != NULL)
9219 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9222 ObjectInfo->Links = 0;
9224 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9226 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9231 // Clear out the extents
9232 // And get rid of them (note this involves waiting
9233 // for any writes or reads to the cache to complete)
9236 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9239 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9245 case AFS_INVALIDATE_DATA_VERSION:
9248 LARGE_INTEGER liCurrentOffset = {0,0};
9249 LARGE_INTEGER liFlushLength = {0,0};
9250 ULONG ulFlushLength = 0;
9251 BOOLEAN bLocked = FALSE;
9252 BOOLEAN bExtentsLocked = FALSE;
9253 BOOLEAN bCleanExtents = FALSE;
9255 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9256 ObjectInfo->Fcb != NULL)
9259 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9264 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9265 AFS_TRACE_LEVEL_VERBOSE,
9266 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %08lX SHARED %08lX\n",
9267 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9268 PsGetCurrentThread());
9270 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9273 bExtentsLocked = TRUE;
9276 // There are several possibilities here:
9278 // 0. If there are no extents or all of the extents are dirty, do nothing.
9280 // 1. There could be nothing dirty and an open reference count of zero
9281 // in which case we can just tear down all of the extents without
9282 // holding any resources.
9284 // 2. There could be nothing dirty and a non-zero open reference count
9285 // in which case we can issue a CcPurge against the entire file
9286 // while holding just the Fcb Resource.
9288 // 3. There can be dirty extents in which case we need to identify
9289 // the non-dirty ranges and then perform a CcPurge on just the
9290 // non-dirty ranges while holding just the Fcb Resource.
9293 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9296 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9299 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9301 bExtentsLocked = FALSE;
9303 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9306 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9310 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9316 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9317 AFS_TRACE_LEVEL_VERBOSE,
9318 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
9319 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9320 PsGetCurrentThread());
9322 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9325 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9332 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9333 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9339 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9340 AFS_TRACE_LEVEL_WARNING,
9341 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9342 ObjectInfo->FileId.Cell,
9343 ObjectInfo->FileId.Volume,
9344 ObjectInfo->FileId.Vnode,
9345 ObjectInfo->FileId.Unique);
9347 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9352 bCleanExtents = TRUE;
9355 __except( EXCEPTION_EXECUTE_HANDLER)
9358 ntStatus = GetExceptionCode();
9362 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9363 ObjectInfo->FileId.Cell,
9364 ObjectInfo->FileId.Volume,
9365 ObjectInfo->FileId.Vnode,
9366 ObjectInfo->FileId.Unique,
9369 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9372 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9373 AFS_TRACE_LEVEL_VERBOSE,
9374 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
9375 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9376 PsGetCurrentThread());
9378 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9384 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9386 bExtentsLocked = FALSE;
9388 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9389 AFS_TRACE_LEVEL_VERBOSE,
9390 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
9391 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9392 PsGetCurrentThread());
9394 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9397 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9402 // Must build a list of non-dirty ranges from the beginning of the file
9403 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9404 // ranges. In all but the most extreme random data write scenario there will
9405 // be significantly fewer.
9407 // For each range we need offset and size.
9410 AFSByteRange * ByteRangeList = NULL;
9411 ULONG ulByteRangeCount = 0;
9413 BOOLEAN bPurgeOnClose = FALSE;
9418 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9421 if ( ByteRangeList != NULL ||
9422 ulByteRangeCount == 0)
9425 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9432 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9434 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9435 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9436 &ByteRangeList[ulIndex].FileOffset,
9441 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9442 AFS_TRACE_LEVEL_WARNING,
9443 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9444 ObjectInfo->FileId.Cell,
9445 ObjectInfo->FileId.Volume,
9446 ObjectInfo->FileId.Vnode,
9447 ObjectInfo->FileId.Unique);
9449 bPurgeOnClose = TRUE;
9454 bCleanExtents = TRUE;
9457 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9459 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9461 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9468 // We couldn't allocate the memory to build the purge list
9469 // so just walk the extent list while holding the ExtentsList Resource.
9470 // This could deadlock but we do not have much choice.
9473 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9475 bExtentsLocked = TRUE;
9477 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9481 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9485 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9487 while( ulProcessCount < ulCount)
9489 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9491 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9493 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9494 &pEntry->FileOffset,
9499 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9500 AFS_TRACE_LEVEL_WARNING,
9501 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9502 ObjectInfo->FileId.Cell,
9503 ObjectInfo->FileId.Volume,
9504 ObjectInfo->FileId.Vnode,
9505 ObjectInfo->FileId.Unique);
9507 bPurgeOnClose = TRUE;
9512 bCleanExtents = TRUE;
9516 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9519 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9521 while( liFlushLength.QuadPart > 0)
9524 if( liFlushLength.QuadPart > 512 * 1024000)
9526 ulFlushLength = 512 * 1024000;
9530 ulFlushLength = liFlushLength.LowPart;
9533 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9539 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9540 AFS_TRACE_LEVEL_WARNING,
9541 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9542 ObjectInfo->FileId.Cell,
9543 ObjectInfo->FileId.Volume,
9544 ObjectInfo->FileId.Vnode,
9545 ObjectInfo->FileId.Unique);
9547 bPurgeOnClose = TRUE;
9552 bCleanExtents = TRUE;
9555 liFlushLength.QuadPart -= ulFlushLength;
9559 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9567 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9573 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
9574 AFS_TRACE_LEVEL_WARNING,
9575 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9576 ObjectInfo->FileId.Cell,
9577 ObjectInfo->FileId.Volume,
9578 ObjectInfo->FileId.Vnode,
9579 ObjectInfo->FileId.Unique);
9581 bPurgeOnClose = TRUE;
9586 bCleanExtents = TRUE;
9593 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9597 __except( EXCEPTION_EXECUTE_HANDLER)
9600 ntStatus = GetExceptionCode();
9604 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9605 ObjectInfo->FileId.Cell,
9606 ObjectInfo->FileId.Volume,
9607 ObjectInfo->FileId.Vnode,
9608 ObjectInfo->FileId.Unique,
9612 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
9613 AFS_TRACE_LEVEL_VERBOSE,
9614 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
9615 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9616 PsGetCurrentThread());
9618 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9622 if ( bExtentsLocked)
9625 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9631 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9637 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9646 if( ObjectInfo != NULL)
9649 AFSObjectInfoDecrement( ObjectInfo);