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 ULONG Code,
55 IN PEXCEPTION_POINTERS ExceptPtrs)
58 PEXCEPTION_RECORD ExceptRec;
64 ExceptRec = ExceptPtrs->ExceptionRecord;
66 Context = ExceptPtrs->ContextRecord;
70 "AFSExceptionFilter (Library) - EXR %p CXR %p Code %08lX Address %p Routine %p\n",
73 ExceptRec->ExceptionCode,
74 ExceptRec->ExceptionAddress,
75 (void *)AFSExceptionFilter);
77 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
79 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
80 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
82 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
84 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
87 KeBugCheck( (ULONG)-2);
95 __except( EXCEPTION_EXECUTE_HANDLER)
101 return EXCEPTION_EXECUTE_HANDLER;
105 // Function: AFSLibExAllocatePoolWithTag()
107 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
108 // is configured on, then bugcheck the system if
109 // a memory allocation fails. The routine should be
110 // used for all memory allocations that are to be freed
111 // when the library is unloaded. Memory allocations that
112 // are to survive library unload and reload should be
113 // performed using AFSExAllocatePoolWithTag() which is
114 // provided by the AFS Framework.
117 // POOL_TYPE PoolType - Paged or NonPaged
118 // SIZE_T NumberOfBytes - requested allocation size
119 // ULONG Tag - Pool Allocation Tag to be applied for tracking
122 // void * - the memory allocation
126 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
127 IN SIZE_T NumberOfBytes,
131 void *pBuffer = NULL;
133 pBuffer = ExAllocatePoolWithTag( PoolType,
140 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
143 KeBugCheck( (ULONG)-2);
150 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
154 PsGetCurrentThread());
164 // Function: AFSAcquireExcl()
166 // Purpose: Called to acquire a resource exclusive with optional wait
169 // PERESOURCE Resource - Resource to acquire
170 // BOOLEAN Wait - Whether to block
173 // BOOLEAN - Whether the mask was acquired
177 AFSAcquireExcl( IN PERESOURCE Resource,
181 BOOLEAN bStatus = FALSE;
184 // Normal kernel APCs must be disabled before calling
185 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
188 KeEnterCriticalRegion();
190 bStatus = ExAcquireResourceExclusiveLite( Resource,
196 KeLeaveCriticalRegion();
203 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
207 BOOLEAN bStatus = FALSE;
209 KeEnterCriticalRegion();
211 bStatus = ExAcquireSharedStarveExclusive( Resource,
217 KeLeaveCriticalRegion();
224 // Function: AFSAcquireShared()
226 // Purpose: Called to acquire a resource shared with optional wait
229 // PERESOURCE Resource - Resource to acquire
230 // BOOLEAN Wait - Whether to block
233 // BOOLEAN - Whether the mask was acquired
237 AFSAcquireShared( IN PERESOURCE Resource,
241 BOOLEAN bStatus = FALSE;
243 KeEnterCriticalRegion();
245 bStatus = ExAcquireResourceSharedLite( Resource,
251 KeLeaveCriticalRegion();
258 // Function: AFSReleaseResource()
260 // Purpose: Called to release a resource
263 // PERESOURCE Resource - Resource to release
270 AFSReleaseResource( IN PERESOURCE Resource)
273 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
274 AFS_TRACE_LEVEL_VERBOSE,
275 "AFSReleaseResource Releasing lock %08lX Thread %08lX\n",
277 PsGetCurrentThread());
279 ExReleaseResourceLite( Resource);
281 KeLeaveCriticalRegion();
287 AFSConvertToShared( IN PERESOURCE Resource)
290 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
291 AFS_TRACE_LEVEL_VERBOSE,
292 "AFSConvertToShared Converting lock %08lX Thread %08lX\n",
294 PsGetCurrentThread());
296 ExConvertExclusiveToSharedLite( Resource);
302 // Function: AFSCompleteRequest
306 // This function completes irps
310 // A status is returned for the function
314 AFSCompleteRequest( IN PIRP Irp,
318 Irp->IoStatus.Status = Status;
320 IoCompleteRequest( Irp,
327 // Function: AFSBuildCRCTable
331 // This function builds the CRC table for mapping filenames to a CRC value.
335 // A status is returned for the function
344 for ( i = 0; i <= 255; i++)
347 for ( j = 8; j > 0; j--)
351 crc = ( crc >> 1 ) ^ CRC32_POLYNOMIAL;
359 AFSCRCTable[ i ] = crc;
364 // Function: AFSGenerateCRC
368 // Given a device and filename this function generates a CRC
372 // A status is returned for the function
376 AFSGenerateCRC( IN PUNICODE_STRING FileName,
377 IN BOOLEAN UpperCaseName)
382 UNICODE_STRING UpcaseString;
396 RtlUpcaseUnicodeString( &UpcaseString,
400 lpbuffer = UpcaseString.Buffer;
402 size = (UpcaseString.Length/sizeof( WCHAR));
407 lpbuffer = FileName->Buffer;
409 size = (FileName->Length/sizeof( WCHAR));
414 temp1 = (crc >> 8) & 0x00FFFFFFL;
415 temp2 = AFSCRCTable[((int)crc ^ *lpbuffer++) & 0xff];
422 RtlFreeUnicodeString( &UpcaseString);
431 AFSLockSystemBuffer( IN PIRP Irp,
435 NTSTATUS Status = STATUS_SUCCESS;
436 void *pAddress = NULL;
438 if( Irp->MdlAddress != NULL)
441 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
444 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
447 pAddress = Irp->AssociatedIrp.SystemBuffer;
449 else if( Irp->UserBuffer != NULL)
452 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
458 if( Irp->MdlAddress != NULL)
462 // Lock the new Mdl in memory.
467 PIO_STACK_LOCATION pIoStack;
468 pIoStack = IoGetCurrentIrpStackLocation( Irp);
471 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
472 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
474 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
477 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
480 IoFreeMdl( Irp->MdlAddress );
481 Irp->MdlAddress = NULL;
491 AFSLockUserBuffer( IN void *UserBuffer,
492 IN ULONG BufferLength,
496 NTSTATUS ntStatus = STATUS_SUCCESS;
497 void *pAddress = NULL;
503 pMdl = IoAllocateMdl( UserBuffer,
512 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
516 // Lock the new Mdl in memory.
522 MmProbeAndLockPages( pMdl,
526 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
529 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
552 AFSMapToService( IN PIRP Irp,
556 NTSTATUS ntStatus = STATUS_SUCCESS;
557 void *pMappedBuffer = NULL;
558 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
564 if( pDevExt->Specific.Control.ServiceProcess == NULL)
567 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
570 if( Irp->MdlAddress == NULL)
573 if( AFSLockSystemBuffer( Irp,
577 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
582 // Attach to the service process for mapping
585 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
586 (PRKAPC_STATE)&stApcState);
588 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
595 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
602 return pMappedBuffer;
606 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
610 NTSTATUS ntStatus = STATUS_SUCCESS;
611 void *pMappedBuffer = NULL;
612 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
618 if( pDevExt->Specific.Control.ServiceProcess == NULL)
621 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
628 // Attach to the service process for mapping
631 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
632 (PRKAPC_STATE)&stApcState);
634 MmUnmapLockedPages( MappedBuffer,
637 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
649 AFSInitializeLibraryDevice()
652 NTSTATUS ntStatus = STATUS_SUCCESS;
653 AFSDeviceExt *pDeviceExt = NULL;
658 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
661 // The PIOCtl file name
664 RtlInitUnicodeString( &AFSPIOCtlName,
665 AFS_PIOCTL_FILE_INTERFACE_NAME);
668 // And the global root share name
671 RtlInitUnicodeString( &AFSGlobalRootName,
672 AFS_GLOBAL_ROOT_SHARE_NAME);
680 AFSRemoveLibraryDevice()
683 NTSTATUS ntStatus = STATUS_SUCCESS;
694 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
698 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
699 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
701 AFSCompleteRequest( Irp,
708 AFSInitializeGlobalDirectoryEntries()
711 NTSTATUS ntStatus = STATUS_SUCCESS;
712 AFSDirectoryCB *pDirNode = NULL;
713 ULONG ulEntryLength = 0;
714 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
715 AFSObjectInfoCB *pObjectInfoCB = NULL;
716 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
722 // Initialize the global . entry
725 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
728 if( pObjectInfoCB == NULL)
731 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
732 AFS_TRACE_LEVEL_ERROR,
733 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
736 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
739 InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
741 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
742 AFS_TRACE_LEVEL_VERBOSE,
743 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
745 pObjectInfoCB->ObjectReferenceCount);
747 ntStatus = STATUS_SUCCESS;
749 ulEntryLength = sizeof( AFSDirectoryCB) +
752 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
756 if( pDirNode == NULL)
759 AFSDeleteObjectInfo( pObjectInfoCB);
761 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
762 AFS_TRACE_LEVEL_ERROR,
763 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
765 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
768 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
769 sizeof( AFSNonPagedDirectoryCB),
770 AFS_DIR_ENTRY_NP_TAG);
772 if( pNonPagedDirEntry == NULL)
775 ExFreePool( pDirNode);
777 AFSDeleteObjectInfo( pObjectInfoCB);
779 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
780 AFS_TRACE_LEVEL_ERROR,
781 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
783 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
786 RtlZeroMemory( pDirNode,
789 RtlZeroMemory( pNonPagedDirEntry,
790 sizeof( AFSNonPagedDirectoryCB));
792 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
794 pDirNode->NonPaged = pNonPagedDirEntry;
796 pDirNode->ObjectInformation = pObjectInfoCB;
802 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
804 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
807 // Setup the names in the entry
810 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
812 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
814 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
816 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
819 // Populate the rest of the data
822 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
824 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
826 AFSGlobalDotDirEntry = pDirNode;
832 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
835 if( pObjectInfoCB == NULL)
838 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
839 AFS_TRACE_LEVEL_ERROR,
840 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
843 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
846 InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
848 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
849 AFS_TRACE_LEVEL_VERBOSE,
850 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
852 pObjectInfoCB->ObjectReferenceCount);
854 ntStatus = STATUS_SUCCESS;
856 ulEntryLength = sizeof( AFSDirectoryCB) +
857 ( 2 * sizeof( WCHAR));
859 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
863 if( pDirNode == NULL)
866 AFSDeleteObjectInfo( pObjectInfoCB);
868 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
871 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
872 sizeof( AFSNonPagedDirectoryCB),
873 AFS_DIR_ENTRY_NP_TAG);
875 if( pNonPagedDirEntry == NULL)
878 ExFreePool( pDirNode);
880 AFSDeleteObjectInfo( pObjectInfoCB);
882 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
885 RtlZeroMemory( pDirNode,
888 RtlZeroMemory( pNonPagedDirEntry,
889 sizeof( AFSNonPagedDirectoryCB));
891 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
893 pDirNode->NonPaged = pNonPagedDirEntry;
895 pDirNode->ObjectInformation = pObjectInfoCB;
901 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
903 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
906 // Setup the names in the entry
909 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
911 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
913 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
915 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
917 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
920 // Populate the rest of the data
923 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
925 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
927 AFSGlobalDotDotDirEntry = pDirNode;
931 if( !NT_SUCCESS( ntStatus))
934 if( AFSGlobalDotDirEntry != NULL)
937 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
939 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
941 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
943 ExFreePool( AFSGlobalDotDirEntry);
945 AFSGlobalDotDirEntry = NULL;
948 if( AFSGlobalDotDotDirEntry != NULL)
951 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
953 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
955 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
957 ExFreePool( AFSGlobalDotDotDirEntry);
959 AFSGlobalDotDotDirEntry = NULL;
968 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
969 IN PUNICODE_STRING FileName,
970 IN PUNICODE_STRING TargetName,
971 IN AFSDirEnumEntry *DirEnumEntry,
975 AFSDirectoryCB *pDirNode = NULL;
976 NTSTATUS ntStatus = STATUS_SUCCESS;
977 ULONG ulEntryLength = 0;
978 AFSDirEnumEntry *pDirEnumCB = NULL;
979 AFSFileID stTargetFileID;
981 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
982 AFSObjectInfoCB *pObjectInfoCB = NULL;
983 BOOLEAN bAllocatedObjectCB = FALSE;
984 ULONGLONG ullIndex = 0;
985 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
990 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
991 AFS_TRACE_LEVEL_VERBOSE,
992 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
994 ParentObjectInfo->FileId.Cell,
995 ParentObjectInfo->FileId.Volume,
996 ParentObjectInfo->FileId.Vnode,
997 ParentObjectInfo->FileId.Unique);
1000 // First thing is to locate/create our object information block
1004 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
1007 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
1009 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
1011 (AFSBTreeEntry **)&pObjectInfoCB);
1013 if( !NT_SUCCESS( ntStatus) ||
1014 pObjectInfoCB == NULL)
1018 // Allocate our object info cb
1021 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
1024 if( pObjectInfoCB == NULL)
1027 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1029 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1032 bAllocatedObjectCB = TRUE;
1034 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
1035 AFS_TRACE_LEVEL_VERBOSE,
1036 "AFSInitDirEntry initialized object %08lX Parent Object %08lX for %wZ\n",
1042 InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
1044 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1045 AFS_TRACE_LEVEL_VERBOSE,
1046 "AFSInitDirEntry Increment count on object %08lX Cnt %d\n",
1048 pObjectInfoCB->ObjectReferenceCount);
1050 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1052 ntStatus = STATUS_SUCCESS;
1054 ulEntryLength = sizeof( AFSDirectoryCB) +
1057 if( TargetName != NULL)
1060 ulEntryLength += TargetName->Length;
1063 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1067 if( pDirNode == NULL)
1070 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1073 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1074 sizeof( AFSNonPagedDirectoryCB),
1075 AFS_DIR_ENTRY_NP_TAG);
1077 if( pNonPagedDirEntry == NULL)
1080 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1083 RtlZeroMemory( pDirNode,
1086 RtlZeroMemory( pNonPagedDirEntry,
1087 sizeof( AFSNonPagedDirectoryCB));
1089 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1091 pDirNode->NonPaged = pNonPagedDirEntry;
1093 pDirNode->ObjectInformation = pObjectInfoCB;
1099 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
1101 pDirNode->FileIndex = FileIndex;
1104 // Setup the names in the entry
1107 if( FileName->Length > 0)
1110 pDirNode->NameInformation.FileName.Length = FileName->Length;
1112 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1114 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1116 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1118 pDirNode->NameInformation.FileName.Length);
1121 // Create a CRC for the file
1124 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1127 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1131 if( TargetName != NULL &&
1132 TargetName->Length > 0)
1135 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1137 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1139 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1140 sizeof( AFSDirectoryCB) +
1141 pDirNode->NameInformation.FileName.Length);
1143 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1145 pDirNode->NameInformation.TargetName.Length);
1149 // If we allocated the object information cb then update the information
1152 if( bAllocatedObjectCB)
1156 // Populate the rest of the data
1159 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1161 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1163 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1165 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1167 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1169 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1171 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1173 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1175 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1177 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1179 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1180 pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1181 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1184 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1187 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1190 // Object specific information
1193 pObjectInfoCB->Links = DirEnumEntry->Links;
1195 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1197 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1200 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1201 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1205 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1206 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1207 pObjectInfoCB->TargetFileId.Unique == 0 &&
1208 pDirNode->NameInformation.TargetName.Length == 0)
1212 // This will ensure we perform a validation on the node
1215 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1218 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1221 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1227 if( !NT_SUCCESS( ntStatus))
1230 if( pNonPagedDirEntry != NULL)
1233 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1235 AFSExFreePool( pNonPagedDirEntry);
1238 if( pDirNode != NULL)
1241 AFSExFreePool( pDirNode);
1247 // Dereference our object info block if we have one
1250 if( pObjectInfoCB != NULL)
1253 InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
1255 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1256 AFS_TRACE_LEVEL_VERBOSE,
1257 "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
1259 pObjectInfoCB->ObjectReferenceCount);
1261 if( bAllocatedObjectCB)
1264 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1266 AFSDeleteObjectInfo( pObjectInfoCB);
1276 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1277 IN BOOLEAN DirectoryEntry)
1280 BOOLEAN bReturn = TRUE;
1281 ACCESS_MASK stAccessMask = 0;
1284 // Get rid of anything we don't know about
1287 DesiredAccess = (DesiredAccess &
1293 ACCESS_SYSTEM_SECURITY |
1297 FILE_READ_ATTRIBUTES |
1298 FILE_WRITE_ATTRIBUTES |
1299 FILE_LIST_DIRECTORY |
1305 // Our 'read only' access mask. These are the accesses we will
1306 // allow for a read only file
1309 stAccessMask = DELETE |
1314 ACCESS_SYSTEM_SECURITY |
1318 FILE_READ_ATTRIBUTES |
1319 FILE_WRITE_ATTRIBUTES |
1321 FILE_LIST_DIRECTORY |
1325 // For a directory, add in the directory specific accesses
1331 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1336 if( FlagOn( DesiredAccess, ~stAccessMask))
1340 // A write access is set ...
1350 AFSEvaluateNode( IN GUID *AuthGroup,
1351 IN AFSDirectoryCB *DirEntry)
1354 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1355 NTSTATUS ntStatus = STATUS_SUCCESS;
1356 AFSDirEnumEntry *pDirEntry = NULL;
1357 UNICODE_STRING uniTargetName;
1362 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1367 if( !NT_SUCCESS( ntStatus))
1370 try_return( ntStatus);
1373 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1375 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1377 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1379 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1381 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1383 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1385 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1387 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1389 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1391 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1393 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1395 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1396 pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1397 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1400 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1403 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1405 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1408 // If we have a target name then see if it needs updating ...
1411 if( pDirEntry->TargetNameLength > 0)
1415 // Update the target name information if needed
1418 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1420 uniTargetName.MaximumLength = uniTargetName.Length;
1422 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1424 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1427 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1428 RtlCompareUnicodeString( &uniTargetName,
1429 &DirEntry->NameInformation.TargetName,
1434 // Update the target name
1437 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1439 uniTargetName.Buffer,
1440 uniTargetName.Length);
1442 if( !NT_SUCCESS( ntStatus))
1445 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1447 try_return( ntStatus);
1451 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1456 if( pDirEntry != NULL)
1459 AFSExFreePool( pDirEntry);
1467 AFSValidateSymLink( IN GUID *AuthGroup,
1468 IN AFSDirectoryCB *DirEntry)
1471 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1472 NTSTATUS ntStatus = STATUS_SUCCESS;
1473 AFSDirEnumEntry *pDirEntry = NULL;
1474 UNICODE_STRING uniTargetName;
1479 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1484 if( !NT_SUCCESS( ntStatus))
1487 try_return( ntStatus);
1490 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1491 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1494 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1497 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1499 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1501 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1504 // Update the target name information if needed
1507 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1509 uniTargetName.MaximumLength = uniTargetName.Length;
1511 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1513 if( uniTargetName.Length > 0)
1516 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1519 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1520 RtlCompareUnicodeString( &uniTargetName,
1521 &DirEntry->NameInformation.TargetName,
1526 // Update the target name
1529 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1531 uniTargetName.Buffer,
1532 uniTargetName.Length);
1534 if( !NT_SUCCESS( ntStatus))
1537 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1539 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1543 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1547 // If the FileType is the same then nothing to do since it IS
1551 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1554 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1556 try_return( ntStatus = STATUS_SUCCESS);
1559 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1561 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1563 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1565 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1567 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1569 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1571 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1573 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1575 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1576 pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1577 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1580 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1583 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1585 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1589 if( pDirEntry != NULL)
1592 AFSExFreePool( pDirEntry);
1600 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1603 NTSTATUS ntStatus = STATUS_SUCCESS;
1604 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1605 AFSVolumeCB *pVolumeCB = NULL;
1606 AFSFcb *pTargetDcb = NULL;
1607 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1608 AFSDirectoryCB *pCurrentDirEntry = NULL;
1609 BOOLEAN bIsChild = FALSE;
1610 ULONGLONG ullIndex = 0;
1611 AFSObjectInfoCB *pObjectInfo = NULL;
1612 IO_STATUS_BLOCK stIoStatus;
1619 // Need to locate the Fcb for the directory to purge
1622 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1623 AFS_TRACE_LEVEL_VERBOSE,
1624 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1625 &pDevExt->Specific.RDR.VolumeTreeLock,
1626 PsGetCurrentThread());
1629 // Starve any exclusive waiters on this paticular call
1632 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1635 // Locate the volume node
1638 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1640 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1642 (AFSBTreeEntry **)&pVolumeCB);
1644 if( pVolumeCB != NULL)
1647 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1649 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1650 AFS_TRACE_LEVEL_VERBOSE,
1651 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1653 pVolumeCB->VolumeReferenceCount);
1656 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1658 if( !NT_SUCCESS( ntStatus) ||
1661 try_return( ntStatus = STATUS_SUCCESS);
1665 // If this is a whole volume invalidation then go do it now
1668 if( InvalidateCB->WholeVolume ||
1669 AFSIsVolumeFID( &InvalidateCB->FileID))
1672 ntStatus = AFSInvalidateVolume( pVolumeCB,
1673 InvalidateCB->Reason);
1675 AFSFsRtlNotifyFullReportChange( &pVolumeCB->ObjectInformation,
1677 FILE_NOTIFY_CHANGE_FILE_NAME |
1678 FILE_NOTIFY_CHANGE_DIR_NAME |
1679 FILE_NOTIFY_CHANGE_NAME |
1680 FILE_NOTIFY_CHANGE_ATTRIBUTES |
1681 FILE_NOTIFY_CHANGE_SIZE,
1682 FILE_ACTION_MODIFIED);
1684 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1686 try_return( ntStatus);
1689 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1692 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1694 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1695 AFS_TRACE_LEVEL_VERBOSE,
1696 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
1698 pVolumeCB->VolumeReferenceCount);
1700 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
1702 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
1704 (AFSBTreeEntry **)&pObjectInfo);
1706 if( pObjectInfo != NULL)
1710 // Reference the node so it won't be torn down
1713 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
1715 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1716 AFS_TRACE_LEVEL_VERBOSE,
1717 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
1719 pObjectInfo->ObjectReferenceCount);
1722 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1724 if( !NT_SUCCESS( ntStatus) ||
1725 pObjectInfo == NULL)
1727 try_return( ntStatus = STATUS_SUCCESS);
1730 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
1731 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK ||
1732 pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1735 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1736 AFS_TRACE_LEVEL_VERBOSE,
1737 "AFSInvalidateCache Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1738 pObjectInfo->FileType,
1739 pObjectInfo->FileId.Cell,
1740 pObjectInfo->FileId.Volume,
1741 pObjectInfo->FileId.Vnode,
1742 pObjectInfo->FileId.Unique,
1743 InvalidateCB->Reason);
1746 // We only act on the mount point itself, not the target. If the
1747 // node has been deleted then mark it as such otherwise indicate
1748 // it requires verification
1751 if( InvalidateCB->Reason == AFS_INVALIDATE_DELETED)
1753 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1758 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
1759 InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1761 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1764 pObjectInfo->Expiration.QuadPart = 0;
1766 pObjectInfo->TargetFileId.Vnode = 0;
1768 pObjectInfo->TargetFileId.Unique = 0;
1770 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1771 AFS_TRACE_LEVEL_VERBOSE,
1772 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1773 pObjectInfo->FileId.Cell,
1774 pObjectInfo->FileId.Volume,
1775 pObjectInfo->FileId.Vnode,
1776 pObjectInfo->FileId.Unique);
1778 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1781 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1783 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1785 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1788 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1790 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1794 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1797 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1799 FILE_NOTIFY_CHANGE_FILE_NAME |
1800 FILE_NOTIFY_CHANGE_ATTRIBUTES,
1801 FILE_ACTION_MODIFIED);
1803 try_return( ntStatus);
1807 // Depending on the reason for invalidation then perform work on the node
1810 switch( InvalidateCB->Reason)
1813 case AFS_INVALIDATE_DELETED:
1817 // Mark this node as invalid
1820 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
1822 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1823 AFS_TRACE_LEVEL_VERBOSE,
1824 "AFSInvalidateCache Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1825 pObjectInfo->FileId.Cell,
1826 pObjectInfo->FileId.Volume,
1827 pObjectInfo->FileId.Vnode,
1828 pObjectInfo->FileId.Unique);
1830 if( pObjectInfo->ParentObjectInformation != NULL)
1833 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1834 AFS_TRACE_LEVEL_VERBOSE,
1835 "AFSInvalidateCache Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1836 pObjectInfo->ParentObjectInformation->FileId.Cell,
1837 pObjectInfo->ParentObjectInformation->FileId.Volume,
1838 pObjectInfo->ParentObjectInformation->FileId.Vnode,
1839 pObjectInfo->ParentObjectInformation->FileId.Unique);
1841 SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1842 pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1843 pObjectInfo->ParentObjectInformation->Expiration.QuadPart = 0;
1846 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1848 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1852 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1855 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1858 FILE_ACTION_REMOVED);
1863 case AFS_INVALIDATE_FLUSHED:
1866 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
1867 pObjectInfo->Fcb != NULL)
1870 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1871 AFS_TRACE_LEVEL_VERBOSE,
1872 "AFSInvalidateCache Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1873 pObjectInfo->FileId.Cell,
1874 pObjectInfo->FileId.Volume,
1875 pObjectInfo->FileId.Vnode,
1876 pObjectInfo->FileId.Unique);
1878 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
1884 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1889 if( !NT_SUCCESS( stIoStatus.Status))
1892 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1893 AFS_TRACE_LEVEL_ERROR,
1894 "AFSInvalidateCache CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1895 pObjectInfo->FileId.Cell,
1896 pObjectInfo->FileId.Volume,
1897 pObjectInfo->FileId.Vnode,
1898 pObjectInfo->FileId.Unique,
1900 stIoStatus.Information);
1902 ntStatus = stIoStatus.Status;
1905 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1910 __except( EXCEPTION_EXECUTE_HANDLER)
1913 ntStatus = GetExceptionCode();
1916 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
1919 // Clear out the extents
1920 // Get rid of them (note this involves waiting
1921 // for any writes or reads to the cache to complete)
1924 (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb);
1927 // Fall through to the default processing
1933 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1935 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1939 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1942 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1944 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1947 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1949 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1953 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1956 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1959 FILE_ACTION_MODIFIED);
1962 // Indicate this node requires re-evaluation for the remaining reasons
1965 pObjectInfo->Expiration.QuadPart = 0;
1967 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1968 AFS_TRACE_LEVEL_VERBOSE,
1969 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1970 pObjectInfo->FileId.Cell,
1971 pObjectInfo->FileId.Volume,
1972 pObjectInfo->FileId.Vnode,
1973 pObjectInfo->FileId.Unique);
1975 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1977 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
1978 InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1980 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1982 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
1985 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1986 AFS_TRACE_LEVEL_VERBOSE,
1987 "AFSInvalidateCache Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1988 pObjectInfo->FileId.Cell,
1989 pObjectInfo->FileId.Volume,
1990 pObjectInfo->FileId.Vnode,
1991 pObjectInfo->FileId.Unique);
1993 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2003 if( pObjectInfo != NULL)
2006 InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
2008 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2009 AFS_TRACE_LEVEL_VERBOSE,
2010 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
2012 pObjectInfo->ObjectReferenceCount);
2020 AFSIsChildOfParent( IN AFSFcb *Dcb,
2024 BOOLEAN bIsChild = FALSE;
2025 AFSFcb *pCurrentFcb = Fcb;
2027 while( pCurrentFcb != NULL)
2030 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2038 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2046 AFSCreateHighIndex( IN AFSFileID *FileID)
2049 ULONGLONG ullIndex = 0;
2051 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2058 AFSCreateLowIndex( IN AFSFileID *FileID)
2061 ULONGLONG ullIndex = 0;
2063 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2069 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2070 IN ACCESS_MASK GrantedAccess,
2071 IN BOOLEAN DirectoryEntry)
2074 BOOLEAN bAccessGranted = TRUE;
2077 // Check if we are asking for read/write and granted only read only
2078 // NOTE: There will be more checks here
2081 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2083 AFSCheckForReadOnlyAccess( GrantedAccess,
2087 bAccessGranted = FALSE;
2090 return bAccessGranted;
2094 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2097 NTSTATUS ntStatus = STATUS_SUCCESS;
2098 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2104 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2106 if( AFSGlobalRoot == NULL)
2113 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2116 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2123 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2130 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2131 IN UNICODE_STRING *SubstituteName,
2132 IN ULONG StringIndex)
2135 NTSTATUS ntStatus = STATUS_SUCCESS;
2136 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2137 AFSSysNameCB *pSysName = NULL;
2138 ERESOURCE *pSysNameLock = NULL;
2141 UNICODE_STRING uniSysName;
2148 if( IoIs32bitProcess( NULL))
2151 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2153 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2158 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2160 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2164 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2166 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2170 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2171 AFS_TRACE_LEVEL_VERBOSE,
2172 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2174 PsGetCurrentThread());
2176 AFSAcquireShared( pSysNameLock,
2180 // Find where we are in the list
2183 while( pSysName != NULL &&
2184 ulIndex < StringIndex)
2187 pSysName = pSysName->fLink;
2192 if( pSysName == NULL)
2195 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2198 RtlInitUnicodeString( &uniSysName,
2201 // If it is a full component of @SYS then just substitue the
2205 if( RtlCompareUnicodeString( &uniSysName,
2210 SubstituteName->Length = pSysName->SysName.Length;
2211 SubstituteName->MaximumLength = SubstituteName->Length;
2213 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2214 SubstituteName->Length,
2215 AFS_SUBST_BUFFER_TAG);
2217 if( SubstituteName->Buffer == NULL)
2220 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2223 RtlCopyMemory( SubstituteName->Buffer,
2224 pSysName->SysName.Buffer,
2225 pSysName->SysName.Length);
2232 while( ComponentName->Buffer[ usIndex] != L'@')
2238 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2239 SubstituteName->MaximumLength = SubstituteName->Length;
2241 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2242 SubstituteName->Length,
2243 AFS_SUBST_BUFFER_TAG);
2245 if( SubstituteName->Buffer == NULL)
2248 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2251 RtlCopyMemory( SubstituteName->Buffer,
2252 ComponentName->Buffer,
2253 usIndex * sizeof( WCHAR));
2255 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2256 pSysName->SysName.Buffer,
2257 pSysName->SysName.Length);
2262 AFSReleaseResource( pSysNameLock);
2269 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2270 IN OUT UNICODE_STRING *ComponentName,
2271 IN UNICODE_STRING *SubstituteName,
2272 IN OUT UNICODE_STRING *RemainingPath,
2273 IN BOOLEAN FreePathName)
2276 NTSTATUS ntStatus = STATUS_SUCCESS;
2277 UNICODE_STRING uniPathName;
2278 USHORT usPrefixNameLen = 0;
2279 SHORT sNameLenDelta = 0;
2285 // If the passed in name can handle the additional length
2286 // then just moves things around
2289 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2291 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2293 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2296 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2299 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2300 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2301 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2304 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2305 SubstituteName->Buffer,
2306 SubstituteName->Length);
2308 FullPathName->Length += sNameLenDelta;
2310 ComponentName->Length += sNameLenDelta;
2312 ComponentName->MaximumLength = ComponentName->Length;
2314 if ( RemainingPath->Buffer)
2317 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2320 try_return( ntStatus);
2324 // Need to re-allocate the buffer
2327 uniPathName.Length = FullPathName->Length -
2328 ComponentName->Length +
2329 SubstituteName->Length;
2331 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2333 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2334 uniPathName.MaximumLength,
2335 AFS_NAME_BUFFER_FOUR_TAG);
2337 if( uniPathName.Buffer == NULL)
2340 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2343 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2345 usPrefixNameLen *= sizeof( WCHAR);
2347 RtlZeroMemory( uniPathName.Buffer,
2348 uniPathName.MaximumLength);
2350 RtlCopyMemory( uniPathName.Buffer,
2351 FullPathName->Buffer,
2354 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2355 SubstituteName->Buffer,
2356 SubstituteName->Length);
2358 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2361 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2362 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2363 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2366 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2368 ComponentName->Length += sNameLenDelta;
2370 ComponentName->MaximumLength = ComponentName->Length;
2372 if ( RemainingPath->Buffer)
2375 RemainingPath->Buffer = uniPathName.Buffer
2376 + (RemainingPath->Buffer - FullPathName->Buffer)
2377 + sNameLenDelta/sizeof( WCHAR);
2382 AFSExFreePool( FullPathName->Buffer);
2385 *FullPathName = uniPathName;
2396 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2400 NTSTATUS ntStatus = STATUS_SUCCESS;
2401 AFSFcb *pFcb = NULL;
2402 AFSObjectInfoCB *pCurrentObject = NULL;
2408 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2409 AFS_TRACE_LEVEL_VERBOSE,
2410 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2411 VolumeCB->ObjectInformation.FileId.Cell,
2412 VolumeCB->ObjectInformation.FileId.Volume,
2413 VolumeCB->ObjectInformation.FileId.Vnode,
2414 VolumeCB->ObjectInformation.FileId.Unique,
2418 // Depending on the reason for invalidation then perform work on the node
2424 case AFS_INVALIDATE_DELETED:
2428 // Mark this volume as invalid
2431 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2433 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2435 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2437 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2439 FILE_NOTIFY_CHANGE_DIR_NAME,
2440 FILE_ACTION_REMOVED);
2442 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2445 pCurrentObject = VolumeCB->ObjectInfoListHead;
2447 while( pCurrentObject != NULL)
2450 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2452 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2456 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2459 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2462 FILE_ACTION_REMOVED);
2464 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2466 pFcb = pCurrentObject->Fcb;
2469 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2474 // Clear out the extents
2475 // And get rid of them (note this involves waiting
2476 // for any writes or reads to the cache to complete)
2479 (VOID) AFSTearDownFcbExtents( pFcb);
2482 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2485 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2494 // Indicate this node requires re-evaluation for the remaining reasons
2497 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2499 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2500 AFS_TRACE_LEVEL_VERBOSE,
2501 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2502 VolumeCB->ObjectInformation.FileId.Cell,
2503 VolumeCB->ObjectInformation.FileId.Volume,
2504 VolumeCB->ObjectInformation.FileId.Vnode,
2505 VolumeCB->ObjectInformation.FileId.Unique);
2507 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY);
2509 if( Reason == AFS_INVALIDATE_FLUSHED ||
2510 Reason == AFS_INVALIDATE_DATA_VERSION)
2513 VolumeCB->ObjectInformation.DataVersion.QuadPart = (ULONGLONG)-1;
2517 // Notify anyone that cares
2520 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2522 if( Reason == AFS_INVALIDATE_CREDS)
2524 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2527 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2529 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2533 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2536 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2539 FILE_ACTION_MODIFIED);
2542 // Volume invalidations require all objects in the volume be re-verified
2545 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2548 pCurrentObject = VolumeCB->ObjectInfoListHead;
2550 while( pCurrentObject != NULL)
2553 pCurrentObject->Expiration.QuadPart = 0;
2555 pCurrentObject->TargetFileId.Vnode = 0;
2557 pCurrentObject->TargetFileId.Unique = 0;
2559 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2560 AFS_TRACE_LEVEL_VERBOSE,
2561 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2562 pCurrentObject->FileId.Cell,
2563 pCurrentObject->FileId.Volume,
2564 pCurrentObject->FileId.Vnode,
2565 pCurrentObject->FileId.Unique);
2567 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
2569 if( Reason == AFS_INVALIDATE_FLUSHED ||
2570 Reason == AFS_INVALIDATE_DATA_VERSION)
2573 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
2575 if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
2578 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2579 AFS_TRACE_LEVEL_VERBOSE,
2580 "AFSInvalidateVolume Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
2581 pCurrentObject->FileId.Cell,
2582 pCurrentObject->FileId.Volume,
2583 pCurrentObject->FileId.Vnode,
2584 pCurrentObject->FileId.Unique);
2586 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2590 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2592 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2596 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2599 if( Reason == AFS_INVALIDATE_CREDS)
2601 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2604 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2606 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2610 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2613 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2616 FILE_ACTION_MODIFIED);
2618 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2621 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2632 AFSVerifyEntry( IN GUID *AuthGroup,
2633 IN AFSDirectoryCB *DirEntry)
2636 NTSTATUS ntStatus = STATUS_SUCCESS;
2637 AFSDirEnumEntry *pDirEnumEntry = NULL;
2638 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2639 IO_STATUS_BLOCK stIoStatus;
2644 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2645 AFS_TRACE_LEVEL_VERBOSE_2,
2646 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2647 &DirEntry->NameInformation.FileName,
2648 pObjectInfo->FileId.Cell,
2649 pObjectInfo->FileId.Volume,
2650 pObjectInfo->FileId.Vnode,
2651 pObjectInfo->FileId.Unique);
2653 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2658 if( !NT_SUCCESS( ntStatus))
2661 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2662 AFS_TRACE_LEVEL_ERROR,
2663 "AFSValidateEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2664 &DirEntry->NameInformation.FileName,
2665 pObjectInfo->FileId.Cell,
2666 pObjectInfo->FileId.Volume,
2667 pObjectInfo->FileId.Vnode,
2668 pObjectInfo->FileId.Unique,
2671 try_return( ntStatus);
2675 // Check the data version of the file
2678 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2679 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2682 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2683 AFS_TRACE_LEVEL_VERBOSE,
2684 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2685 pObjectInfo->DataVersion.QuadPart,
2686 &DirEntry->NameInformation.FileName,
2687 pObjectInfo->FileId.Cell,
2688 pObjectInfo->FileId.Volume,
2689 pObjectInfo->FileId.Vnode,
2690 pObjectInfo->FileId.Unique);
2693 // We are ok, just get out
2696 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2698 try_return( ntStatus = STATUS_SUCCESS);
2702 // New data version so we will need to process the node based on the type
2705 switch( pDirEnumEntry->FileType)
2708 case AFS_FILE_TYPE_MOUNTPOINT:
2712 // For a mount point we need to ensure the target is the same
2715 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2716 &pDirEnumEntry->TargetFileId))
2722 // Update the metadata for the entry
2725 ntStatus = AFSUpdateMetaData( DirEntry,
2728 if( NT_SUCCESS( ntStatus))
2731 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2737 case AFS_FILE_TYPE_SYMLINK:
2740 ASSERT( pDirEnumEntry->TargetNameLength > 0);
2743 // Update the metadata for the entry
2746 ntStatus = AFSUpdateMetaData( DirEntry,
2749 if( NT_SUCCESS( ntStatus))
2752 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2758 case AFS_FILE_TYPE_FILE:
2760 FILE_OBJECT * pCCFileObject = NULL;
2761 BOOLEAN bPurgeExtents = FALSE;
2763 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2765 bPurgeExtents = TRUE;
2767 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2768 AFS_TRACE_LEVEL_VERBOSE,
2769 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2770 &DirEntry->NameInformation.FileName,
2771 pObjectInfo->FileId.Cell,
2772 pObjectInfo->FileId.Volume,
2773 pObjectInfo->FileId.Vnode,
2774 pObjectInfo->FileId.Unique);
2776 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2780 // Update the metadata for the entry
2783 ntStatus = AFSUpdateMetaData( DirEntry,
2786 if( !NT_SUCCESS( ntStatus))
2789 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2790 AFS_TRACE_LEVEL_ERROR,
2791 "AFSInvalidateCache Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2792 &DirEntry->NameInformation.FileName,
2793 pObjectInfo->FileId.Cell,
2794 pObjectInfo->FileId.Volume,
2795 pObjectInfo->FileId.Vnode,
2796 pObjectInfo->FileId.Unique,
2802 if( pObjectInfo->Fcb != NULL)
2805 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2806 AFS_TRACE_LEVEL_VERBOSE,
2807 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2808 &DirEntry->NameInformation.FileName,
2809 pObjectInfo->FileId.Cell,
2810 pObjectInfo->FileId.Volume,
2811 pObjectInfo->FileId.Vnode,
2812 pObjectInfo->FileId.Unique);
2814 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2820 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2825 if( !NT_SUCCESS( stIoStatus.Status))
2828 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2829 AFS_TRACE_LEVEL_ERROR,
2830 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2831 &DirEntry->NameInformation.FileName,
2832 pObjectInfo->FileId.Cell,
2833 pObjectInfo->FileId.Volume,
2834 pObjectInfo->FileId.Vnode,
2835 pObjectInfo->FileId.Unique,
2837 stIoStatus.Information);
2839 ntStatus = stIoStatus.Status;
2845 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2851 __except( EXCEPTION_EXECUTE_HANDLER)
2853 ntStatus = GetExceptionCode();
2855 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2856 AFS_TRACE_LEVEL_ERROR,
2857 "AFSVerifyEntry CcFlushCache or CcPurgeCacheSection Exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2858 &DirEntry->NameInformation.FileName,
2859 pObjectInfo->FileId.Cell,
2860 pObjectInfo->FileId.Volume,
2861 pObjectInfo->FileId.Vnode,
2862 pObjectInfo->FileId.Unique,
2866 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2870 AFSFlushExtents( pObjectInfo->Fcb);
2874 // Reacquire the Fcb to purge the cache
2877 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2878 AFS_TRACE_LEVEL_VERBOSE,
2879 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2880 &pObjectInfo->Fcb->NPFcb->Resource,
2881 PsGetCurrentThread());
2883 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2887 // Update file sizes
2890 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2891 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2892 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2894 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2896 if ( pCCFileObject != NULL)
2898 CcSetFileSizes( pCCFileObject,
2899 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
2902 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2906 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2907 AFS_TRACE_LEVEL_WARNING,
2908 "AFSValidateEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2909 &DirEntry->NameInformation.FileName,
2910 pObjectInfo->FileId.Cell,
2911 pObjectInfo->FileId.Volume,
2912 pObjectInfo->FileId.Vnode,
2913 pObjectInfo->FileId.Unique);
2916 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2921 case AFS_FILE_TYPE_DIRECTORY:
2924 AFSFcb *pCurrentFcb = NULL;
2925 AFSDirectoryCB *pCurrentDirEntry = NULL;
2928 // For a directory or root entry flush the content of
2929 // the directory enumeration.
2932 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2935 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2936 AFS_TRACE_LEVEL_VERBOSE_2,
2937 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2938 &DirEntry->NameInformation.FileName,
2939 pObjectInfo->FileId.Cell,
2940 pObjectInfo->FileId.Volume,
2941 pObjectInfo->FileId.Vnode,
2942 pObjectInfo->FileId.Unique);
2944 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2947 AFSValidateDirectoryCache( pObjectInfo,
2950 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2954 // Update the metadata for the entry
2957 ntStatus = AFSUpdateMetaData( DirEntry,
2960 if( NT_SUCCESS( ntStatus))
2963 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2969 case AFS_FILE_TYPE_DFSLINK:
2972 UNICODE_STRING uniTargetName;
2975 // For a DFS link need to check the target name has not changed
2978 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
2980 uniTargetName.MaximumLength = uniTargetName.Length;
2982 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
2984 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
2987 if( DirEntry->NameInformation.TargetName.Length == 0 ||
2988 RtlCompareUnicodeString( &uniTargetName,
2989 &DirEntry->NameInformation.TargetName,
2994 // Update the target name
2997 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
2999 uniTargetName.Buffer,
3000 uniTargetName.Length);
3002 if( !NT_SUCCESS( ntStatus))
3005 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3011 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3014 // Update the metadata for the entry
3017 ntStatus = AFSUpdateMetaData( DirEntry,
3020 if( NT_SUCCESS( ntStatus))
3023 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3031 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3032 AFS_TRACE_LEVEL_WARNING,
3033 "AFSVerifyEntry Attempt to verify node of type %d\n",
3034 pObjectInfo->FileType);
3041 if( pDirEnumEntry != NULL)
3044 AFSExFreePool( pDirEnumEntry);
3052 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3055 NTSTATUS ntStatus = STATUS_SUCCESS;
3056 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3057 ULONGLONG ullIndex = 0;
3058 AFSVolumeCB *pVolumeCB = NULL;
3059 AFSFcb *pFcb = NULL;
3060 AFSObjectInfoCB *pCurrentObject = NULL;
3065 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3066 AFS_TRACE_LEVEL_VERBOSE,
3067 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3068 VolumeStatus->Online,
3069 VolumeStatus->FileID.Cell,
3070 VolumeStatus->FileID.Volume);
3073 // Need to locate the Fcb for the directory to purge
3076 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3077 AFS_TRACE_LEVEL_VERBOSE,
3078 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3079 &pDevExt->Specific.RDR.VolumeTreeLock,
3080 PsGetCurrentThread());
3082 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3085 // Locate the volume node
3088 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3090 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3092 (AFSBTreeEntry **)&pVolumeCB);
3094 if( pVolumeCB != NULL)
3097 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3099 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3102 // Set the volume state accordingly
3105 if( VolumeStatus->Online)
3108 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3113 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3116 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3119 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3121 while( pCurrentObject != NULL)
3124 if( VolumeStatus->Online)
3127 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3129 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3131 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3136 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3139 pFcb = pCurrentObject->Fcb;
3142 !(VolumeStatus->Online) &&
3143 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3146 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3147 AFS_TRACE_LEVEL_ERROR,
3148 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3149 VolumeStatus->FileID.Cell,
3150 VolumeStatus->FileID.Volume);
3153 // Clear out the extents
3156 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3157 AFS_TRACE_LEVEL_VERBOSE,
3158 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3159 &pFcb->NPFcb->Specific.File.ExtentsResource,
3160 PsGetCurrentThread());
3162 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3165 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3167 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3171 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3172 AFS_TRACE_LEVEL_VERBOSE,
3173 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3174 &pFcb->NPFcb->Specific.File.ExtentsResource,
3175 PsGetCurrentThread());
3177 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3180 // And get rid of them (note this involves waiting
3181 // for any writes or reads to the cache to complete)
3184 (VOID) AFSTearDownFcbExtents( pFcb);
3187 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3190 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3192 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3197 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3205 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3208 NTSTATUS ntStatus = STATUS_SUCCESS;
3213 if( AFSGlobalRoot == NULL)
3216 try_return( ntStatus);
3219 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3223 // Set the network state according to the information
3226 if( NetworkStatus->Online)
3229 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3234 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3237 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3248 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3252 NTSTATUS ntStatus = STATUS_SUCCESS;
3253 BOOLEAN bAcquiredLock = FALSE;
3254 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3255 AFSFcb *pFcb = NULL;
3260 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3261 AFS_TRACE_LEVEL_VERBOSE,
3262 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3263 ObjectInfo->FileId.Cell,
3264 ObjectInfo->FileId.Volume,
3265 ObjectInfo->FileId.Vnode,
3266 ObjectInfo->FileId.Unique);
3268 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3271 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3272 AFS_TRACE_LEVEL_VERBOSE,
3273 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3274 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3275 PsGetCurrentThread());
3277 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3280 bAcquiredLock = TRUE;
3284 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3287 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3288 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3291 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3292 AFS_TRACE_LEVEL_ERROR,
3293 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
3294 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3295 ObjectInfo->FileId.Cell,
3296 ObjectInfo->FileId.Volume,
3297 ObjectInfo->FileId.Vnode,
3298 ObjectInfo->FileId.Unique);
3302 // Reset the directory list information by clearing all valid entries
3305 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3307 while( pCurrentDirEntry != NULL)
3310 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3313 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3316 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3320 // Reget the directory contents
3323 AFSVerifyDirectoryContent( ObjectInfo,
3327 // Now start again and tear down any entries not valid
3330 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3332 while( pCurrentDirEntry != NULL)
3335 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3337 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3340 pCurrentDirEntry = pNextDirEntry;
3345 if( pCurrentDirEntry->OpenReferenceCount == 0)
3348 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3349 AFS_TRACE_LEVEL_VERBOSE,
3350 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3351 &pCurrentDirEntry->NameInformation.FileName,
3352 ObjectInfo->FileId.Cell,
3353 ObjectInfo->FileId.Volume,
3354 ObjectInfo->FileId.Vnode,
3355 ObjectInfo->FileId.Unique);
3357 AFSDeleteDirEntry( ObjectInfo,
3363 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3364 AFS_TRACE_LEVEL_VERBOSE,
3365 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3367 &pCurrentDirEntry->NameInformation.FileName,
3368 ObjectInfo->FileId.Cell,
3369 ObjectInfo->FileId.Volume,
3370 ObjectInfo->FileId.Vnode,
3371 ObjectInfo->FileId.Unique);
3373 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3375 AFSRemoveNameEntry( ObjectInfo,
3379 pCurrentDirEntry = pNextDirEntry;
3383 if( !AFSValidateDirList( ObjectInfo))
3386 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3393 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3401 AFSIsVolumeFID( IN AFSFileID *FileID)
3404 BOOLEAN bIsVolume = FALSE;
3406 if( FileID->Vnode == 1 &&
3407 FileID->Unique == 1)
3417 AFSIsFinalNode( IN AFSFcb *Fcb)
3420 BOOLEAN bIsFinalNode = FALSE;
3422 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3423 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3424 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3425 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3426 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3429 bIsFinalNode = TRUE;
3434 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3435 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3438 return bIsFinalNode;
3442 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3443 IN AFSDirEnumEntry *DirEnumEntry)
3446 NTSTATUS ntStatus = STATUS_SUCCESS;
3447 UNICODE_STRING uniTargetName;
3448 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3453 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3455 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3457 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3459 pObjectInfo->FileType = DirEnumEntry->FileType;
3461 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3463 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3465 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3467 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3469 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3471 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3473 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3475 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3476 pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3477 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3480 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3483 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3485 pObjectInfo->Links = DirEnumEntry->Links;
3487 if( DirEnumEntry->TargetNameLength > 0)
3491 // Update the target name information if needed
3494 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3496 uniTargetName.MaximumLength = uniTargetName.Length;
3498 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3500 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3503 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3504 RtlCompareUnicodeString( &uniTargetName,
3505 &DirEntry->NameInformation.TargetName,
3510 // Update the target name
3513 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3515 uniTargetName.Buffer,
3516 uniTargetName.Length);
3518 if( !NT_SUCCESS( ntStatus))
3521 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3523 try_return( ntStatus);
3527 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3529 else if( DirEntry->NameInformation.TargetName.Length > 0)
3532 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3535 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3536 DirEntry->NameInformation.TargetName.Buffer != NULL)
3538 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
3541 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3543 DirEntry->NameInformation.TargetName.Length = 0;
3544 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3545 DirEntry->NameInformation.TargetName.Buffer = NULL;
3547 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3559 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3561 IN BOOLEAN PurgeContent,
3562 IN BOOLEAN FastCall)
3565 NTSTATUS ntStatus = STATUS_SUCCESS;
3566 LARGE_INTEGER liSystemTime;
3567 AFSDirEnumEntry *pDirEnumEntry = NULL;
3568 AFSFcb *pCurrentFcb = NULL;
3569 BOOLEAN bReleaseFcb = FALSE;
3570 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3576 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3580 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3581 AFS_TRACE_LEVEL_VERBOSE_2,
3582 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3583 &DirEntry->NameInformation.FileName,
3584 pObjectInfo->FileId.Cell,
3585 pObjectInfo->FileId.Volume,
3586 pObjectInfo->FileId.Vnode,
3587 pObjectInfo->FileId.Unique);
3590 // If this is a fake node then bail since the service knows nothing about it
3593 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3596 try_return( ntStatus);
3600 pObjectInfo->Fcb != NULL)
3603 pCurrentFcb = pObjectInfo->Fcb;
3605 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3608 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3609 AFS_TRACE_LEVEL_VERBOSE,
3610 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3611 &pCurrentFcb->NPFcb->Resource,
3612 PsGetCurrentThread());
3614 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3622 // This routine ensures that the current entry is valid by:
3624 // 1) Checking that the expiration time is non-zero and after where we
3628 KeQuerySystemTime( &liSystemTime);
3630 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3631 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3632 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3633 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3636 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3637 AFS_TRACE_LEVEL_VERBOSE_2,
3638 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3639 &DirEntry->NameInformation.FileName,
3640 pObjectInfo->FileId.Cell,
3641 pObjectInfo->FileId.Volume,
3642 pObjectInfo->FileId.Vnode,
3643 pObjectInfo->FileId.Unique);
3645 try_return( ntStatus);
3649 // This node requires updating
3652 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3657 if( !NT_SUCCESS( ntStatus))
3660 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3661 AFS_TRACE_LEVEL_ERROR,
3662 "AFSValidateEntry Failed to evaluate entry %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3663 &DirEntry->NameInformation.FileName,
3664 pObjectInfo->FileId.Cell,
3665 pObjectInfo->FileId.Volume,
3666 pObjectInfo->FileId.Vnode,
3667 pObjectInfo->FileId.Unique,
3671 // Failed validation of node so return access-denied
3674 try_return( ntStatus);
3677 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3678 AFS_TRACE_LEVEL_VERBOSE,
3679 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3680 &DirEntry->NameInformation.FileName,
3681 pObjectInfo->FileId.Cell,
3682 pObjectInfo->FileId.Volume,
3683 pObjectInfo->FileId.Vnode,
3684 pObjectInfo->FileId.Unique,
3685 pObjectInfo->DataVersion.QuadPart,
3686 pDirEnumEntry->DataVersion.QuadPart,
3687 pDirEnumEntry->FileType);
3691 // Based on the file type, process the node
3694 switch( pDirEnumEntry->FileType)
3697 case AFS_FILE_TYPE_MOUNTPOINT:
3701 // Update the metadata for the entry
3704 ntStatus = AFSUpdateMetaData( DirEntry,
3707 if( NT_SUCCESS( ntStatus))
3710 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3716 case AFS_FILE_TYPE_SYMLINK:
3717 case AFS_FILE_TYPE_DFSLINK:
3721 // Update the metadata for the entry
3724 ntStatus = AFSUpdateMetaData( DirEntry,
3727 if( NT_SUCCESS( ntStatus))
3730 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3736 case AFS_FILE_TYPE_FILE:
3740 // For a file where the data version has become invalid we need to
3741 // fail any current extent requests and purge the cache for the file
3742 // Can't hold the Fcb resource while doing this
3745 if( pCurrentFcb != NULL &&
3746 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3747 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3750 IO_STATUS_BLOCK stIoStatus;
3751 BOOLEAN bPurgeExtents = FALSE;
3753 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3754 AFS_TRACE_LEVEL_VERBOSE_2,
3755 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3756 &DirEntry->NameInformation.FileName,
3757 pObjectInfo->FileId.Cell,
3758 pObjectInfo->FileId.Volume,
3759 pObjectInfo->FileId.Vnode,
3760 pObjectInfo->FileId.Unique);
3762 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3764 bPurgeExtents = TRUE;
3766 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3767 AFS_TRACE_LEVEL_VERBOSE,
3768 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3769 &DirEntry->NameInformation.FileName,
3770 pObjectInfo->FileId.Cell,
3771 pObjectInfo->FileId.Volume,
3772 pObjectInfo->FileId.Vnode,
3773 pObjectInfo->FileId.Unique);
3775 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3781 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
3786 if( !NT_SUCCESS( stIoStatus.Status))
3789 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3790 AFS_TRACE_LEVEL_ERROR,
3791 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3792 &DirEntry->NameInformation.FileName,
3793 pObjectInfo->FileId.Cell,
3794 pObjectInfo->FileId.Volume,
3795 pObjectInfo->FileId.Vnode,
3796 pObjectInfo->FileId.Unique,
3798 stIoStatus.Information);
3800 ntStatus = stIoStatus.Status;
3806 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3812 __except( EXCEPTION_EXECUTE_HANDLER)
3814 ntStatus = GetExceptionCode();
3816 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3817 AFS_TRACE_LEVEL_ERROR,
3818 "AFSValidateEntry CcFlushCache or CcPurgeCacheSection exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3819 &DirEntry->NameInformation.FileName,
3820 pObjectInfo->FileId.Cell,
3821 pObjectInfo->FileId.Volume,
3822 pObjectInfo->FileId.Vnode,
3823 pObjectInfo->FileId.Unique,
3828 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3832 AFSFlushExtents( pCurrentFcb);
3836 // Reacquire the Fcb to purge the cache
3839 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3840 AFS_TRACE_LEVEL_VERBOSE,
3841 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3842 &pCurrentFcb->NPFcb->Resource,
3843 PsGetCurrentThread());
3845 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3850 // Update the metadata for the entry
3853 ntStatus = AFSUpdateMetaData( DirEntry,
3856 if( !NT_SUCCESS( ntStatus))
3859 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3860 AFS_TRACE_LEVEL_ERROR,
3861 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3862 &DirEntry->NameInformation.FileName,
3863 pObjectInfo->FileId.Cell,
3864 pObjectInfo->FileId.Volume,
3865 pObjectInfo->FileId.Vnode,
3866 pObjectInfo->FileId.Unique,
3872 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3875 // Update file sizes
3878 if( pObjectInfo->Fcb != NULL)
3880 FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3882 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3883 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3884 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3886 if ( pCCFileObject != NULL)
3888 CcSetFileSizes( pCCFileObject,
3889 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3896 case AFS_FILE_TYPE_DIRECTORY:
3899 AFSDirectoryCB *pCurrentDirEntry = NULL;
3901 if( pCurrentFcb != NULL &&
3902 pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3906 // For a directory or root entry flush the content of
3907 // the directory enumeration.
3910 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3911 AFS_TRACE_LEVEL_VERBOSE,
3912 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3913 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3914 PsGetCurrentThread());
3916 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3919 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3920 AFS_TRACE_LEVEL_VERBOSE_2,
3921 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3922 &DirEntry->NameInformation.FileName,
3923 pObjectInfo->FileId.Cell,
3924 pObjectInfo->FileId.Volume,
3925 pObjectInfo->FileId.Vnode,
3926 pObjectInfo->FileId.Unique);
3928 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3931 AFSValidateDirectoryCache( pCurrentFcb->ObjectInformation,
3934 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3937 if( !NT_SUCCESS( ntStatus))
3940 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3941 AFS_TRACE_LEVEL_ERROR,
3942 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3943 &DirEntry->NameInformation.FileName,
3944 pObjectInfo->FileId.Cell,
3945 pObjectInfo->FileId.Volume,
3946 pObjectInfo->FileId.Vnode,
3947 pObjectInfo->FileId.Unique,
3955 // Update the metadata for the entry
3958 ntStatus = AFSUpdateMetaData( DirEntry,
3961 if( NT_SUCCESS( ntStatus))
3964 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3972 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3973 AFS_TRACE_LEVEL_WARNING,
3974 "AFSValidateEntry Attempt to verify node of type %d\n",
3975 pObjectInfo->FileType);
3985 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3988 if( pDirEnumEntry != NULL)
3991 AFSExFreePool( pDirEnumEntry);
3999 AFSInitializeSpecialShareNameList()
4002 NTSTATUS ntStatus = STATUS_SUCCESS;
4003 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4004 AFSObjectInfoCB *pObjectInfoCB = NULL;
4005 UNICODE_STRING uniShareName;
4006 ULONG ulEntryLength = 0;
4007 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4012 RtlInitUnicodeString( &uniShareName,
4015 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4018 if( pObjectInfoCB == NULL)
4021 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4024 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4025 AFS_TRACE_LEVEL_VERBOSE,
4026 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
4029 pObjectInfoCB->ObjectReferenceCount = 1;
4031 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4033 ulEntryLength = sizeof( AFSDirectoryCB) +
4034 uniShareName.Length;
4036 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4040 if( pDirNode == NULL)
4043 AFSDeleteObjectInfo( pObjectInfoCB);
4045 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4048 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4049 sizeof( AFSNonPagedDirectoryCB),
4050 AFS_DIR_ENTRY_NP_TAG);
4052 if( pNonPagedDirEntry == NULL)
4055 ExFreePool( pDirNode);
4057 AFSDeleteObjectInfo( pObjectInfoCB);
4059 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4062 RtlZeroMemory( pDirNode,
4065 RtlZeroMemory( pNonPagedDirEntry,
4066 sizeof( AFSNonPagedDirectoryCB));
4068 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4070 pDirNode->NonPaged = pNonPagedDirEntry;
4072 pDirNode->ObjectInformation = pObjectInfoCB;
4078 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
4080 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4082 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4084 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4086 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4087 uniShareName.Buffer,
4088 pDirNode->NameInformation.FileName.Length);
4090 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4093 AFSSpecialShareNames = pDirNode;
4095 pLastDirNode = pDirNode;
4097 RtlInitUnicodeString( &uniShareName,
4100 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4103 if( pObjectInfoCB == NULL)
4106 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4109 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4110 AFS_TRACE_LEVEL_VERBOSE,
4111 "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
4114 pObjectInfoCB->ObjectReferenceCount = 1;
4116 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4118 ulEntryLength = sizeof( AFSDirectoryCB) +
4119 uniShareName.Length;
4121 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4125 if( pDirNode == NULL)
4128 AFSDeleteObjectInfo( pObjectInfoCB);
4130 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4133 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4134 sizeof( AFSNonPagedDirectoryCB),
4135 AFS_DIR_ENTRY_NP_TAG);
4137 if( pNonPagedDirEntry == NULL)
4140 ExFreePool( pDirNode);
4142 AFSDeleteObjectInfo( pObjectInfoCB);
4144 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4147 RtlZeroMemory( pDirNode,
4150 RtlZeroMemory( pNonPagedDirEntry,
4151 sizeof( AFSNonPagedDirectoryCB));
4153 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4155 pDirNode->NonPaged = pNonPagedDirEntry;
4157 pDirNode->ObjectInformation = pObjectInfoCB;
4163 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
4165 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4167 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4169 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4171 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4172 uniShareName.Buffer,
4173 pDirNode->NameInformation.FileName.Length);
4175 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4178 pLastDirNode->ListEntry.fLink = pDirNode;
4180 pDirNode->ListEntry.bLink = pLastDirNode;
4182 pLastDirNode = pDirNode;
4184 RtlInitUnicodeString( &uniShareName,
4187 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4190 if( pObjectInfoCB == NULL)
4193 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4196 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4197 AFS_TRACE_LEVEL_VERBOSE,
4198 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4201 pObjectInfoCB->ObjectReferenceCount = 1;
4203 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4205 ulEntryLength = sizeof( AFSDirectoryCB) +
4206 uniShareName.Length;
4208 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4212 if( pDirNode == NULL)
4215 AFSDeleteObjectInfo( pObjectInfoCB);
4217 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4220 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4221 sizeof( AFSNonPagedDirectoryCB),
4222 AFS_DIR_ENTRY_NP_TAG);
4224 if( pNonPagedDirEntry == NULL)
4227 ExFreePool( pDirNode);
4229 AFSDeleteObjectInfo( pObjectInfoCB);
4231 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4234 RtlZeroMemory( pDirNode,
4237 RtlZeroMemory( pNonPagedDirEntry,
4238 sizeof( AFSNonPagedDirectoryCB));
4240 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4242 pDirNode->NonPaged = pNonPagedDirEntry;
4244 pDirNode->ObjectInformation = pObjectInfoCB;
4250 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4252 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4254 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4256 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4258 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4259 uniShareName.Buffer,
4260 pDirNode->NameInformation.FileName.Length);
4262 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4265 pLastDirNode->ListEntry.fLink = pDirNode;
4267 pDirNode->ListEntry.bLink = pLastDirNode;
4271 if( !NT_SUCCESS( ntStatus))
4274 if( AFSSpecialShareNames != NULL)
4277 pDirNode = AFSSpecialShareNames;
4279 while( pDirNode != NULL)
4282 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4284 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4286 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4288 ExFreePool( pDirNode->NonPaged);
4290 ExFreePool( pDirNode);
4292 pDirNode = pLastDirNode;
4295 AFSSpecialShareNames = NULL;
4304 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4305 IN UNICODE_STRING *SecondaryName)
4308 AFSDirectoryCB *pDirectoryCB = NULL;
4309 ULONGLONG ullHash = 0;
4310 UNICODE_STRING uniFullShareName;
4316 // Build up the entire name here. We are guaranteed that if there is a
4317 // secondary name, it is pointing to a portion of the share name buffer
4320 if( SecondaryName->Length > 0 &&
4321 SecondaryName->Buffer != NULL)
4324 uniFullShareName = *SecondaryName;
4327 // The calling routine strips off the leading slash so add it back in
4330 uniFullShareName.Buffer--;
4331 uniFullShareName.Length += sizeof( WCHAR);
4332 uniFullShareName.MaximumLength += sizeof( WCHAR);
4335 // And the share name
4338 uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
4339 uniFullShareName.Length += ShareName->Length;
4340 uniFullShareName.MaximumLength += ShareName->Length;
4345 uniFullShareName = *ShareName;
4349 // Generate our hash value
4352 ullHash = AFSGenerateCRC( &uniFullShareName,
4356 // Loop through our special share names to see if this is one of them
4359 pDirectoryCB = AFSSpecialShareNames;
4361 while( pDirectoryCB != NULL)
4364 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4370 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4374 return pDirectoryCB;
4378 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4382 // Block on the queue flush event
4385 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4395 AFSWaitOnQueuedReleases()
4398 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4401 // Block on the queue flush event
4404 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4414 AFSIsEqualFID( IN AFSFileID *FileId1,
4415 IN AFSFileID *FileId2)
4418 BOOLEAN bIsEqual = FALSE;
4420 if( FileId1->Unique == FileId2->Unique &&
4421 FileId1->Vnode == FileId2->Vnode &&
4422 FileId1->Volume == FileId2->Volume &&
4423 FileId1->Cell == FileId2->Cell)
4433 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4436 NTSTATUS ntStatus = STATUS_SUCCESS;
4437 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4442 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4445 // Reset the directory list information
4448 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4450 while( pCurrentDirEntry != NULL)
4453 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4455 if( pCurrentDirEntry->OpenReferenceCount == 0)
4458 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4459 AFS_TRACE_LEVEL_VERBOSE,
4460 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4462 &pCurrentDirEntry->NameInformation.FileName);
4464 AFSDeleteDirEntry( ObjectInfoCB,
4470 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4471 AFS_TRACE_LEVEL_VERBOSE,
4472 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4474 &pCurrentDirEntry->NameInformation.FileName);
4476 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4478 AFSRemoveNameEntry( ObjectInfoCB,
4482 pCurrentDirEntry = pNextDirEntry;
4485 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4487 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4489 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4491 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4493 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4495 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4497 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4498 AFS_TRACE_LEVEL_VERBOSE,
4499 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4500 ObjectInfoCB->FileId.Cell,
4501 ObjectInfoCB->FileId.Volume,
4502 ObjectInfoCB->FileId.Vnode,
4503 ObjectInfoCB->FileId.Unique);
4510 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4513 NTSTATUS ntStatus = STATUS_SUCCESS;
4514 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4515 UNICODE_STRING uniFullName;
4520 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4521 AFS_TRACE_LEVEL_VERBOSE,
4522 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4523 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4524 PsGetCurrentThread());
4526 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4529 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4532 try_return( ntStatus);
4536 // Initialize the root information
4539 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4542 // Enumerate the shares in the volume
4545 ntStatus = AFSEnumerateDirectory( AuthGroup,
4546 &AFSGlobalRoot->ObjectInformation,
4549 if( !NT_SUCCESS( ntStatus))
4552 try_return( ntStatus);
4555 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4558 // Indicate the node is initialized
4561 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4563 uniFullName.MaximumLength = PAGE_SIZE;
4564 uniFullName.Length = 0;
4566 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4567 uniFullName.MaximumLength,
4568 AFS_GENERIC_MEMORY_12_TAG);
4570 if( uniFullName.Buffer == NULL)
4574 // Reset the directory content
4577 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4579 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4581 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4585 // Populate our list of entries in the NP enumeration list
4588 while( pDirGlobalDirNode != NULL)
4591 uniFullName.Buffer[ 0] = L'\\';
4592 uniFullName.Buffer[ 1] = L'\\';
4594 uniFullName.Length = 2 * sizeof( WCHAR);
4596 RtlCopyMemory( &uniFullName.Buffer[ 2],
4597 AFSServerName.Buffer,
4598 AFSServerName.Length);
4600 uniFullName.Length += AFSServerName.Length;
4602 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4604 uniFullName.Length += sizeof( WCHAR);
4606 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4607 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4608 pDirGlobalDirNode->NameInformation.FileName.Length);
4610 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4612 AFSAddConnectionEx( &uniFullName,
4613 RESOURCEDISPLAYTYPE_SHARE,
4616 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4619 AFSExFreePool( uniFullName.Buffer);
4623 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4630 AFSIsRelativeName( IN UNICODE_STRING *Name)
4633 BOOLEAN bIsRelative = FALSE;
4635 if( Name->Buffer[ 0] != L'\\')
4645 AFSUpdateName( IN UNICODE_STRING *Name)
4650 while( usIndex < Name->Length/sizeof( WCHAR))
4653 if( Name->Buffer[ usIndex] == L'/')
4656 Name->Buffer[ usIndex] = L'\\';
4666 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4667 IN OUT ULONG *Flags,
4668 IN WCHAR *NameBuffer,
4669 IN USHORT NameLength)
4672 NTSTATUS ntStatus = STATUS_SUCCESS;
4673 WCHAR *pTmpBuffer = NULL;
4679 // If we have enough space then just move in the name otherwise
4680 // allocate a new buffer
4683 if( TargetName->Length < NameLength)
4686 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4688 AFS_NAME_BUFFER_FIVE_TAG);
4690 if( pTmpBuffer == NULL)
4693 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4696 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4699 AFSExFreePool( TargetName->Buffer);
4702 TargetName->MaximumLength = NameLength;
4704 TargetName->Buffer = pTmpBuffer;
4706 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4709 TargetName->Length = NameLength;
4711 RtlCopyMemory( TargetName->Buffer,
4713 TargetName->Length);
4716 // Update the name in the buffer
4719 AFSUpdateName( TargetName);
4730 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4731 IN ULONG InitialElementCount)
4734 AFSNameArrayHdr *pNameArray = NULL;
4735 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4740 if( InitialElementCount == 0)
4743 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
4746 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
4747 sizeof( AFSNameArrayHdr) +
4748 (InitialElementCount * sizeof( AFSNameArrayCB)),
4749 AFS_NAME_ARRAY_TAG);
4751 if( pNameArray == NULL)
4754 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4755 AFS_TRACE_LEVEL_ERROR,
4756 "AFSInitNameArray Failed to allocate name array\n");
4758 try_return( pNameArray);
4761 RtlZeroMemory( pNameArray,
4762 sizeof( AFSNameArrayHdr) +
4763 (InitialElementCount * sizeof( AFSNameArrayCB)));
4765 pNameArray->MaxElementCount = InitialElementCount;
4767 if( DirectoryCB != NULL)
4770 pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
4772 InterlockedIncrement( &pNameArray->Count);
4774 InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
4776 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4777 AFS_TRACE_LEVEL_VERBOSE,
4778 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
4779 &DirectoryCB->NameInformation.FileName,
4781 DirectoryCB->OpenReferenceCount);
4783 pNameArray->CurrentEntry->DirectoryCB = DirectoryCB;
4785 pNameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
4787 pNameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
4799 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
4800 IN UNICODE_STRING *Path,
4801 IN AFSDirectoryCB *DirectoryCB)
4804 NTSTATUS ntStatus = STATUS_SUCCESS;
4805 AFSNameArrayCB *pCurrentElement = NULL;
4806 UNICODE_STRING uniComponentName, uniRemainingPath;
4807 AFSObjectInfoCB *pCurrentObject = NULL;
4808 ULONG ulTotalCount = 0;
4810 USHORT usLength = 0;
4816 // Init some info in the header
4819 pCurrentElement = &NameArray->ElementArray[ 0];
4821 NameArray->CurrentEntry = pCurrentElement;
4824 // The first entry points at the root
4827 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
4829 InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4831 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4832 AFS_TRACE_LEVEL_VERBOSE,
4833 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
4834 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4835 pCurrentElement->DirectoryCB,
4836 pCurrentElement->DirectoryCB->OpenReferenceCount);
4838 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
4840 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
4842 NameArray->Count = 1;
4844 NameArray->LinkCount = 0;
4847 // If the root is the parent then we are done ...
4850 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
4852 try_return( ntStatus);
4864 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
4865 IN AFSNameArrayHdr *RelatedNameArray,
4866 IN AFSDirectoryCB *DirectoryCB)
4869 NTSTATUS ntStatus = STATUS_SUCCESS;
4870 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
4871 UNICODE_STRING uniComponentName, uniRemainingPath;
4872 AFSObjectInfoCB *pObjectInfo = NULL;
4873 ULONG ulTotalCount = 0;
4875 USHORT usLength = 0;
4881 // Init some info in the header
4884 pCurrentElement = &NameArray->ElementArray[ 0];
4886 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
4888 NameArray->Count = 0;
4890 NameArray->LinkCount = RelatedNameArray->LinkCount;
4893 // Populate the name array with the data from the related array
4899 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
4901 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
4903 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
4905 InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4907 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4908 AFS_TRACE_LEVEL_VERBOSE,
4909 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
4910 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4911 pCurrentElement->DirectoryCB,
4912 pCurrentElement->DirectoryCB->OpenReferenceCount);
4914 InterlockedIncrement( &NameArray->Count);
4916 if( pCurrentElement->DirectoryCB == DirectoryCB ||
4917 NameArray->Count == RelatedNameArray->Count)
4929 pCurrentRelatedElement++;
4932 if( NameArray->Count > 0)
4934 NameArray->CurrentEntry = pCurrentElement;
4942 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
4945 NTSTATUS ntStatus = STATUS_SUCCESS;
4946 AFSNameArrayCB *pCurrentElement = NULL;
4951 pCurrentElement = &NameArray->ElementArray[ 0];
4956 if( pCurrentElement->DirectoryCB == NULL)
4962 InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4964 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4965 AFS_TRACE_LEVEL_VERBOSE,
4966 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
4967 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4968 pCurrentElement->DirectoryCB,
4969 pCurrentElement->DirectoryCB->OpenReferenceCount);
4974 AFSExFreePool( NameArray);
4981 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
4982 IN AFSDirectoryCB *DirEntry)
4985 NTSTATUS ntStatus = STATUS_SUCCESS;
4986 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4991 if( NameArray->Count == NameArray->MaxElementCount)
4994 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4997 if( NameArray->CurrentEntry != NULL &&
4998 NameArray->CurrentEntry->DirectoryCB == DirEntry)
5001 try_return( ntStatus);
5004 if( NameArray->Count > 0)
5007 NameArray->CurrentEntry++;
5011 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5014 InterlockedIncrement( &NameArray->Count);
5016 InterlockedIncrement( &DirEntry->OpenReferenceCount);
5018 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5019 AFS_TRACE_LEVEL_VERBOSE,
5020 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
5021 &DirEntry->NameInformation.FileName,
5023 DirEntry->OpenReferenceCount);
5025 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5027 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5029 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5040 AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
5041 IN AFSDirectoryCB *DirectoryCB)
5044 ASSERT( NameArray->CurrentEntry != NULL);
5046 InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5048 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5049 AFS_TRACE_LEVEL_VERBOSE,
5050 "AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
5051 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5052 NameArray->CurrentEntry->DirectoryCB,
5053 NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5055 InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5057 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5058 AFS_TRACE_LEVEL_VERBOSE,
5059 "AFSReplaceCurrentElement Increment count on %wZ DE %p Cnt %d\n",
5060 &DirectoryCB->NameInformation.FileName,
5062 DirectoryCB->OpenReferenceCount);
5064 NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
5066 NameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
5068 NameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
5070 if( DirectoryCB->ObjectInformation->ParentObjectInformation == NULL)
5073 SetFlag( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5080 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5083 AFSDirectoryCB *pCurrentDirEntry = NULL;
5088 if( NameArray->Count == 0)
5090 try_return( pCurrentDirEntry);
5093 InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5095 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5096 AFS_TRACE_LEVEL_VERBOSE,
5097 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5098 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5099 NameArray->CurrentEntry->DirectoryCB,
5100 NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5102 NameArray->CurrentEntry->DirectoryCB = NULL;
5104 if( InterlockedDecrement( &NameArray->Count) == 0)
5106 NameArray->CurrentEntry = NULL;
5110 NameArray->CurrentEntry--;
5111 pCurrentDirEntry = NameArray->CurrentEntry->DirectoryCB;
5119 return pCurrentDirEntry;
5123 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5126 AFSDirectoryCB *pDirEntry = NULL;
5127 AFSNameArrayCB *pElement = NULL;
5132 if( NameArray->Count == 0 ||
5133 NameArray->Count == 1)
5136 try_return( pDirEntry = NULL);
5139 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5141 pDirEntry = pElement->DirectoryCB;
5152 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5153 IN AFSDirectoryCB *DirEntry)
5156 AFSNameArrayCB *pCurrentElement = NULL;
5157 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5162 pCurrentElement = &NameArray->ElementArray[ 0];
5167 if( pCurrentElement->DirectoryCB == NULL)
5173 InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5175 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5176 AFS_TRACE_LEVEL_VERBOSE,
5177 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5178 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5179 pCurrentElement->DirectoryCB,
5180 pCurrentElement->DirectoryCB->OpenReferenceCount);
5185 RtlZeroMemory( NameArray,
5186 sizeof( AFSNameArrayHdr) +
5187 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5189 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5191 if( DirEntry != NULL)
5194 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5196 InterlockedIncrement( &NameArray->Count);
5198 InterlockedIncrement( &DirEntry->OpenReferenceCount);
5200 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5201 AFS_TRACE_LEVEL_VERBOSE,
5202 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5203 &DirEntry->NameInformation.FileName,
5205 DirEntry->OpenReferenceCount);
5207 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5209 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5211 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5219 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5222 AFSNameArrayCB *pCurrentElement = NULL;
5224 pCurrentElement = &NameArray->ElementArray[ 0];
5226 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5228 while( pCurrentElement->DirectoryCB != NULL)
5231 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5232 pCurrentElement->FileId.Cell,
5233 pCurrentElement->FileId.Volume,
5234 pCurrentElement->FileId.Vnode,
5235 pCurrentElement->FileId.Unique,
5236 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5241 AFSPrint("AFSDumpNameArray End\n\n");
5247 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5251 // Depending on the type of node, set the event
5254 switch( Fcb->Header.NodeTypeCode)
5257 case AFS_DIRECTORY_FCB:
5260 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5264 InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5273 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5277 InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5287 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5291 // Depending on the type of node, set the event
5294 switch( Fcb->Header.NodeTypeCode)
5297 case AFS_DIRECTORY_FCB:
5300 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5302 if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
5305 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5315 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5317 if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
5320 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5331 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5334 BOOLEAN bIsInProcess = FALSE;
5339 if( ObjectInfo->Fcb == NULL)
5342 try_return( bIsInProcess);
5346 // Depending on the type of node, set the event
5349 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5352 case AFS_DIRECTORY_FCB:
5355 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5358 bIsInProcess = TRUE;
5368 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5371 bIsInProcess = TRUE;
5383 return bIsInProcess;
5387 AFSVerifyVolume( IN ULONGLONG ProcessId,
5388 IN AFSVolumeCB *VolumeCB)
5391 NTSTATUS ntStatus = STATUS_SUCCESS;
5398 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5401 NTSTATUS ntStatus = STATUS_SUCCESS;
5402 AFSObjectInfoCB *pObjectInfoCB = NULL;
5403 AFSDirectoryCB *pDirNode = NULL;
5404 ULONG ulEntryLength = 0;
5405 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5410 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5413 if( pObjectInfoCB == NULL)
5416 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5419 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5420 AFS_TRACE_LEVEL_VERBOSE,
5421 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5424 pObjectInfoCB->ObjectReferenceCount = 1;
5426 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5428 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5430 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5432 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5436 if( pDirNode == NULL)
5439 AFSDeleteObjectInfo( pObjectInfoCB);
5441 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5444 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5445 sizeof( AFSNonPagedDirectoryCB),
5446 AFS_DIR_ENTRY_NP_TAG);
5448 if( pNonPagedDirEntry == NULL)
5451 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5454 RtlZeroMemory( pDirNode,
5457 RtlZeroMemory( pNonPagedDirEntry,
5458 sizeof( AFSNonPagedDirectoryCB));
5460 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5462 pDirNode->NonPaged = pNonPagedDirEntry;
5464 pDirNode->ObjectInformation = pObjectInfoCB;
5466 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5472 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5474 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5476 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5478 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5480 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5481 AFSPIOCtlName.Buffer,
5482 pDirNode->NameInformation.FileName.Length);
5484 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5487 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB = pDirNode;
5491 if ( !NT_SUCCESS( ntStatus))
5494 if ( pDirNode != NULL)
5497 AFSExFreePool( pDirNode);
5500 if ( pObjectInfoCB != NULL)
5503 AFSDeleteObjectInfo( pObjectInfoCB);
5512 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5513 IN AFSDirectoryCB *DirectoryCB,
5514 IN UNICODE_STRING *ParentPathName,
5515 IN AFSNameArrayHdr *RelatedNameArray,
5516 OUT AFSFileInfoCB *FileInfo)
5519 NTSTATUS ntStatus = STATUS_SUCCESS;
5520 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
5521 UNICODE_STRING uniFullPathName;
5522 AFSNameArrayHdr *pNameArray = NULL;
5523 AFSVolumeCB *pVolumeCB = NULL;
5524 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5525 WCHAR *pwchBuffer = NULL;
5526 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5527 ULONG ulNameDifference = 0;
5528 GUID *pAuthGroup = NULL;
5534 // Retrieve a target name for the entry
5537 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5540 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5543 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5545 if( ParentDirectoryCB->ObjectInformation->Fcb != NULL)
5547 pAuthGroup = &ParentDirectoryCB->ObjectInformation->Fcb->AuthGroup;
5549 else if( DirectoryCB->ObjectInformation->Fcb != NULL)
5551 pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
5554 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5559 if( !NT_SUCCESS( ntStatus) ||
5560 pDirEntry->TargetNameLength == 0)
5563 if( pDirEntry != NULL)
5566 ntStatus = STATUS_ACCESS_DENIED;
5569 try_return( ntStatus);
5572 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5575 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5579 // Update the target name
5582 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5583 &DirectoryCB->Flags,
5584 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5585 (USHORT)pDirEntry->TargetNameLength);
5587 if( !NT_SUCCESS( ntStatus))
5590 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5592 try_return( ntStatus);
5596 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5600 // Need to pass the full path in for parsing.
5603 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5606 uniFullPathName.Length = 0;
5607 uniFullPathName.MaximumLength = ParentPathName->Length +
5609 DirectoryCB->NameInformation.TargetName.Length;
5611 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5612 uniFullPathName.MaximumLength,
5613 AFS_NAME_BUFFER_SIX_TAG);
5615 if( uniFullPathName.Buffer == NULL)
5618 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5620 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5623 pwchBuffer = uniFullPathName.Buffer;
5625 RtlZeroMemory( uniFullPathName.Buffer,
5626 uniFullPathName.MaximumLength);
5628 RtlCopyMemory( uniFullPathName.Buffer,
5629 ParentPathName->Buffer,
5630 ParentPathName->Length);
5632 uniFullPathName.Length = ParentPathName->Length;
5634 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5635 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5638 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5640 uniFullPathName.Length += sizeof( WCHAR);
5643 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5644 DirectoryCB->NameInformation.TargetName.Buffer,
5645 DirectoryCB->NameInformation.TargetName.Length);
5647 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5649 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5650 uniParsedName.MaximumLength = uniParsedName.Length;
5652 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5654 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5657 // We populate up to the current parent
5660 if( RelatedNameArray != NULL)
5663 pNameArray = AFSInitNameArray( NULL,
5664 RelatedNameArray->MaxElementCount);
5666 if( pNameArray == NULL)
5669 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5672 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5679 pNameArray = AFSInitNameArray( NULL,
5682 if( pNameArray == NULL)
5685 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5688 ntStatus = AFSPopulateNameArray( pNameArray,
5693 if( !NT_SUCCESS( ntStatus))
5696 try_return( ntStatus);
5699 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5701 AFSAcquireShared( pVolumeCB->VolumeLock,
5704 pParentDirEntry = ParentDirectoryCB;
5709 uniFullPathName.Length = 0;
5710 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5712 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5713 uniFullPathName.MaximumLength,
5714 AFS_NAME_BUFFER_SEVEN_TAG);
5716 if( uniFullPathName.Buffer == NULL)
5719 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5721 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5724 pwchBuffer = uniFullPathName.Buffer;
5726 RtlZeroMemory( uniFullPathName.Buffer,
5727 uniFullPathName.MaximumLength);
5729 RtlCopyMemory( uniFullPathName.Buffer,
5730 DirectoryCB->NameInformation.TargetName.Buffer,
5731 DirectoryCB->NameInformation.TargetName.Length);
5733 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5736 // This name should begin with the \afs server so parse it off and check it
5739 FsRtlDissectName( uniFullPathName,
5743 if( RtlCompareUnicodeString( &uniComponentName,
5748 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5750 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5751 AFS_TRACE_LEVEL_ERROR,
5752 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5755 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5758 uniFullPathName = uniRemainingPath;
5760 uniParsedName = uniFullPathName;
5762 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5764 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5770 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5773 if( pNameArray == NULL)
5776 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5779 pVolumeCB = AFSGlobalRoot;
5781 AFSAcquireShared( pVolumeCB->VolumeLock,
5784 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5788 // Increment the ref count on the volume and dir entry for correct processing below
5791 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
5793 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5794 AFS_TRACE_LEVEL_VERBOSE,
5795 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
5797 pVolumeCB->VolumeReferenceCount);
5799 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
5801 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5802 AFS_TRACE_LEVEL_VERBOSE,
5803 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5804 &pParentDirEntry->NameInformation.FileName,
5807 pParentDirEntry->OpenReferenceCount);
5809 ntStatus = AFSLocateNameEntry( NULL,
5814 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5820 if( !NT_SUCCESS( ntStatus))
5824 // The volume lock was released on failure above
5825 // Except for STATUS_OBJECT_NAME_NOT_FOUND
5828 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
5831 if( pVolumeCB != NULL)
5834 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5836 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5837 AFS_TRACE_LEVEL_VERBOSE,
5838 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
5840 pVolumeCB->VolumeReferenceCount);
5842 AFSReleaseResource( pVolumeCB->VolumeLock);
5845 if( pDirectoryEntry != NULL)
5848 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5850 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5851 AFS_TRACE_LEVEL_VERBOSE,
5852 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5853 &pDirectoryEntry->NameInformation.FileName,
5856 pDirectoryEntry->OpenReferenceCount);
5861 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
5863 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5864 AFS_TRACE_LEVEL_VERBOSE,
5865 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5866 &pParentDirEntry->NameInformation.FileName,
5869 pParentDirEntry->OpenReferenceCount);
5875 try_return( ntStatus);
5879 // Store off the information
5882 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5885 // Check for the mount point being returned
5888 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
5891 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5893 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
5894 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5897 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5900 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5902 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5904 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5906 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5908 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5910 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5913 // Remove the reference made above
5916 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5918 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5919 AFS_TRACE_LEVEL_VERBOSE,
5920 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
5921 &pDirectoryEntry->NameInformation.FileName,
5924 pDirectoryEntry->OpenReferenceCount);
5928 if( pDirEntry != NULL)
5931 AFSExFreePool( pDirEntry);
5934 if( pVolumeCB != NULL)
5937 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5939 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5940 AFS_TRACE_LEVEL_VERBOSE,
5941 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
5943 pVolumeCB->VolumeReferenceCount);
5945 AFSReleaseResource( pVolumeCB->VolumeLock);
5948 if( pNameArray != NULL)
5951 AFSFreeNameArray( pNameArray);
5954 if( pwchBuffer != NULL)
5958 // Always free the buffer that we allocated as AFSLocateNameEntry
5959 // will not free it. If uniFullPathName.Buffer was allocated by
5960 // AFSLocateNameEntry, then we must free that as well.
5961 // Check that the uniFullPathName.Buffer in the string is not the same
5962 // offset by the length of the server name
5965 if( uniFullPathName.Length > 0 &&
5966 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
5969 AFSExFreePool( uniFullPathName.Buffer);
5972 AFSExFreePool( pwchBuffer);
5980 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
5981 IN ULONGLONG HashIndex)
5984 NTSTATUS ntStatus = STATUS_SUCCESS;
5985 AFSObjectInfoCB *pObjectInfo = NULL;
5990 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
5991 sizeof( AFSObjectInfoCB),
5992 AFS_OBJECT_INFO_TAG);
5994 if( pObjectInfo == NULL)
5997 try_return( pObjectInfo);
6000 RtlZeroMemory( pObjectInfo,
6001 sizeof( AFSObjectInfoCB));
6003 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6004 sizeof( AFSNonPagedObjectInfoCB),
6005 AFS_NP_OBJECT_INFO_TAG);
6007 if( pObjectInfo->NonPagedInfo == NULL)
6010 AFSExFreePool( pObjectInfo);
6012 try_return( pObjectInfo = NULL);
6015 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6017 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6019 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6021 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6023 if( ParentObjectInfo != NULL)
6025 InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
6029 // Initialize the access time
6032 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6038 // Insert the entry into the object tree and list
6041 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6043 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6046 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6051 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6052 &pObjectInfo->TreeEntry);
6054 ASSERT( NT_SUCCESS( ntStatus));
6058 // And the object list in the volume
6061 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6064 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6069 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6071 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6074 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6077 // Indicate the object is in the hash tree and linked list in the volume
6080 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6092 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6095 BOOLEAN bAcquiredTreeLock = FALSE;
6097 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6100 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6102 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6105 bAcquiredTreeLock = TRUE;
6109 // Remove it from the tree and list if it was inserted
6112 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6115 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6116 &ObjectInfo->TreeEntry);
6119 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6122 if( ObjectInfo->ListEntry.fLink == NULL)
6125 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6127 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6130 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6136 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6139 if( ObjectInfo->ListEntry.bLink == NULL)
6142 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6144 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6147 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6153 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6157 if( ObjectInfo->ParentObjectInformation != NULL)
6159 InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
6162 if( bAcquiredTreeLock)
6165 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6169 // Release the fid in the service
6172 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6175 AFSReleaseFid( &ObjectInfo->FileId);
6178 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6180 AFSExFreePool( ObjectInfo->NonPagedInfo);
6182 AFSExFreePool( ObjectInfo);
6188 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6189 OUT AFSDirectoryCB **TargetDirEntry)
6192 NTSTATUS ntStatus = STATUS_SUCCESS;
6193 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6194 UNICODE_STRING uniFullPathName;
6195 AFSNameArrayHdr *pNameArray = NULL;
6196 AFSVolumeCB *pVolumeCB = NULL;
6197 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6198 WCHAR *pwchBuffer = NULL;
6199 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6200 ULONG ulNameDifference = 0;
6201 GUID *pAuthGroup = NULL;
6207 // Retrieve a target name for the entry
6210 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6213 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6216 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6218 if( DirectoryCB->ObjectInformation->Fcb != NULL)
6220 pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
6223 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6228 if( !NT_SUCCESS( ntStatus) ||
6229 pDirEntry->TargetNameLength == 0)
6232 if( pDirEntry != NULL)
6235 ntStatus = STATUS_ACCESS_DENIED;
6238 try_return( ntStatus);
6241 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6244 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6248 // Update the target name
6251 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6252 &DirectoryCB->Flags,
6253 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6254 (USHORT)pDirEntry->TargetNameLength);
6256 if( !NT_SUCCESS( ntStatus))
6259 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6261 try_return( ntStatus);
6265 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6269 // Need to pass the full path in for parsing.
6272 uniFullPathName.Length = 0;
6273 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6275 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6276 uniFullPathName.MaximumLength,
6277 AFS_NAME_BUFFER_EIGHT_TAG);
6279 if( uniFullPathName.Buffer == NULL)
6282 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6284 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6287 pwchBuffer = uniFullPathName.Buffer;
6289 RtlZeroMemory( uniFullPathName.Buffer,
6290 uniFullPathName.MaximumLength);
6292 RtlCopyMemory( uniFullPathName.Buffer,
6293 DirectoryCB->NameInformation.TargetName.Buffer,
6294 DirectoryCB->NameInformation.TargetName.Length);
6296 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6299 // This name should begin with the \afs server so parse it off and chech it
6302 FsRtlDissectName( uniFullPathName,
6306 if( RtlCompareUnicodeString( &uniComponentName,
6312 // Try evaluating the full path
6315 uniFullPathName.Buffer = pwchBuffer;
6317 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6319 uniFullPathName.MaximumLength = uniFullPathName.Length;
6324 uniFullPathName = uniRemainingPath;
6327 uniParsedName = uniFullPathName;
6329 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6331 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6337 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6340 if( pNameArray == NULL)
6343 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6346 pVolumeCB = AFSGlobalRoot;
6348 AFSAcquireShared( pVolumeCB->VolumeLock,
6351 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6353 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6355 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6356 AFS_TRACE_LEVEL_VERBOSE,
6357 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6359 pVolumeCB->VolumeReferenceCount);
6361 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6363 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6364 AFS_TRACE_LEVEL_VERBOSE,
6365 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6366 &pParentDirEntry->NameInformation.FileName,
6369 pParentDirEntry->OpenReferenceCount);
6371 ntStatus = AFSLocateNameEntry( NULL,
6382 if( !NT_SUCCESS( ntStatus))
6386 // The volume lock was released on failure above
6387 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6390 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6393 if( pVolumeCB != NULL)
6396 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6398 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6399 AFS_TRACE_LEVEL_VERBOSE,
6400 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
6402 pVolumeCB->VolumeReferenceCount);
6404 AFSReleaseResource( pVolumeCB->VolumeLock);
6407 if( pDirectoryEntry != NULL)
6410 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6412 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6413 AFS_TRACE_LEVEL_VERBOSE,
6414 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6415 &pDirectoryEntry->NameInformation.FileName,
6418 pDirectoryEntry->OpenReferenceCount);
6423 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6425 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6426 AFS_TRACE_LEVEL_VERBOSE,
6427 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6428 &pParentDirEntry->NameInformation.FileName,
6431 pParentDirEntry->OpenReferenceCount);
6437 try_return( ntStatus);
6441 // Pass back the target dir entry for this request
6444 *TargetDirEntry = pDirectoryEntry;
6448 if( pDirEntry != NULL)
6451 AFSExFreePool( pDirEntry);
6454 if( pVolumeCB != NULL)
6457 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6459 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6460 AFS_TRACE_LEVEL_VERBOSE,
6461 "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
6463 pVolumeCB->VolumeReferenceCount);
6465 AFSReleaseResource( pVolumeCB->VolumeLock);
6468 if( pNameArray != NULL)
6471 AFSFreeNameArray( pNameArray);
6474 if( pwchBuffer != NULL)
6478 // Always free the buffer that we allocated as AFSLocateNameEntry
6479 // will not free it. If uniFullPathName.Buffer was allocated by
6480 // AFSLocateNameEntry, then we must free that as well.
6481 // Check that the uniFullPathName.Buffer in the string is not the same
6482 // offset by the length of the server name
6485 if( uniFullPathName.Length > 0 &&
6486 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6489 AFSExFreePool( uniFullPathName.Buffer);
6492 AFSExFreePool( pwchBuffer);
6500 AFSCleanupFcb( IN AFSFcb *Fcb,
6501 IN BOOLEAN ForceFlush)
6504 NTSTATUS ntStatus = STATUS_SUCCESS;
6505 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6506 LARGE_INTEGER liTime;
6507 IO_STATUS_BLOCK stIoStatus;
6512 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6514 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6516 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6519 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6520 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6523 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6526 if( Fcb->OpenReferenceCount > 0)
6532 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6537 if( !NT_SUCCESS( stIoStatus.Status))
6540 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6541 AFS_TRACE_LEVEL_ERROR,
6542 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6543 Fcb->ObjectInformation->FileId.Cell,
6544 Fcb->ObjectInformation->FileId.Volume,
6545 Fcb->ObjectInformation->FileId.Vnode,
6546 Fcb->ObjectInformation->FileId.Unique,
6548 stIoStatus.Information);
6550 ntStatus = stIoStatus.Status;
6553 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6558 __except( EXCEPTION_EXECUTE_HANDLER)
6560 ntStatus = GetExceptionCode();
6564 AFSReleaseResource( &Fcb->NPFcb->Resource);
6567 // Wait for any currently running flush or release requests to complete
6570 AFSWaitOnQueuedFlushes( Fcb);
6573 // Now perform another flush on the file
6576 if( !NT_SUCCESS( AFSFlushExtents( Fcb)))
6579 AFSReleaseExtentsWithFlush( Fcb);
6583 if( Fcb->OpenReferenceCount == 0 ||
6584 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6585 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6588 AFSTearDownFcbExtents( Fcb);
6591 try_return( ntStatus);
6594 KeQueryTickCount( &liTime);
6597 // First up are there dirty extents in the cache to flush?
6601 ( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6602 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
6603 ( Fcb->Specific.File.ExtentsDirtyCount ||
6604 Fcb->Specific.File.ExtentCount) &&
6605 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6606 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6609 if( !NT_SUCCESS( AFSFlushExtents( Fcb)) &&
6610 Fcb->OpenReferenceCount == 0)
6613 AFSReleaseExtentsWithFlush( Fcb);
6616 else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6617 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6621 // The file has been marked as invalid. Dump it
6624 AFSTearDownFcbExtents( Fcb);
6628 // If there are extents and they haven't been used recently *and*
6629 // are not being used
6633 ( 0 != Fcb->Specific.File.ExtentCount &&
6634 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6635 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6636 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
6637 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6644 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6649 if( !NT_SUCCESS( stIoStatus.Status))
6652 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6653 AFS_TRACE_LEVEL_ERROR,
6654 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6655 Fcb->ObjectInformation->FileId.Cell,
6656 Fcb->ObjectInformation->FileId.Volume,
6657 Fcb->ObjectInformation->FileId.Vnode,
6658 Fcb->ObjectInformation->FileId.Unique,
6660 stIoStatus.Information);
6662 ntStatus = stIoStatus.Status;
6668 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6674 __except( EXCEPTION_EXECUTE_HANDLER)
6676 ntStatus = GetExceptionCode();
6679 AFSReleaseResource( &Fcb->NPFcb->Resource);
6681 if( Fcb->OpenReferenceCount == 0)
6685 // Tear em down we'll not be needing them again
6688 AFSTearDownFcbExtents( Fcb);
6701 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
6702 IN UNICODE_STRING *NewFileName)
6705 NTSTATUS ntStatus = STATUS_SUCCESS;
6706 WCHAR *pTmpBuffer = NULL;
6711 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
6714 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
6717 AFSExFreePool( DirectoryCB->NameInformation.FileName.Buffer);
6719 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6721 DirectoryCB->NameInformation.FileName.Buffer = NULL;
6725 // OK, we need to allocate a new name buffer
6728 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6729 NewFileName->Length,
6730 AFS_NAME_BUFFER_NINE_TAG);
6732 if( pTmpBuffer == NULL)
6735 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6738 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
6740 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
6742 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6745 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
6747 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
6748 NewFileName->Buffer,
6749 NewFileName->Length);
6760 AFSReadCacheFile( IN void *ReadBuffer,
6761 IN LARGE_INTEGER *ReadOffset,
6762 IN ULONG RequestedDataLength,
6763 IN OUT PULONG BytesRead)
6766 NTSTATUS ntStatus = STATUS_SUCCESS;
6769 PIO_STACK_LOCATION pIoStackLocation = NULL;
6770 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6771 DEVICE_OBJECT *pTargetDeviceObject = NULL;
6772 FILE_OBJECT *pCacheFileObject = NULL;
6777 pCacheFileObject = AFSReferenceCacheFileObject();
6779 if( pCacheFileObject == NULL)
6781 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
6784 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
6787 // Initialize the event
6790 KeInitializeEvent( &kEvent,
6791 SynchronizationEvent,
6795 // Allocate an irp for this request. This could also come from a
6796 // private pool, for instance.
6799 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
6805 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6809 // Build the IRP's main body
6812 pIrp->UserBuffer = ReadBuffer;
6814 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
6815 pIrp->RequestorMode = KernelMode;
6816 pIrp->Flags |= IRP_READ_OPERATION;
6819 // Set up the I/O stack location.
6822 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
6823 pIoStackLocation->MajorFunction = IRP_MJ_READ;
6824 pIoStackLocation->DeviceObject = pTargetDeviceObject;
6825 pIoStackLocation->FileObject = pCacheFileObject;
6826 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
6828 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
6831 // Set the completion routine.
6834 IoSetCompletionRoutine( pIrp,
6842 // Send it to the FSD
6845 ntStatus = IoCallDriver( pTargetDeviceObject,
6848 if( NT_SUCCESS( ntStatus))
6855 ntStatus = KeWaitForSingleObject( &kEvent,
6861 if( NT_SUCCESS( ntStatus))
6864 ntStatus = pIrp->IoStatus.Status;
6866 *BytesRead = (ULONG)pIrp->IoStatus.Information;
6872 if( pCacheFileObject != NULL)
6874 AFSReleaseCacheFileObject( pCacheFileObject);
6880 if( pIrp->MdlAddress != NULL)
6883 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
6886 MmUnlockPages( pIrp->MdlAddress);
6889 IoFreeMdl( pIrp->MdlAddress);
6892 pIrp->MdlAddress = NULL;
6906 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
6911 KEVENT *pEvent = (KEVENT *)Context;
6917 return STATUS_MORE_PROCESSING_REQUIRED;
6921 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
6924 BOOLEAN bIsEmpty = FALSE;
6925 AFSDirectoryCB *pDirEntry = NULL;
6930 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
6935 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
6938 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
6940 while( pDirEntry != NULL)
6943 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
6944 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
6952 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
6957 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
6964 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
6965 IN AFSDirectoryCB *DirEntry)
6968 NTSTATUS ntStatus = STATUS_SUCCESS;
6973 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
6976 try_return( ntStatus);
6979 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
6982 // Remove the entry from the parent tree
6985 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
6988 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
6991 if( ParentObjectInfo->Specific.Directory.ShortNameTree &&
6992 DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
6996 // From the short name tree
6999 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7003 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7014 AFSGetAuthenticationId()
7017 LARGE_INTEGER liAuthId = {0,0};
7018 NTSTATUS ntStatus = STATUS_SUCCESS;
7019 PACCESS_TOKEN hToken = NULL;
7020 PTOKEN_STATISTICS pTokenInfo = NULL;
7021 BOOLEAN bCopyOnOpen = FALSE;
7022 BOOLEAN bEffectiveOnly = FALSE;
7023 BOOLEAN bPrimaryToken = FALSE;
7024 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7029 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7032 &stImpersonationLevel);
7037 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7042 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7043 AFS_TRACE_LEVEL_ERROR,
7044 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7046 try_return( ntStatus);
7049 bPrimaryToken = TRUE;
7052 ntStatus = SeQueryInformationToken( hToken,
7054 (PVOID *)&pTokenInfo);
7056 if( !NT_SUCCESS( ntStatus))
7059 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7060 AFS_TRACE_LEVEL_ERROR,
7061 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7063 try_return( ntStatus);
7066 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7067 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7069 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7070 AFS_TRACE_LEVEL_VERBOSE,
7071 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7082 PsDereferenceImpersonationToken( hToken);
7087 PsDereferencePrimaryToken( hToken);
7091 if( pTokenInfo != NULL)
7094 AFSExFreePool( pTokenInfo);
7102 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7106 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7108 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7111 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7113 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7116 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7118 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7121 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7123 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7126 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7128 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7135 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7138 BOOLEAN bIsValid = TRUE;
7140 AFSDirectoryCB *pCurrentDirEntry = NULL;
7142 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7144 while( pCurrentDirEntry != NULL)
7147 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7152 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7155 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7158 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7160 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7162 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7171 AFSReferenceCacheFileObject()
7174 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7175 FILE_OBJECT *pCacheFileObject = NULL;
7177 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7180 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7182 if( pCacheFileObject != NULL)
7184 ObReferenceObject( pCacheFileObject);
7187 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7189 return pCacheFileObject;
7193 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7196 ASSERT( CacheFileObject != NULL);
7198 ObDereferenceObject( CacheFileObject);
7204 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7207 NTSTATUS ntStatus = STATUS_SUCCESS;
7208 AFSDeviceExt *pControlDevExt = NULL;
7209 ULONG ulTimeIncrement = 0;
7214 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7216 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7218 AFSServerName = LibraryInit->AFSServerName;
7220 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7223 // Callbacks in the framework
7226 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7228 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7230 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7232 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7234 AFSExFreePool = LibraryInit->AFSExFreePool;
7236 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7238 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7240 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7242 if( LibraryInit->AFSCacheBaseAddress != NULL)
7245 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7247 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7249 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7253 // Initialize some flush parameters
7256 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7258 ulTimeIncrement = KeQueryTimeIncrement();
7260 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7261 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_ONE_SECOND;
7262 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart *= AFS_SERVER_PURGE_DELAY;
7263 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7264 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)(AFS_ONE_SECOND * AFS_SERVER_FLUSH_DELAY) / (ULONGLONG)ulTimeIncrement);
7265 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7268 // Initialize the global root entry
7271 ntStatus = AFSInitVolume( NULL,
7272 &LibraryInit->GlobalRootFid,
7275 if( !NT_SUCCESS( ntStatus))
7278 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7279 AFS_TRACE_LEVEL_ERROR,
7280 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7283 try_return( ntStatus);
7286 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7289 if( !NT_SUCCESS( ntStatus))
7292 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7293 AFS_TRACE_LEVEL_ERROR,
7294 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7297 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7299 try_return( ntStatus);
7303 // Update the node type code to AFS_ROOT_ALL
7306 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7308 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7311 // Drop the locks acquired above
7314 AFSInitVolumeWorker( AFSGlobalRoot);
7316 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7318 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7332 NTSTATUS ntStatus = STATUS_SUCCESS;
7333 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7338 if( AFSGlobalDotDirEntry != NULL)
7341 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
7343 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7345 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7347 ExFreePool( AFSGlobalDotDirEntry);
7349 AFSGlobalDotDirEntry = NULL;
7352 if( AFSGlobalDotDotDirEntry != NULL)
7355 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
7357 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7359 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7361 ExFreePool( AFSGlobalDotDotDirEntry);
7363 AFSGlobalDotDotDirEntry = NULL;
7366 if( AFSSpecialShareNames != NULL)
7369 pDirNode = AFSSpecialShareNames;
7371 while( pDirNode != NULL)
7374 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7376 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
7378 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7380 ExFreePool( pDirNode->NonPaged);
7382 ExFreePool( pDirNode);
7384 pDirNode = pLastDirNode;
7387 AFSSpecialShareNames = NULL;
7395 AFSDefaultLogMsg( IN ULONG Subsystem,
7401 NTSTATUS ntStatus = STATUS_SUCCESS;
7403 char chDebugBuffer[ 256];
7408 va_start( va_args, Format);
7410 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7415 if( NT_SUCCESS( ntStatus))
7417 DbgPrint( chDebugBuffer);
7427 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7428 IN ULONG InputBufferLength,
7429 IN AFSStatusInfoCB *StatusInfo,
7430 OUT ULONG *ReturnLength)
7433 NTSTATUS ntStatus = STATUS_SUCCESS;
7434 AFSFcb *pFcb = NULL;
7435 AFSVolumeCB *pVolumeCB = NULL;
7436 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7437 AFSObjectInfoCB *pObjectInfo = NULL;
7438 ULONGLONG ullIndex = 0;
7439 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7440 AFSNameArrayHdr *pNameArray = NULL;
7441 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7447 // If we are given a FID then look up the entry by that, otherwise
7451 if( GetStatusInfo->FileID.Cell != 0 &&
7452 GetStatusInfo->FileID.Volume != 0 &&
7453 GetStatusInfo->FileID.Vnode != 0 &&
7454 GetStatusInfo->FileID.Unique != 0)
7457 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7460 // Locate the volume node
7463 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7465 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7467 (AFSBTreeEntry **)&pVolumeCB);
7469 if( pVolumeCB != NULL)
7472 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7474 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7475 AFS_TRACE_LEVEL_VERBOSE,
7476 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7478 pVolumeCB->VolumeReferenceCount);
7481 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7483 if( !NT_SUCCESS( ntStatus) ||
7486 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7489 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
7492 pObjectInfo = &pVolumeCB->ObjectInformation;
7494 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7496 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7501 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
7504 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7506 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7507 AFS_TRACE_LEVEL_VERBOSE,
7508 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7510 pVolumeCB->VolumeReferenceCount);
7512 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
7514 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
7516 (AFSBTreeEntry **)&pObjectInfo);
7518 if( pObjectInfo != NULL)
7522 // Reference the node so it won't be torn down
7525 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7527 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7528 AFS_TRACE_LEVEL_VERBOSE,
7529 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
7531 pObjectInfo->ObjectReferenceCount);
7534 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
7536 if( !NT_SUCCESS( ntStatus) ||
7537 pObjectInfo == NULL)
7539 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7546 if( GetStatusInfo->FileNameLength == 0 ||
7547 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
7549 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7552 uniFullPathName.Length = GetStatusInfo->FileNameLength;
7553 uniFullPathName.MaximumLength = uniFullPathName.Length;
7555 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
7558 // This name should begin with the \afs server so parse it off and check it
7561 FsRtlDissectName( uniFullPathName,
7565 if( RtlCompareUnicodeString( &uniComponentName,
7569 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7570 AFS_TRACE_LEVEL_ERROR,
7571 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
7574 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
7577 uniFullPathName = uniRemainingPath;
7579 uniParsedName = uniFullPathName;
7585 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7588 if( pNameArray == NULL)
7590 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7593 pVolumeCB = AFSGlobalRoot;
7595 AFSAcquireShared( pVolumeCB->VolumeLock,
7598 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7601 // Increment the ref count on the volume and dir entry for correct processing below
7604 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7606 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7607 AFS_TRACE_LEVEL_VERBOSE,
7608 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7610 pVolumeCB->VolumeReferenceCount);
7612 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
7614 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7615 AFS_TRACE_LEVEL_VERBOSE,
7616 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7617 &pParentDirEntry->NameInformation.FileName,
7620 pParentDirEntry->OpenReferenceCount);
7622 ntStatus = AFSLocateNameEntry( NULL,
7627 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
7628 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
7634 if( !NT_SUCCESS( ntStatus))
7638 // The volume lock was released on failure above
7639 // Except for STATUS_OBJECT_NAME_NOT_FOUND
7642 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
7645 if( pVolumeCB != NULL)
7648 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7650 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7651 AFS_TRACE_LEVEL_VERBOSE,
7652 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7654 pVolumeCB->VolumeReferenceCount);
7656 AFSReleaseResource( pVolumeCB->VolumeLock);
7659 if( pDirectoryEntry != NULL)
7662 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7664 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7665 AFS_TRACE_LEVEL_VERBOSE,
7666 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7667 &pDirectoryEntry->NameInformation.FileName,
7670 pDirectoryEntry->OpenReferenceCount);
7675 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
7677 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7678 AFS_TRACE_LEVEL_VERBOSE,
7679 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7680 &pParentDirEntry->NameInformation.FileName,
7683 pParentDirEntry->OpenReferenceCount);
7689 try_return( ntStatus);
7693 // Remove the reference made above
7696 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7698 pObjectInfo = pDirectoryEntry->ObjectInformation;
7700 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7702 if( pVolumeCB != NULL)
7705 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7707 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7708 AFS_TRACE_LEVEL_VERBOSE,
7709 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
7711 pVolumeCB->VolumeReferenceCount);
7713 AFSReleaseResource( pVolumeCB->VolumeLock);
7718 // At this point we have an object info block, return the information
7721 StatusInfo->FileId = pObjectInfo->FileId;
7723 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
7725 StatusInfo->Expiration = pObjectInfo->Expiration;
7727 StatusInfo->DataVersion = pObjectInfo->DataVersion;
7729 StatusInfo->FileType = pObjectInfo->FileType;
7731 StatusInfo->ObjectFlags = pObjectInfo->Flags;
7733 StatusInfo->CreationTime = pObjectInfo->CreationTime;
7735 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
7737 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
7739 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
7741 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
7743 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
7745 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
7747 StatusInfo->EaSize = pObjectInfo->EaSize;
7749 StatusInfo->Links = pObjectInfo->Links;
7752 // Return the information length
7755 *ReturnLength = sizeof( AFSStatusInfoCB);
7759 if( pObjectInfo != NULL)
7762 InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
7765 if( pNameArray != NULL)
7768 AFSFreeNameArray( pNameArray);
7776 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
7777 IN UNICODE_STRING *ComponentName)
7780 NTSTATUS ntStatus = STATUS_SUCCESS;
7781 AFSDirectoryCB *pDirEntry = NULL;
7788 // Search for the entry in the parent
7791 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7792 AFS_TRACE_LEVEL_VERBOSE_2,
7793 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
7796 ulCRC = AFSGenerateCRC( ComponentName,
7799 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7802 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7806 if( pDirEntry == NULL)
7810 // Missed so perform a case insensitive lookup
7813 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7814 AFS_TRACE_LEVEL_VERBOSE_2,
7815 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
7818 ulCRC = AFSGenerateCRC( ComponentName,
7821 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7825 if( pDirEntry == NULL)
7829 // OK, if this component is a valid short name then try
7830 // a lookup in the short name tree
7833 if( RtlIsNameLegalDOS8Dot3( ComponentName,
7838 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7839 AFS_TRACE_LEVEL_VERBOSE_2,
7840 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
7843 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
7850 if( pDirEntry != NULL)
7852 InterlockedIncrement( &pDirEntry->OpenReferenceCount);
7855 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7857 if( pDirEntry == NULL)
7860 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7861 AFS_TRACE_LEVEL_VERBOSE_2,
7862 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
7865 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
7869 // We have the symlink object but previously failed to process it so return access
7873 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7874 AFS_TRACE_LEVEL_VERBOSE_2,
7875 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ ACCESS_DENIED\n",
7878 ntStatus = STATUS_ACCESS_DENIED;
7880 InterlockedDecrement( &pDirEntry->OpenReferenceCount);
7891 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
7892 OUT UNICODE_STRING *ComponentName)
7895 NTSTATUS ntStatus = STATUS_SUCCESS;
7896 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
7898 uniFullPathName = *FullPathName;
7903 FsRtlDissectName( uniFullPathName,
7907 if( uniRemainingPath.Length == 0)
7912 uniFullPathName = uniRemainingPath;
7915 if( uniComponentName.Length > 0)
7917 *ComponentName = uniComponentName;
7924 AFSDumpTraceFiles_Default()
7930 AFSValidNameFormat( IN UNICODE_STRING *FileName)
7933 BOOLEAN bIsValidName = TRUE;
7939 while( usIndex < FileName->Length/sizeof( WCHAR))
7942 if( FileName->Buffer[ usIndex] == L':' ||
7943 FileName->Buffer[ usIndex] == L'*' ||
7944 FileName->Buffer[ usIndex] == L'?' ||
7945 FileName->Buffer[ usIndex] == L'"' ||
7946 FileName->Buffer[ usIndex] == L'<' ||
7947 FileName->Buffer[ usIndex] == L'>')
7949 bIsValidName = FALSE;
7957 return bIsValidName;
7961 AFSCreateDefaultSecurityDescriptor()
7964 NTSTATUS ntStatus = STATUS_SUCCESS;
7966 ULONG ulSACLSize = 0;
7967 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
7968 ULONG ulACESize = 0;
7969 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
7970 ULONG ulSDLength = 0;
7971 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
7976 if( AFSRtlSetSaclSecurityDescriptor == NULL)
7979 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
7984 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
7986 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
7988 AFS_GENERIC_MEMORY_29_TAG);
7993 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
7995 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7998 RtlZeroMemory( pACE,
8001 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8002 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8003 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8004 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8006 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8008 SeExports->SeLowMandatorySid);
8010 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8011 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8013 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8015 AFS_GENERIC_MEMORY_29_TAG);
8020 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8022 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8025 ntStatus = RtlCreateAcl( pSACL,
8029 if( !NT_SUCCESS( ntStatus))
8032 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8035 try_return( ntStatus);
8038 ntStatus = RtlAddAce( pSACL,
8042 pACE->Header.AceSize);
8044 if( !NT_SUCCESS( ntStatus))
8047 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8050 try_return( ntStatus);
8054 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8055 sizeof( SECURITY_DESCRIPTOR),
8056 AFS_GENERIC_MEMORY_27_TAG);
8058 if( pSecurityDescr == NULL)
8061 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8063 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8066 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8067 SECURITY_DESCRIPTOR_REVISION);
8069 if( !NT_SUCCESS( ntStatus))
8072 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8075 try_return( ntStatus);
8078 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8080 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8085 if( !NT_SUCCESS( ntStatus))
8088 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8091 try_return( ntStatus);
8095 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8098 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8100 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8103 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8105 AFS_GENERIC_MEMORY_27_TAG);
8107 if( pRelativeSecurityDescr == NULL)
8110 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8112 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8115 ulSDLength = PAGE_SIZE;
8117 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8118 pRelativeSecurityDescr,
8121 if( !NT_SUCCESS( ntStatus))
8124 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8127 try_return( ntStatus);
8130 AFSDefaultSD = pRelativeSecurityDescr;
8134 if( !NT_SUCCESS( ntStatus))
8137 if( pRelativeSecurityDescr != NULL)
8139 ExFreePool( pRelativeSecurityDescr);
8143 if( pSecurityDescr != NULL)
8145 ExFreePool( pSecurityDescr);