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_FILE_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 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1132 AFS_TRACE_LEVEL_VERBOSE,
1133 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1136 ParentObjectInfo->FileId.Cell,
1137 ParentObjectInfo->FileId.Volume,
1138 ParentObjectInfo->FileId.Vnode,
1139 ParentObjectInfo->FileId.Unique);
1141 if( TargetName != NULL &&
1142 TargetName->Length > 0)
1145 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1147 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1149 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1150 sizeof( AFSDirectoryCB) +
1151 pDirNode->NameInformation.FileName.Length);
1153 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1155 pDirNode->NameInformation.TargetName.Length);
1159 // If we allocated the object information cb then update the information
1162 if( bAllocatedObjectCB)
1166 // Populate the rest of the data
1169 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1171 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1173 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1175 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1177 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1179 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1181 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1183 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1185 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1187 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1189 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1190 pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1191 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1194 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1197 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1200 // Object specific information
1203 pObjectInfoCB->Links = DirEnumEntry->Links;
1205 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1207 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1210 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1211 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1215 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1216 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1217 pObjectInfoCB->TargetFileId.Unique == 0 &&
1218 pDirNode->NameInformation.TargetName.Length == 0)
1222 // This will ensure we perform a validation on the node
1225 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1228 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1231 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1237 if( !NT_SUCCESS( ntStatus))
1240 if( pNonPagedDirEntry != NULL)
1243 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1245 AFSExFreePool( pNonPagedDirEntry);
1248 if( pDirNode != NULL)
1251 AFSExFreePool( pDirNode);
1257 // Dereference our object info block if we have one
1260 if( pObjectInfoCB != NULL)
1263 InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
1265 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1266 AFS_TRACE_LEVEL_VERBOSE,
1267 "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
1269 pObjectInfoCB->ObjectReferenceCount);
1271 if( bAllocatedObjectCB)
1274 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1276 AFSDeleteObjectInfo( pObjectInfoCB);
1286 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1287 IN BOOLEAN DirectoryEntry)
1290 BOOLEAN bReturn = TRUE;
1291 ACCESS_MASK stAccessMask = 0;
1294 // Get rid of anything we don't know about
1297 DesiredAccess = (DesiredAccess &
1303 ACCESS_SYSTEM_SECURITY |
1307 FILE_READ_ATTRIBUTES |
1308 FILE_WRITE_ATTRIBUTES |
1309 FILE_LIST_DIRECTORY |
1315 // Our 'read only' access mask. These are the accesses we will
1316 // allow for a read only file
1319 stAccessMask = DELETE |
1324 ACCESS_SYSTEM_SECURITY |
1328 FILE_READ_ATTRIBUTES |
1329 FILE_WRITE_ATTRIBUTES |
1331 FILE_LIST_DIRECTORY |
1335 // For a directory, add in the directory specific accesses
1341 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1346 if( FlagOn( DesiredAccess, ~stAccessMask))
1350 // A write access is set ...
1360 AFSEvaluateNode( IN GUID *AuthGroup,
1361 IN AFSDirectoryCB *DirEntry)
1364 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1365 NTSTATUS ntStatus = STATUS_SUCCESS;
1366 AFSDirEnumEntry *pDirEntry = NULL;
1367 UNICODE_STRING uniTargetName;
1372 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1377 if( !NT_SUCCESS( ntStatus))
1380 try_return( ntStatus);
1383 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1385 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1387 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1389 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1391 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1393 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1395 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1397 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1399 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1401 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1403 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1405 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1406 pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1407 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1410 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1413 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1415 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1418 // If we have a target name then see if it needs updating ...
1421 if( pDirEntry->TargetNameLength > 0)
1425 // Update the target name information if needed
1428 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1430 uniTargetName.MaximumLength = uniTargetName.Length;
1432 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1434 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1437 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1438 RtlCompareUnicodeString( &uniTargetName,
1439 &DirEntry->NameInformation.TargetName,
1444 // Update the target name
1447 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1449 uniTargetName.Buffer,
1450 uniTargetName.Length);
1452 if( !NT_SUCCESS( ntStatus))
1455 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1457 try_return( ntStatus);
1461 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1466 if( pDirEntry != NULL)
1469 AFSExFreePool( pDirEntry);
1477 AFSValidateSymLink( IN GUID *AuthGroup,
1478 IN AFSDirectoryCB *DirEntry)
1481 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1482 NTSTATUS ntStatus = STATUS_SUCCESS;
1483 AFSDirEnumEntry *pDirEntry = NULL;
1484 UNICODE_STRING uniTargetName;
1489 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1494 if( !NT_SUCCESS( ntStatus))
1497 try_return( ntStatus);
1500 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1501 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1504 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1507 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1509 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1511 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1514 // Update the target name information if needed
1517 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1519 uniTargetName.MaximumLength = uniTargetName.Length;
1521 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1523 if( uniTargetName.Length > 0)
1526 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1529 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1530 RtlCompareUnicodeString( &uniTargetName,
1531 &DirEntry->NameInformation.TargetName,
1536 // Update the target name
1539 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1541 uniTargetName.Buffer,
1542 uniTargetName.Length);
1544 if( !NT_SUCCESS( ntStatus))
1547 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1549 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1553 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1557 // If the FileType is the same then nothing to do since it IS
1561 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1564 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1566 try_return( ntStatus = STATUS_SUCCESS);
1569 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1571 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1573 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1575 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1577 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1579 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1581 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1583 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1585 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1586 pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1587 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1590 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1593 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1595 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1599 if( pDirEntry != NULL)
1602 AFSExFreePool( pDirEntry);
1610 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1613 NTSTATUS ntStatus = STATUS_SUCCESS;
1614 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1615 AFSVolumeCB *pVolumeCB = NULL;
1616 AFSFcb *pTargetDcb = NULL;
1617 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1618 AFSDirectoryCB *pCurrentDirEntry = NULL;
1619 BOOLEAN bIsChild = FALSE;
1620 ULONGLONG ullIndex = 0;
1621 AFSObjectInfoCB *pObjectInfo = NULL;
1622 IO_STATUS_BLOCK stIoStatus;
1629 // Need to locate the Fcb for the directory to purge
1632 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1633 AFS_TRACE_LEVEL_VERBOSE,
1634 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1635 &pDevExt->Specific.RDR.VolumeTreeLock,
1636 PsGetCurrentThread());
1639 // Starve any exclusive waiters on this paticular call
1642 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1645 // Locate the volume node
1648 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1650 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1652 (AFSBTreeEntry **)&pVolumeCB);
1654 if( pVolumeCB != NULL)
1657 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1659 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1660 AFS_TRACE_LEVEL_VERBOSE,
1661 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1663 pVolumeCB->VolumeReferenceCount);
1666 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1668 if( !NT_SUCCESS( ntStatus) ||
1671 try_return( ntStatus = STATUS_SUCCESS);
1675 // If this is a whole volume invalidation then go do it now
1678 if( InvalidateCB->WholeVolume ||
1679 AFSIsVolumeFID( &InvalidateCB->FileID))
1682 ntStatus = AFSInvalidateVolume( pVolumeCB,
1683 InvalidateCB->Reason);
1685 AFSFsRtlNotifyFullReportChange( &pVolumeCB->ObjectInformation,
1687 FILE_NOTIFY_CHANGE_FILE_NAME |
1688 FILE_NOTIFY_CHANGE_DIR_NAME |
1689 FILE_NOTIFY_CHANGE_NAME |
1690 FILE_NOTIFY_CHANGE_ATTRIBUTES |
1691 FILE_NOTIFY_CHANGE_SIZE,
1692 FILE_ACTION_MODIFIED);
1694 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1696 try_return( ntStatus);
1699 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1702 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1704 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1705 AFS_TRACE_LEVEL_VERBOSE,
1706 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
1708 pVolumeCB->VolumeReferenceCount);
1710 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
1712 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
1714 (AFSBTreeEntry **)&pObjectInfo);
1716 if( pObjectInfo != NULL)
1720 // Reference the node so it won't be torn down
1723 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
1725 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1726 AFS_TRACE_LEVEL_VERBOSE,
1727 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
1729 pObjectInfo->ObjectReferenceCount);
1732 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1734 if( !NT_SUCCESS( ntStatus) ||
1735 pObjectInfo == NULL)
1737 try_return( ntStatus = STATUS_SUCCESS);
1740 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
1741 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK ||
1742 pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1745 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1746 AFS_TRACE_LEVEL_VERBOSE,
1747 "AFSInvalidateCache Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1748 pObjectInfo->FileType,
1749 pObjectInfo->FileId.Cell,
1750 pObjectInfo->FileId.Volume,
1751 pObjectInfo->FileId.Vnode,
1752 pObjectInfo->FileId.Unique,
1753 InvalidateCB->Reason);
1756 // We only act on the mount point itself, not the target. If the
1757 // node has been deleted then mark it as such otherwise indicate
1758 // it requires verification
1761 if( InvalidateCB->Reason == AFS_INVALIDATE_DELETED)
1763 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1768 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
1769 InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1771 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1774 pObjectInfo->Expiration.QuadPart = 0;
1776 pObjectInfo->TargetFileId.Vnode = 0;
1778 pObjectInfo->TargetFileId.Unique = 0;
1780 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1781 AFS_TRACE_LEVEL_VERBOSE,
1782 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1783 pObjectInfo->FileId.Cell,
1784 pObjectInfo->FileId.Volume,
1785 pObjectInfo->FileId.Vnode,
1786 pObjectInfo->FileId.Unique);
1788 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1791 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1793 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1795 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1798 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1800 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1804 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1807 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1809 FILE_NOTIFY_CHANGE_FILE_NAME |
1810 FILE_NOTIFY_CHANGE_ATTRIBUTES,
1811 FILE_ACTION_MODIFIED);
1813 try_return( ntStatus);
1817 // Depending on the reason for invalidation then perform work on the node
1820 switch( InvalidateCB->Reason)
1823 case AFS_INVALIDATE_DELETED:
1827 // Mark this node as invalid
1830 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
1832 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1833 AFS_TRACE_LEVEL_VERBOSE,
1834 "AFSInvalidateCache Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1835 pObjectInfo->FileId.Cell,
1836 pObjectInfo->FileId.Volume,
1837 pObjectInfo->FileId.Vnode,
1838 pObjectInfo->FileId.Unique);
1840 if( pObjectInfo->ParentObjectInformation != NULL)
1843 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1844 AFS_TRACE_LEVEL_VERBOSE,
1845 "AFSInvalidateCache Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1846 pObjectInfo->ParentObjectInformation->FileId.Cell,
1847 pObjectInfo->ParentObjectInformation->FileId.Volume,
1848 pObjectInfo->ParentObjectInformation->FileId.Vnode,
1849 pObjectInfo->ParentObjectInformation->FileId.Unique);
1851 SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1852 pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1853 pObjectInfo->ParentObjectInformation->Expiration.QuadPart = 0;
1856 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1858 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1862 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1865 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1868 FILE_ACTION_REMOVED);
1873 case AFS_INVALIDATE_FLUSHED:
1876 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
1877 pObjectInfo->Fcb != NULL)
1880 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1881 AFS_TRACE_LEVEL_VERBOSE,
1882 "AFSInvalidateCache Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1883 pObjectInfo->FileId.Cell,
1884 pObjectInfo->FileId.Volume,
1885 pObjectInfo->FileId.Vnode,
1886 pObjectInfo->FileId.Unique);
1888 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
1894 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1899 if( !NT_SUCCESS( stIoStatus.Status))
1902 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1903 AFS_TRACE_LEVEL_ERROR,
1904 "AFSInvalidateCache CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1905 pObjectInfo->FileId.Cell,
1906 pObjectInfo->FileId.Volume,
1907 pObjectInfo->FileId.Vnode,
1908 pObjectInfo->FileId.Unique,
1910 stIoStatus.Information);
1912 ntStatus = stIoStatus.Status;
1915 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1920 __except( EXCEPTION_EXECUTE_HANDLER)
1923 ntStatus = GetExceptionCode();
1926 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
1929 // Clear out the extents
1930 // Get rid of them (note this involves waiting
1931 // for any writes or reads to the cache to complete)
1934 (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb);
1937 // Fall through to the default processing
1943 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1945 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1949 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1952 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1954 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1957 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1959 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1963 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1966 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1969 FILE_ACTION_MODIFIED);
1972 // Indicate this node requires re-evaluation for the remaining reasons
1975 pObjectInfo->Expiration.QuadPart = 0;
1977 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1978 AFS_TRACE_LEVEL_VERBOSE,
1979 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1980 pObjectInfo->FileId.Cell,
1981 pObjectInfo->FileId.Volume,
1982 pObjectInfo->FileId.Vnode,
1983 pObjectInfo->FileId.Unique);
1985 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1987 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
1988 InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1990 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1992 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
1995 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1996 AFS_TRACE_LEVEL_VERBOSE,
1997 "AFSInvalidateCache Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1998 pObjectInfo->FileId.Cell,
1999 pObjectInfo->FileId.Volume,
2000 pObjectInfo->FileId.Vnode,
2001 pObjectInfo->FileId.Unique);
2003 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2013 if( pObjectInfo != NULL)
2016 InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
2018 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2019 AFS_TRACE_LEVEL_VERBOSE,
2020 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
2022 pObjectInfo->ObjectReferenceCount);
2030 AFSIsChildOfParent( IN AFSFcb *Dcb,
2034 BOOLEAN bIsChild = FALSE;
2035 AFSFcb *pCurrentFcb = Fcb;
2037 while( pCurrentFcb != NULL)
2040 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2048 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2056 AFSCreateHighIndex( IN AFSFileID *FileID)
2059 ULONGLONG ullIndex = 0;
2061 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2068 AFSCreateLowIndex( IN AFSFileID *FileID)
2071 ULONGLONG ullIndex = 0;
2073 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2079 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2080 IN ACCESS_MASK GrantedAccess,
2081 IN BOOLEAN DirectoryEntry)
2084 BOOLEAN bAccessGranted = TRUE;
2087 // Check if we are asking for read/write and granted only read only
2088 // NOTE: There will be more checks here
2091 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2093 AFSCheckForReadOnlyAccess( GrantedAccess,
2097 bAccessGranted = FALSE;
2100 return bAccessGranted;
2104 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2107 NTSTATUS ntStatus = STATUS_SUCCESS;
2108 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2114 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2116 if( AFSGlobalRoot == NULL)
2123 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2126 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2133 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2140 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2141 IN UNICODE_STRING *SubstituteName,
2142 IN ULONG StringIndex)
2145 NTSTATUS ntStatus = STATUS_SUCCESS;
2146 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2147 AFSSysNameCB *pSysName = NULL;
2148 ERESOURCE *pSysNameLock = NULL;
2151 UNICODE_STRING uniSysName;
2158 if( IoIs32bitProcess( NULL))
2161 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2163 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2168 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2170 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2174 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2176 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2180 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2181 AFS_TRACE_LEVEL_VERBOSE,
2182 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2184 PsGetCurrentThread());
2186 AFSAcquireShared( pSysNameLock,
2190 // Find where we are in the list
2193 while( pSysName != NULL &&
2194 ulIndex < StringIndex)
2197 pSysName = pSysName->fLink;
2202 if( pSysName == NULL)
2205 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2208 RtlInitUnicodeString( &uniSysName,
2211 // If it is a full component of @SYS then just substitue the
2215 if( RtlCompareUnicodeString( &uniSysName,
2220 SubstituteName->Length = pSysName->SysName.Length;
2221 SubstituteName->MaximumLength = SubstituteName->Length;
2223 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2224 SubstituteName->Length,
2225 AFS_SUBST_BUFFER_TAG);
2227 if( SubstituteName->Buffer == NULL)
2230 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2233 RtlCopyMemory( SubstituteName->Buffer,
2234 pSysName->SysName.Buffer,
2235 pSysName->SysName.Length);
2242 while( ComponentName->Buffer[ usIndex] != L'@')
2248 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2249 SubstituteName->MaximumLength = SubstituteName->Length;
2251 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2252 SubstituteName->Length,
2253 AFS_SUBST_BUFFER_TAG);
2255 if( SubstituteName->Buffer == NULL)
2258 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2261 RtlCopyMemory( SubstituteName->Buffer,
2262 ComponentName->Buffer,
2263 usIndex * sizeof( WCHAR));
2265 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2266 pSysName->SysName.Buffer,
2267 pSysName->SysName.Length);
2272 AFSReleaseResource( pSysNameLock);
2279 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2280 IN OUT UNICODE_STRING *ComponentName,
2281 IN UNICODE_STRING *SubstituteName,
2282 IN OUT UNICODE_STRING *RemainingPath,
2283 IN BOOLEAN FreePathName)
2286 NTSTATUS ntStatus = STATUS_SUCCESS;
2287 UNICODE_STRING uniPathName;
2288 USHORT usPrefixNameLen = 0;
2289 SHORT sNameLenDelta = 0;
2295 // If the passed in name can handle the additional length
2296 // then just moves things around
2299 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2301 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2303 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2306 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2309 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2310 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2311 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2314 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2315 SubstituteName->Buffer,
2316 SubstituteName->Length);
2318 FullPathName->Length += sNameLenDelta;
2320 ComponentName->Length += sNameLenDelta;
2322 ComponentName->MaximumLength = ComponentName->Length;
2324 if ( RemainingPath->Buffer)
2327 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2330 try_return( ntStatus);
2334 // Need to re-allocate the buffer
2337 uniPathName.Length = FullPathName->Length -
2338 ComponentName->Length +
2339 SubstituteName->Length;
2341 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2343 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2344 uniPathName.MaximumLength,
2345 AFS_NAME_BUFFER_FOUR_TAG);
2347 if( uniPathName.Buffer == NULL)
2350 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2353 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2355 usPrefixNameLen *= sizeof( WCHAR);
2357 RtlZeroMemory( uniPathName.Buffer,
2358 uniPathName.MaximumLength);
2360 RtlCopyMemory( uniPathName.Buffer,
2361 FullPathName->Buffer,
2364 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2365 SubstituteName->Buffer,
2366 SubstituteName->Length);
2368 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2371 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2372 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2373 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2376 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2378 ComponentName->Length += sNameLenDelta;
2380 ComponentName->MaximumLength = ComponentName->Length;
2382 if ( RemainingPath->Buffer)
2385 RemainingPath->Buffer = uniPathName.Buffer
2386 + (RemainingPath->Buffer - FullPathName->Buffer)
2387 + sNameLenDelta/sizeof( WCHAR);
2392 AFSExFreePool( FullPathName->Buffer);
2395 *FullPathName = uniPathName;
2406 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2410 NTSTATUS ntStatus = STATUS_SUCCESS;
2411 AFSFcb *pFcb = NULL;
2412 AFSObjectInfoCB *pCurrentObject = NULL;
2418 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2419 AFS_TRACE_LEVEL_VERBOSE,
2420 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2421 VolumeCB->ObjectInformation.FileId.Cell,
2422 VolumeCB->ObjectInformation.FileId.Volume,
2423 VolumeCB->ObjectInformation.FileId.Vnode,
2424 VolumeCB->ObjectInformation.FileId.Unique,
2428 // Depending on the reason for invalidation then perform work on the node
2434 case AFS_INVALIDATE_DELETED:
2438 // Mark this volume as invalid
2441 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2443 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2445 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2447 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2449 FILE_NOTIFY_CHANGE_DIR_NAME,
2450 FILE_ACTION_REMOVED);
2452 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2455 pCurrentObject = VolumeCB->ObjectInfoListHead;
2457 while( pCurrentObject != NULL)
2460 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2462 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2466 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2469 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2472 FILE_ACTION_REMOVED);
2474 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2476 pFcb = pCurrentObject->Fcb;
2479 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2484 // Clear out the extents
2485 // And get rid of them (note this involves waiting
2486 // for any writes or reads to the cache to complete)
2489 (VOID) AFSTearDownFcbExtents( pFcb);
2492 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2495 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2504 // Indicate this node requires re-evaluation for the remaining reasons
2507 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2509 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2510 AFS_TRACE_LEVEL_VERBOSE,
2511 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2512 VolumeCB->ObjectInformation.FileId.Cell,
2513 VolumeCB->ObjectInformation.FileId.Volume,
2514 VolumeCB->ObjectInformation.FileId.Vnode,
2515 VolumeCB->ObjectInformation.FileId.Unique);
2517 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY);
2519 if( Reason == AFS_INVALIDATE_FLUSHED ||
2520 Reason == AFS_INVALIDATE_DATA_VERSION)
2523 VolumeCB->ObjectInformation.DataVersion.QuadPart = (ULONGLONG)-1;
2527 // Notify anyone that cares
2530 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2532 if( Reason == AFS_INVALIDATE_CREDS)
2534 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2537 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2539 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2543 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2546 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2549 FILE_ACTION_MODIFIED);
2552 // Volume invalidations require all objects in the volume be re-verified
2555 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2558 pCurrentObject = VolumeCB->ObjectInfoListHead;
2560 while( pCurrentObject != NULL)
2563 pCurrentObject->Expiration.QuadPart = 0;
2565 pCurrentObject->TargetFileId.Vnode = 0;
2567 pCurrentObject->TargetFileId.Unique = 0;
2569 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2570 AFS_TRACE_LEVEL_VERBOSE,
2571 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2572 pCurrentObject->FileId.Cell,
2573 pCurrentObject->FileId.Volume,
2574 pCurrentObject->FileId.Vnode,
2575 pCurrentObject->FileId.Unique);
2577 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
2579 if( Reason == AFS_INVALIDATE_FLUSHED ||
2580 Reason == AFS_INVALIDATE_DATA_VERSION)
2583 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
2585 if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
2588 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2589 AFS_TRACE_LEVEL_VERBOSE,
2590 "AFSInvalidateVolume Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
2591 pCurrentObject->FileId.Cell,
2592 pCurrentObject->FileId.Volume,
2593 pCurrentObject->FileId.Vnode,
2594 pCurrentObject->FileId.Unique);
2596 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2600 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2602 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2606 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2609 if( Reason == AFS_INVALIDATE_CREDS)
2611 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2614 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2616 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2620 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2623 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2626 FILE_ACTION_MODIFIED);
2628 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2631 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2642 AFSVerifyEntry( IN GUID *AuthGroup,
2643 IN AFSDirectoryCB *DirEntry)
2646 NTSTATUS ntStatus = STATUS_SUCCESS;
2647 AFSDirEnumEntry *pDirEnumEntry = NULL;
2648 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2649 IO_STATUS_BLOCK stIoStatus;
2654 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2655 AFS_TRACE_LEVEL_VERBOSE_2,
2656 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2657 &DirEntry->NameInformation.FileName,
2658 pObjectInfo->FileId.Cell,
2659 pObjectInfo->FileId.Volume,
2660 pObjectInfo->FileId.Vnode,
2661 pObjectInfo->FileId.Unique);
2663 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2668 if( !NT_SUCCESS( ntStatus))
2671 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2672 AFS_TRACE_LEVEL_ERROR,
2673 "AFSValidateEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2674 &DirEntry->NameInformation.FileName,
2675 pObjectInfo->FileId.Cell,
2676 pObjectInfo->FileId.Volume,
2677 pObjectInfo->FileId.Vnode,
2678 pObjectInfo->FileId.Unique,
2681 try_return( ntStatus);
2685 // Check the data version of the file
2688 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2689 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2692 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2693 AFS_TRACE_LEVEL_VERBOSE,
2694 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2695 pObjectInfo->DataVersion.QuadPart,
2696 &DirEntry->NameInformation.FileName,
2697 pObjectInfo->FileId.Cell,
2698 pObjectInfo->FileId.Volume,
2699 pObjectInfo->FileId.Vnode,
2700 pObjectInfo->FileId.Unique);
2703 // We are ok, just get out
2706 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2708 try_return( ntStatus = STATUS_SUCCESS);
2712 // New data version so we will need to process the node based on the type
2715 switch( pDirEnumEntry->FileType)
2718 case AFS_FILE_TYPE_MOUNTPOINT:
2722 // For a mount point we need to ensure the target is the same
2725 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2726 &pDirEnumEntry->TargetFileId))
2732 // Update the metadata for the entry
2735 ntStatus = AFSUpdateMetaData( DirEntry,
2738 if( NT_SUCCESS( ntStatus))
2741 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2747 case AFS_FILE_TYPE_SYMLINK:
2750 ASSERT( pDirEnumEntry->TargetNameLength > 0);
2753 // Update the metadata for the entry
2756 ntStatus = AFSUpdateMetaData( DirEntry,
2759 if( NT_SUCCESS( ntStatus))
2762 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2768 case AFS_FILE_TYPE_FILE:
2770 FILE_OBJECT * pCCFileObject = NULL;
2771 BOOLEAN bPurgeExtents = FALSE;
2773 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2775 bPurgeExtents = TRUE;
2777 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2778 AFS_TRACE_LEVEL_VERBOSE,
2779 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2780 &DirEntry->NameInformation.FileName,
2781 pObjectInfo->FileId.Cell,
2782 pObjectInfo->FileId.Volume,
2783 pObjectInfo->FileId.Vnode,
2784 pObjectInfo->FileId.Unique);
2786 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2790 // Update the metadata for the entry
2793 ntStatus = AFSUpdateMetaData( DirEntry,
2796 if( !NT_SUCCESS( ntStatus))
2799 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2800 AFS_TRACE_LEVEL_ERROR,
2801 "AFSInvalidateCache Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2802 &DirEntry->NameInformation.FileName,
2803 pObjectInfo->FileId.Cell,
2804 pObjectInfo->FileId.Volume,
2805 pObjectInfo->FileId.Vnode,
2806 pObjectInfo->FileId.Unique,
2812 if( pObjectInfo->Fcb != NULL)
2815 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2816 AFS_TRACE_LEVEL_VERBOSE,
2817 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2818 &DirEntry->NameInformation.FileName,
2819 pObjectInfo->FileId.Cell,
2820 pObjectInfo->FileId.Volume,
2821 pObjectInfo->FileId.Vnode,
2822 pObjectInfo->FileId.Unique);
2824 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2830 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2835 if( !NT_SUCCESS( stIoStatus.Status))
2838 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2839 AFS_TRACE_LEVEL_ERROR,
2840 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2841 &DirEntry->NameInformation.FileName,
2842 pObjectInfo->FileId.Cell,
2843 pObjectInfo->FileId.Volume,
2844 pObjectInfo->FileId.Vnode,
2845 pObjectInfo->FileId.Unique,
2847 stIoStatus.Information);
2849 ntStatus = stIoStatus.Status;
2855 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2861 __except( EXCEPTION_EXECUTE_HANDLER)
2863 ntStatus = GetExceptionCode();
2865 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2866 AFS_TRACE_LEVEL_ERROR,
2867 "AFSVerifyEntry CcFlushCache or CcPurgeCacheSection Exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2868 &DirEntry->NameInformation.FileName,
2869 pObjectInfo->FileId.Cell,
2870 pObjectInfo->FileId.Volume,
2871 pObjectInfo->FileId.Vnode,
2872 pObjectInfo->FileId.Unique,
2876 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2880 AFSFlushExtents( pObjectInfo->Fcb);
2884 // Reacquire the Fcb to purge the cache
2887 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2888 AFS_TRACE_LEVEL_VERBOSE,
2889 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2890 &pObjectInfo->Fcb->NPFcb->Resource,
2891 PsGetCurrentThread());
2893 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2897 // Update file sizes
2900 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2901 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2902 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2904 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2906 if ( pCCFileObject != NULL)
2908 CcSetFileSizes( pCCFileObject,
2909 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
2912 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2916 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2917 AFS_TRACE_LEVEL_WARNING,
2918 "AFSValidateEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2919 &DirEntry->NameInformation.FileName,
2920 pObjectInfo->FileId.Cell,
2921 pObjectInfo->FileId.Volume,
2922 pObjectInfo->FileId.Vnode,
2923 pObjectInfo->FileId.Unique);
2926 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2931 case AFS_FILE_TYPE_DIRECTORY:
2934 AFSFcb *pCurrentFcb = NULL;
2935 AFSDirectoryCB *pCurrentDirEntry = NULL;
2938 // For a directory or root entry flush the content of
2939 // the directory enumeration.
2942 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2945 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2946 AFS_TRACE_LEVEL_VERBOSE_2,
2947 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2948 &DirEntry->NameInformation.FileName,
2949 pObjectInfo->FileId.Cell,
2950 pObjectInfo->FileId.Volume,
2951 pObjectInfo->FileId.Vnode,
2952 pObjectInfo->FileId.Unique);
2954 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2957 AFSValidateDirectoryCache( pObjectInfo,
2960 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2964 // Update the metadata for the entry
2967 ntStatus = AFSUpdateMetaData( DirEntry,
2970 if( NT_SUCCESS( ntStatus))
2973 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2979 case AFS_FILE_TYPE_DFSLINK:
2982 UNICODE_STRING uniTargetName;
2985 // For a DFS link need to check the target name has not changed
2988 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
2990 uniTargetName.MaximumLength = uniTargetName.Length;
2992 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
2994 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
2997 if( DirEntry->NameInformation.TargetName.Length == 0 ||
2998 RtlCompareUnicodeString( &uniTargetName,
2999 &DirEntry->NameInformation.TargetName,
3004 // Update the target name
3007 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3009 uniTargetName.Buffer,
3010 uniTargetName.Length);
3012 if( !NT_SUCCESS( ntStatus))
3015 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3021 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3024 // Update the metadata for the entry
3027 ntStatus = AFSUpdateMetaData( DirEntry,
3030 if( NT_SUCCESS( ntStatus))
3033 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3041 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3042 AFS_TRACE_LEVEL_WARNING,
3043 "AFSVerifyEntry Attempt to verify node of type %d\n",
3044 pObjectInfo->FileType);
3051 if( pDirEnumEntry != NULL)
3054 AFSExFreePool( pDirEnumEntry);
3062 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3065 NTSTATUS ntStatus = STATUS_SUCCESS;
3066 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3067 ULONGLONG ullIndex = 0;
3068 AFSVolumeCB *pVolumeCB = NULL;
3069 AFSFcb *pFcb = NULL;
3070 AFSObjectInfoCB *pCurrentObject = NULL;
3075 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3076 AFS_TRACE_LEVEL_VERBOSE,
3077 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3078 VolumeStatus->Online,
3079 VolumeStatus->FileID.Cell,
3080 VolumeStatus->FileID.Volume);
3083 // Need to locate the Fcb for the directory to purge
3086 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3087 AFS_TRACE_LEVEL_VERBOSE,
3088 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3089 &pDevExt->Specific.RDR.VolumeTreeLock,
3090 PsGetCurrentThread());
3092 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3095 // Locate the volume node
3098 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3100 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3102 (AFSBTreeEntry **)&pVolumeCB);
3104 if( pVolumeCB != NULL)
3107 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3109 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3112 // Set the volume state accordingly
3115 if( VolumeStatus->Online)
3118 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3123 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3126 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3129 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3131 while( pCurrentObject != NULL)
3134 if( VolumeStatus->Online)
3137 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3139 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3141 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3146 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3149 pFcb = pCurrentObject->Fcb;
3152 !(VolumeStatus->Online) &&
3153 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3156 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3157 AFS_TRACE_LEVEL_ERROR,
3158 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3159 VolumeStatus->FileID.Cell,
3160 VolumeStatus->FileID.Volume);
3163 // Clear out the extents
3166 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3167 AFS_TRACE_LEVEL_VERBOSE,
3168 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3169 &pFcb->NPFcb->Specific.File.ExtentsResource,
3170 PsGetCurrentThread());
3172 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3175 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3177 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3181 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3182 AFS_TRACE_LEVEL_VERBOSE,
3183 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3184 &pFcb->NPFcb->Specific.File.ExtentsResource,
3185 PsGetCurrentThread());
3187 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3190 // And get rid of them (note this involves waiting
3191 // for any writes or reads to the cache to complete)
3194 (VOID) AFSTearDownFcbExtents( pFcb);
3197 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3200 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3202 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3207 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3215 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3218 NTSTATUS ntStatus = STATUS_SUCCESS;
3223 if( AFSGlobalRoot == NULL)
3226 try_return( ntStatus);
3229 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3233 // Set the network state according to the information
3236 if( NetworkStatus->Online)
3239 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3244 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3247 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3258 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3262 NTSTATUS ntStatus = STATUS_SUCCESS;
3263 BOOLEAN bAcquiredLock = FALSE;
3264 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3265 AFSFcb *pFcb = NULL;
3270 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3271 AFS_TRACE_LEVEL_VERBOSE,
3272 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3273 ObjectInfo->FileId.Cell,
3274 ObjectInfo->FileId.Volume,
3275 ObjectInfo->FileId.Vnode,
3276 ObjectInfo->FileId.Unique);
3278 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3281 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3282 AFS_TRACE_LEVEL_VERBOSE,
3283 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3284 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3285 PsGetCurrentThread());
3287 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3290 bAcquiredLock = TRUE;
3294 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3297 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3298 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3301 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3302 AFS_TRACE_LEVEL_ERROR,
3303 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
3304 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3305 ObjectInfo->FileId.Cell,
3306 ObjectInfo->FileId.Volume,
3307 ObjectInfo->FileId.Vnode,
3308 ObjectInfo->FileId.Unique);
3312 // Reset the directory list information by clearing all valid entries
3315 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3317 while( pCurrentDirEntry != NULL)
3320 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3323 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3326 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3330 // Reget the directory contents
3333 AFSVerifyDirectoryContent( ObjectInfo,
3337 // Now start again and tear down any entries not valid
3340 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3342 while( pCurrentDirEntry != NULL)
3345 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3347 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3350 pCurrentDirEntry = pNextDirEntry;
3355 if( pCurrentDirEntry->OpenReferenceCount == 0)
3358 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3359 AFS_TRACE_LEVEL_VERBOSE,
3360 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3361 &pCurrentDirEntry->NameInformation.FileName,
3362 ObjectInfo->FileId.Cell,
3363 ObjectInfo->FileId.Volume,
3364 ObjectInfo->FileId.Vnode,
3365 ObjectInfo->FileId.Unique);
3367 AFSDeleteDirEntry( ObjectInfo,
3373 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3374 AFS_TRACE_LEVEL_VERBOSE,
3375 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3377 &pCurrentDirEntry->NameInformation.FileName,
3378 ObjectInfo->FileId.Cell,
3379 ObjectInfo->FileId.Volume,
3380 ObjectInfo->FileId.Vnode,
3381 ObjectInfo->FileId.Unique);
3383 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3385 AFSRemoveNameEntry( ObjectInfo,
3389 pCurrentDirEntry = pNextDirEntry;
3393 if( !AFSValidateDirList( ObjectInfo))
3396 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3403 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3411 AFSIsVolumeFID( IN AFSFileID *FileID)
3414 BOOLEAN bIsVolume = FALSE;
3416 if( FileID->Vnode == 1 &&
3417 FileID->Unique == 1)
3427 AFSIsFinalNode( IN AFSFcb *Fcb)
3430 BOOLEAN bIsFinalNode = FALSE;
3432 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3433 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3434 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3435 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3436 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3439 bIsFinalNode = TRUE;
3444 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3445 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3448 return bIsFinalNode;
3452 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3453 IN AFSDirEnumEntry *DirEnumEntry)
3456 NTSTATUS ntStatus = STATUS_SUCCESS;
3457 UNICODE_STRING uniTargetName;
3458 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3463 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3465 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3467 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3469 pObjectInfo->FileType = DirEnumEntry->FileType;
3471 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3473 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3475 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3477 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3479 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3481 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3483 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3485 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3486 pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3487 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3490 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3493 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3495 pObjectInfo->Links = DirEnumEntry->Links;
3497 if( DirEnumEntry->TargetNameLength > 0)
3501 // Update the target name information if needed
3504 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3506 uniTargetName.MaximumLength = uniTargetName.Length;
3508 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3510 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3513 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3514 RtlCompareUnicodeString( &uniTargetName,
3515 &DirEntry->NameInformation.TargetName,
3520 // Update the target name
3523 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3525 uniTargetName.Buffer,
3526 uniTargetName.Length);
3528 if( !NT_SUCCESS( ntStatus))
3531 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3533 try_return( ntStatus);
3537 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3539 else if( DirEntry->NameInformation.TargetName.Length > 0)
3542 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3545 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3546 DirEntry->NameInformation.TargetName.Buffer != NULL)
3548 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
3551 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3553 DirEntry->NameInformation.TargetName.Length = 0;
3554 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3555 DirEntry->NameInformation.TargetName.Buffer = NULL;
3557 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3569 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3571 IN BOOLEAN PurgeContent,
3572 IN BOOLEAN FastCall)
3575 NTSTATUS ntStatus = STATUS_SUCCESS;
3576 LARGE_INTEGER liSystemTime;
3577 AFSDirEnumEntry *pDirEnumEntry = NULL;
3578 AFSFcb *pCurrentFcb = NULL;
3579 BOOLEAN bReleaseFcb = FALSE;
3580 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3586 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3590 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3591 AFS_TRACE_LEVEL_VERBOSE_2,
3592 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3593 &DirEntry->NameInformation.FileName,
3594 pObjectInfo->FileId.Cell,
3595 pObjectInfo->FileId.Volume,
3596 pObjectInfo->FileId.Vnode,
3597 pObjectInfo->FileId.Unique);
3600 // If this is a fake node then bail since the service knows nothing about it
3603 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3606 try_return( ntStatus);
3610 pObjectInfo->Fcb != NULL)
3613 pCurrentFcb = pObjectInfo->Fcb;
3615 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3618 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3619 AFS_TRACE_LEVEL_VERBOSE,
3620 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3621 &pCurrentFcb->NPFcb->Resource,
3622 PsGetCurrentThread());
3624 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3632 // This routine ensures that the current entry is valid by:
3634 // 1) Checking that the expiration time is non-zero and after where we
3638 KeQuerySystemTime( &liSystemTime);
3640 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3641 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3642 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3643 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3646 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3647 AFS_TRACE_LEVEL_VERBOSE_2,
3648 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3649 &DirEntry->NameInformation.FileName,
3650 pObjectInfo->FileId.Cell,
3651 pObjectInfo->FileId.Volume,
3652 pObjectInfo->FileId.Vnode,
3653 pObjectInfo->FileId.Unique);
3655 try_return( ntStatus);
3659 // This node requires updating
3662 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3667 if( !NT_SUCCESS( ntStatus))
3670 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3671 AFS_TRACE_LEVEL_ERROR,
3672 "AFSValidateEntry Failed to evaluate entry %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3673 &DirEntry->NameInformation.FileName,
3674 pObjectInfo->FileId.Cell,
3675 pObjectInfo->FileId.Volume,
3676 pObjectInfo->FileId.Vnode,
3677 pObjectInfo->FileId.Unique,
3681 // Failed validation of node so return access-denied
3684 try_return( ntStatus);
3687 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3688 AFS_TRACE_LEVEL_VERBOSE,
3689 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3690 &DirEntry->NameInformation.FileName,
3691 pObjectInfo->FileId.Cell,
3692 pObjectInfo->FileId.Volume,
3693 pObjectInfo->FileId.Vnode,
3694 pObjectInfo->FileId.Unique,
3695 pObjectInfo->DataVersion.QuadPart,
3696 pDirEnumEntry->DataVersion.QuadPart,
3697 pDirEnumEntry->FileType);
3701 // Based on the file type, process the node
3704 switch( pDirEnumEntry->FileType)
3707 case AFS_FILE_TYPE_MOUNTPOINT:
3711 // Update the metadata for the entry
3714 ntStatus = AFSUpdateMetaData( DirEntry,
3717 if( NT_SUCCESS( ntStatus))
3720 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3726 case AFS_FILE_TYPE_SYMLINK:
3727 case AFS_FILE_TYPE_DFSLINK:
3731 // Update the metadata for the entry
3734 ntStatus = AFSUpdateMetaData( DirEntry,
3737 if( NT_SUCCESS( ntStatus))
3740 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3746 case AFS_FILE_TYPE_FILE:
3750 // For a file where the data version has become invalid we need to
3751 // fail any current extent requests and purge the cache for the file
3752 // Can't hold the Fcb resource while doing this
3755 if( pCurrentFcb != NULL &&
3756 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3757 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3760 IO_STATUS_BLOCK stIoStatus;
3761 BOOLEAN bPurgeExtents = FALSE;
3763 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3764 AFS_TRACE_LEVEL_VERBOSE_2,
3765 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3766 &DirEntry->NameInformation.FileName,
3767 pObjectInfo->FileId.Cell,
3768 pObjectInfo->FileId.Volume,
3769 pObjectInfo->FileId.Vnode,
3770 pObjectInfo->FileId.Unique);
3772 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3774 bPurgeExtents = TRUE;
3776 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3777 AFS_TRACE_LEVEL_VERBOSE,
3778 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3779 &DirEntry->NameInformation.FileName,
3780 pObjectInfo->FileId.Cell,
3781 pObjectInfo->FileId.Volume,
3782 pObjectInfo->FileId.Vnode,
3783 pObjectInfo->FileId.Unique);
3785 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3791 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
3796 if( !NT_SUCCESS( stIoStatus.Status))
3799 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3800 AFS_TRACE_LEVEL_ERROR,
3801 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3802 &DirEntry->NameInformation.FileName,
3803 pObjectInfo->FileId.Cell,
3804 pObjectInfo->FileId.Volume,
3805 pObjectInfo->FileId.Vnode,
3806 pObjectInfo->FileId.Unique,
3808 stIoStatus.Information);
3810 ntStatus = stIoStatus.Status;
3816 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3822 __except( EXCEPTION_EXECUTE_HANDLER)
3824 ntStatus = GetExceptionCode();
3826 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3827 AFS_TRACE_LEVEL_ERROR,
3828 "AFSValidateEntry CcFlushCache or CcPurgeCacheSection exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3829 &DirEntry->NameInformation.FileName,
3830 pObjectInfo->FileId.Cell,
3831 pObjectInfo->FileId.Volume,
3832 pObjectInfo->FileId.Vnode,
3833 pObjectInfo->FileId.Unique,
3838 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3842 AFSFlushExtents( pCurrentFcb);
3846 // Reacquire the Fcb to purge the cache
3849 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3850 AFS_TRACE_LEVEL_VERBOSE,
3851 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3852 &pCurrentFcb->NPFcb->Resource,
3853 PsGetCurrentThread());
3855 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3860 // Update the metadata for the entry
3863 ntStatus = AFSUpdateMetaData( DirEntry,
3866 if( !NT_SUCCESS( ntStatus))
3869 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3870 AFS_TRACE_LEVEL_ERROR,
3871 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3872 &DirEntry->NameInformation.FileName,
3873 pObjectInfo->FileId.Cell,
3874 pObjectInfo->FileId.Volume,
3875 pObjectInfo->FileId.Vnode,
3876 pObjectInfo->FileId.Unique,
3882 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3885 // Update file sizes
3888 if( pObjectInfo->Fcb != NULL)
3890 FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3892 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3893 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3894 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3896 if ( pCCFileObject != NULL)
3898 CcSetFileSizes( pCCFileObject,
3899 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3906 case AFS_FILE_TYPE_DIRECTORY:
3909 AFSDirectoryCB *pCurrentDirEntry = NULL;
3911 if( pCurrentFcb != NULL &&
3912 pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3916 // For a directory or root entry flush the content of
3917 // the directory enumeration.
3920 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3921 AFS_TRACE_LEVEL_VERBOSE,
3922 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3923 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3924 PsGetCurrentThread());
3926 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3929 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3930 AFS_TRACE_LEVEL_VERBOSE_2,
3931 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3932 &DirEntry->NameInformation.FileName,
3933 pObjectInfo->FileId.Cell,
3934 pObjectInfo->FileId.Volume,
3935 pObjectInfo->FileId.Vnode,
3936 pObjectInfo->FileId.Unique);
3938 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3941 AFSValidateDirectoryCache( pCurrentFcb->ObjectInformation,
3944 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3947 if( !NT_SUCCESS( ntStatus))
3950 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3951 AFS_TRACE_LEVEL_ERROR,
3952 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3953 &DirEntry->NameInformation.FileName,
3954 pObjectInfo->FileId.Cell,
3955 pObjectInfo->FileId.Volume,
3956 pObjectInfo->FileId.Vnode,
3957 pObjectInfo->FileId.Unique,
3965 // Update the metadata for the entry
3968 ntStatus = AFSUpdateMetaData( DirEntry,
3971 if( NT_SUCCESS( ntStatus))
3974 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3982 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3983 AFS_TRACE_LEVEL_WARNING,
3984 "AFSValidateEntry Attempt to verify node of type %d\n",
3985 pObjectInfo->FileType);
3995 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3998 if( pDirEnumEntry != NULL)
4001 AFSExFreePool( pDirEnumEntry);
4009 AFSInitializeSpecialShareNameList()
4012 NTSTATUS ntStatus = STATUS_SUCCESS;
4013 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4014 AFSObjectInfoCB *pObjectInfoCB = NULL;
4015 UNICODE_STRING uniShareName;
4016 ULONG ulEntryLength = 0;
4017 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4022 RtlInitUnicodeString( &uniShareName,
4025 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4028 if( pObjectInfoCB == NULL)
4031 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4034 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4035 AFS_TRACE_LEVEL_VERBOSE,
4036 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
4039 pObjectInfoCB->ObjectReferenceCount = 1;
4041 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4043 ulEntryLength = sizeof( AFSDirectoryCB) +
4044 uniShareName.Length;
4046 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4050 if( pDirNode == NULL)
4053 AFSDeleteObjectInfo( pObjectInfoCB);
4055 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4058 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4059 sizeof( AFSNonPagedDirectoryCB),
4060 AFS_DIR_ENTRY_NP_TAG);
4062 if( pNonPagedDirEntry == NULL)
4065 ExFreePool( pDirNode);
4067 AFSDeleteObjectInfo( pObjectInfoCB);
4069 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4072 RtlZeroMemory( pDirNode,
4075 RtlZeroMemory( pNonPagedDirEntry,
4076 sizeof( AFSNonPagedDirectoryCB));
4078 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4080 pDirNode->NonPaged = pNonPagedDirEntry;
4082 pDirNode->ObjectInformation = pObjectInfoCB;
4088 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
4090 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4092 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4094 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4096 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4097 uniShareName.Buffer,
4098 pDirNode->NameInformation.FileName.Length);
4100 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4103 AFSSpecialShareNames = pDirNode;
4105 pLastDirNode = pDirNode;
4107 RtlInitUnicodeString( &uniShareName,
4110 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4113 if( pObjectInfoCB == NULL)
4116 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4119 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4120 AFS_TRACE_LEVEL_VERBOSE,
4121 "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
4124 pObjectInfoCB->ObjectReferenceCount = 1;
4126 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4128 ulEntryLength = sizeof( AFSDirectoryCB) +
4129 uniShareName.Length;
4131 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4135 if( pDirNode == NULL)
4138 AFSDeleteObjectInfo( pObjectInfoCB);
4140 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4143 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4144 sizeof( AFSNonPagedDirectoryCB),
4145 AFS_DIR_ENTRY_NP_TAG);
4147 if( pNonPagedDirEntry == NULL)
4150 ExFreePool( pDirNode);
4152 AFSDeleteObjectInfo( pObjectInfoCB);
4154 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4157 RtlZeroMemory( pDirNode,
4160 RtlZeroMemory( pNonPagedDirEntry,
4161 sizeof( AFSNonPagedDirectoryCB));
4163 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4165 pDirNode->NonPaged = pNonPagedDirEntry;
4167 pDirNode->ObjectInformation = pObjectInfoCB;
4173 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
4175 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4177 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4179 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4181 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4182 uniShareName.Buffer,
4183 pDirNode->NameInformation.FileName.Length);
4185 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4188 pLastDirNode->ListEntry.fLink = pDirNode;
4190 pDirNode->ListEntry.bLink = pLastDirNode;
4192 pLastDirNode = pDirNode;
4194 RtlInitUnicodeString( &uniShareName,
4197 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4200 if( pObjectInfoCB == NULL)
4203 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4206 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4207 AFS_TRACE_LEVEL_VERBOSE,
4208 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4211 pObjectInfoCB->ObjectReferenceCount = 1;
4213 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4215 ulEntryLength = sizeof( AFSDirectoryCB) +
4216 uniShareName.Length;
4218 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4222 if( pDirNode == NULL)
4225 AFSDeleteObjectInfo( pObjectInfoCB);
4227 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4230 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4231 sizeof( AFSNonPagedDirectoryCB),
4232 AFS_DIR_ENTRY_NP_TAG);
4234 if( pNonPagedDirEntry == NULL)
4237 ExFreePool( pDirNode);
4239 AFSDeleteObjectInfo( pObjectInfoCB);
4241 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4244 RtlZeroMemory( pDirNode,
4247 RtlZeroMemory( pNonPagedDirEntry,
4248 sizeof( AFSNonPagedDirectoryCB));
4250 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4252 pDirNode->NonPaged = pNonPagedDirEntry;
4254 pDirNode->ObjectInformation = pObjectInfoCB;
4260 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4262 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4264 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4266 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4268 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4269 uniShareName.Buffer,
4270 pDirNode->NameInformation.FileName.Length);
4272 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4275 pLastDirNode->ListEntry.fLink = pDirNode;
4277 pDirNode->ListEntry.bLink = pLastDirNode;
4281 if( !NT_SUCCESS( ntStatus))
4284 if( AFSSpecialShareNames != NULL)
4287 pDirNode = AFSSpecialShareNames;
4289 while( pDirNode != NULL)
4292 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4294 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4296 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4298 ExFreePool( pDirNode->NonPaged);
4300 ExFreePool( pDirNode);
4302 pDirNode = pLastDirNode;
4305 AFSSpecialShareNames = NULL;
4314 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4315 IN UNICODE_STRING *SecondaryName)
4318 AFSDirectoryCB *pDirectoryCB = NULL;
4319 ULONGLONG ullHash = 0;
4320 UNICODE_STRING uniFullShareName;
4326 // Build up the entire name here. We are guaranteed that if there is a
4327 // secondary name, it is pointing to a portion of the share name buffer
4330 if( SecondaryName->Length > 0 &&
4331 SecondaryName->Buffer != NULL)
4334 uniFullShareName = *SecondaryName;
4337 // The calling routine strips off the leading slash so add it back in
4340 uniFullShareName.Buffer--;
4341 uniFullShareName.Length += sizeof( WCHAR);
4342 uniFullShareName.MaximumLength += sizeof( WCHAR);
4345 // And the share name
4348 uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
4349 uniFullShareName.Length += ShareName->Length;
4350 uniFullShareName.MaximumLength += ShareName->Length;
4355 uniFullShareName = *ShareName;
4359 // Generate our hash value
4362 ullHash = AFSGenerateCRC( &uniFullShareName,
4366 // Loop through our special share names to see if this is one of them
4369 pDirectoryCB = AFSSpecialShareNames;
4371 while( pDirectoryCB != NULL)
4374 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4380 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4384 return pDirectoryCB;
4388 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4392 // Block on the queue flush event
4395 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4405 AFSWaitOnQueuedReleases()
4408 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4411 // Block on the queue flush event
4414 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4424 AFSIsEqualFID( IN AFSFileID *FileId1,
4425 IN AFSFileID *FileId2)
4428 BOOLEAN bIsEqual = FALSE;
4430 if( FileId1->Unique == FileId2->Unique &&
4431 FileId1->Vnode == FileId2->Vnode &&
4432 FileId1->Volume == FileId2->Volume &&
4433 FileId1->Cell == FileId2->Cell)
4443 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4446 NTSTATUS ntStatus = STATUS_SUCCESS;
4447 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4452 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4455 // Reset the directory list information
4458 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4460 while( pCurrentDirEntry != NULL)
4463 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4465 if( pCurrentDirEntry->OpenReferenceCount == 0)
4468 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4469 AFS_TRACE_LEVEL_VERBOSE,
4470 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4472 &pCurrentDirEntry->NameInformation.FileName);
4474 AFSDeleteDirEntry( ObjectInfoCB,
4480 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4481 AFS_TRACE_LEVEL_VERBOSE,
4482 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4484 &pCurrentDirEntry->NameInformation.FileName);
4486 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4488 AFSRemoveNameEntry( ObjectInfoCB,
4492 pCurrentDirEntry = pNextDirEntry;
4495 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4497 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4499 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4501 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4503 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4505 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4507 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4508 AFS_TRACE_LEVEL_VERBOSE,
4509 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4510 ObjectInfoCB->FileId.Cell,
4511 ObjectInfoCB->FileId.Volume,
4512 ObjectInfoCB->FileId.Vnode,
4513 ObjectInfoCB->FileId.Unique);
4520 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4523 NTSTATUS ntStatus = STATUS_SUCCESS;
4524 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4525 UNICODE_STRING uniFullName;
4530 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4531 AFS_TRACE_LEVEL_VERBOSE,
4532 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4533 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4534 PsGetCurrentThread());
4536 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4539 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4542 try_return( ntStatus);
4546 // Initialize the root information
4549 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4552 // Enumerate the shares in the volume
4555 ntStatus = AFSEnumerateDirectory( AuthGroup,
4556 &AFSGlobalRoot->ObjectInformation,
4559 if( !NT_SUCCESS( ntStatus))
4562 try_return( ntStatus);
4565 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4568 // Indicate the node is initialized
4571 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4573 uniFullName.MaximumLength = PAGE_SIZE;
4574 uniFullName.Length = 0;
4576 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4577 uniFullName.MaximumLength,
4578 AFS_GENERIC_MEMORY_12_TAG);
4580 if( uniFullName.Buffer == NULL)
4584 // Reset the directory content
4587 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4589 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4591 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4595 // Populate our list of entries in the NP enumeration list
4598 while( pDirGlobalDirNode != NULL)
4601 uniFullName.Buffer[ 0] = L'\\';
4602 uniFullName.Buffer[ 1] = L'\\';
4604 uniFullName.Length = 2 * sizeof( WCHAR);
4606 RtlCopyMemory( &uniFullName.Buffer[ 2],
4607 AFSServerName.Buffer,
4608 AFSServerName.Length);
4610 uniFullName.Length += AFSServerName.Length;
4612 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4614 uniFullName.Length += sizeof( WCHAR);
4616 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4617 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4618 pDirGlobalDirNode->NameInformation.FileName.Length);
4620 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4622 AFSAddConnectionEx( &uniFullName,
4623 RESOURCEDISPLAYTYPE_SHARE,
4626 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4629 AFSExFreePool( uniFullName.Buffer);
4633 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4640 AFSIsRelativeName( IN UNICODE_STRING *Name)
4643 BOOLEAN bIsRelative = FALSE;
4645 if( Name->Buffer[ 0] != L'\\')
4655 AFSUpdateName( IN UNICODE_STRING *Name)
4660 while( usIndex < Name->Length/sizeof( WCHAR))
4663 if( Name->Buffer[ usIndex] == L'/')
4666 Name->Buffer[ usIndex] = L'\\';
4676 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4677 IN OUT ULONG *Flags,
4678 IN WCHAR *NameBuffer,
4679 IN USHORT NameLength)
4682 NTSTATUS ntStatus = STATUS_SUCCESS;
4683 WCHAR *pTmpBuffer = NULL;
4689 // If we have enough space then just move in the name otherwise
4690 // allocate a new buffer
4693 if( TargetName->Length < NameLength)
4696 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4698 AFS_NAME_BUFFER_FIVE_TAG);
4700 if( pTmpBuffer == NULL)
4703 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4706 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4709 AFSExFreePool( TargetName->Buffer);
4712 TargetName->MaximumLength = NameLength;
4714 TargetName->Buffer = pTmpBuffer;
4716 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4719 TargetName->Length = NameLength;
4721 RtlCopyMemory( TargetName->Buffer,
4723 TargetName->Length);
4726 // Update the name in the buffer
4729 AFSUpdateName( TargetName);
4740 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4741 IN ULONG InitialElementCount)
4744 AFSNameArrayHdr *pNameArray = NULL;
4745 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4750 if( InitialElementCount == 0)
4753 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
4756 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
4757 sizeof( AFSNameArrayHdr) +
4758 (InitialElementCount * sizeof( AFSNameArrayCB)),
4759 AFS_NAME_ARRAY_TAG);
4761 if( pNameArray == NULL)
4764 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4765 AFS_TRACE_LEVEL_ERROR,
4766 "AFSInitNameArray Failed to allocate name array\n");
4768 try_return( pNameArray);
4771 RtlZeroMemory( pNameArray,
4772 sizeof( AFSNameArrayHdr) +
4773 (InitialElementCount * sizeof( AFSNameArrayCB)));
4775 pNameArray->MaxElementCount = InitialElementCount;
4777 if( DirectoryCB != NULL)
4780 pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
4782 InterlockedIncrement( &pNameArray->Count);
4784 InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
4786 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4787 AFS_TRACE_LEVEL_VERBOSE,
4788 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
4789 &DirectoryCB->NameInformation.FileName,
4791 DirectoryCB->OpenReferenceCount);
4793 pNameArray->CurrentEntry->DirectoryCB = DirectoryCB;
4795 pNameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
4797 pNameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
4809 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
4810 IN UNICODE_STRING *Path,
4811 IN AFSDirectoryCB *DirectoryCB)
4814 NTSTATUS ntStatus = STATUS_SUCCESS;
4815 AFSNameArrayCB *pCurrentElement = NULL;
4816 UNICODE_STRING uniComponentName, uniRemainingPath;
4817 AFSObjectInfoCB *pCurrentObject = NULL;
4818 ULONG ulTotalCount = 0;
4820 USHORT usLength = 0;
4826 // Init some info in the header
4829 pCurrentElement = &NameArray->ElementArray[ 0];
4831 NameArray->CurrentEntry = pCurrentElement;
4834 // The first entry points at the root
4837 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
4839 InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4841 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4842 AFS_TRACE_LEVEL_VERBOSE,
4843 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
4844 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4845 pCurrentElement->DirectoryCB,
4846 pCurrentElement->DirectoryCB->OpenReferenceCount);
4848 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
4850 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
4852 NameArray->Count = 1;
4854 NameArray->LinkCount = 0;
4857 // If the root is the parent then we are done ...
4860 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
4862 try_return( ntStatus);
4874 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
4875 IN AFSNameArrayHdr *RelatedNameArray,
4876 IN AFSDirectoryCB *DirectoryCB)
4879 NTSTATUS ntStatus = STATUS_SUCCESS;
4880 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
4881 UNICODE_STRING uniComponentName, uniRemainingPath;
4882 AFSObjectInfoCB *pObjectInfo = NULL;
4883 ULONG ulTotalCount = 0;
4885 USHORT usLength = 0;
4891 // Init some info in the header
4894 pCurrentElement = &NameArray->ElementArray[ 0];
4896 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
4898 NameArray->Count = 0;
4900 NameArray->LinkCount = RelatedNameArray->LinkCount;
4903 // Populate the name array with the data from the related array
4909 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
4911 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
4913 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
4915 InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4917 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4918 AFS_TRACE_LEVEL_VERBOSE,
4919 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
4920 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4921 pCurrentElement->DirectoryCB,
4922 pCurrentElement->DirectoryCB->OpenReferenceCount);
4924 InterlockedIncrement( &NameArray->Count);
4926 if( pCurrentElement->DirectoryCB == DirectoryCB ||
4927 NameArray->Count == RelatedNameArray->Count)
4939 pCurrentRelatedElement++;
4942 if( NameArray->Count > 0)
4944 NameArray->CurrentEntry = pCurrentElement;
4952 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
4955 NTSTATUS ntStatus = STATUS_SUCCESS;
4956 AFSNameArrayCB *pCurrentElement = NULL;
4961 pCurrentElement = &NameArray->ElementArray[ 0];
4966 if( pCurrentElement->DirectoryCB == NULL)
4972 InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4974 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4975 AFS_TRACE_LEVEL_VERBOSE,
4976 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
4977 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4978 pCurrentElement->DirectoryCB,
4979 pCurrentElement->DirectoryCB->OpenReferenceCount);
4984 AFSExFreePool( NameArray);
4991 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
4992 IN AFSDirectoryCB *DirEntry)
4995 NTSTATUS ntStatus = STATUS_SUCCESS;
4996 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5001 if( NameArray->Count == NameArray->MaxElementCount)
5004 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5007 if( NameArray->CurrentEntry != NULL &&
5008 NameArray->CurrentEntry->DirectoryCB == DirEntry)
5011 try_return( ntStatus);
5014 if( NameArray->Count > 0)
5017 NameArray->CurrentEntry++;
5021 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5024 InterlockedIncrement( &NameArray->Count);
5026 InterlockedIncrement( &DirEntry->OpenReferenceCount);
5028 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5029 AFS_TRACE_LEVEL_VERBOSE,
5030 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
5031 &DirEntry->NameInformation.FileName,
5033 DirEntry->OpenReferenceCount);
5035 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5037 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5039 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5050 AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
5051 IN AFSDirectoryCB *DirectoryCB)
5054 ASSERT( NameArray->CurrentEntry != NULL);
5056 InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5058 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5059 AFS_TRACE_LEVEL_VERBOSE,
5060 "AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
5061 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5062 NameArray->CurrentEntry->DirectoryCB,
5063 NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5065 InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5067 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5068 AFS_TRACE_LEVEL_VERBOSE,
5069 "AFSReplaceCurrentElement Increment count on %wZ DE %p Cnt %d\n",
5070 &DirectoryCB->NameInformation.FileName,
5072 DirectoryCB->OpenReferenceCount);
5074 NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
5076 NameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
5078 NameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
5080 if( DirectoryCB->ObjectInformation->ParentObjectInformation == NULL)
5083 SetFlag( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5090 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5093 AFSDirectoryCB *pCurrentDirEntry = NULL;
5098 if( NameArray->Count == 0)
5100 try_return( pCurrentDirEntry);
5103 InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5105 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5106 AFS_TRACE_LEVEL_VERBOSE,
5107 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5108 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5109 NameArray->CurrentEntry->DirectoryCB,
5110 NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5112 NameArray->CurrentEntry->DirectoryCB = NULL;
5114 if( InterlockedDecrement( &NameArray->Count) == 0)
5116 NameArray->CurrentEntry = NULL;
5120 NameArray->CurrentEntry--;
5121 pCurrentDirEntry = NameArray->CurrentEntry->DirectoryCB;
5129 return pCurrentDirEntry;
5133 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5136 AFSDirectoryCB *pDirEntry = NULL;
5137 AFSNameArrayCB *pElement = NULL;
5142 if( NameArray->Count == 0 ||
5143 NameArray->Count == 1)
5146 try_return( pDirEntry = NULL);
5149 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5151 pDirEntry = pElement->DirectoryCB;
5162 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5163 IN AFSDirectoryCB *DirEntry)
5166 AFSNameArrayCB *pCurrentElement = NULL;
5167 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5172 pCurrentElement = &NameArray->ElementArray[ 0];
5177 if( pCurrentElement->DirectoryCB == NULL)
5183 InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5185 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5186 AFS_TRACE_LEVEL_VERBOSE,
5187 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5188 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5189 pCurrentElement->DirectoryCB,
5190 pCurrentElement->DirectoryCB->OpenReferenceCount);
5195 RtlZeroMemory( NameArray,
5196 sizeof( AFSNameArrayHdr) +
5197 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5199 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5201 if( DirEntry != NULL)
5204 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5206 InterlockedIncrement( &NameArray->Count);
5208 InterlockedIncrement( &DirEntry->OpenReferenceCount);
5210 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5211 AFS_TRACE_LEVEL_VERBOSE,
5212 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5213 &DirEntry->NameInformation.FileName,
5215 DirEntry->OpenReferenceCount);
5217 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5219 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5221 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5229 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5232 AFSNameArrayCB *pCurrentElement = NULL;
5234 pCurrentElement = &NameArray->ElementArray[ 0];
5236 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5238 while( pCurrentElement->DirectoryCB != NULL)
5241 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5242 pCurrentElement->FileId.Cell,
5243 pCurrentElement->FileId.Volume,
5244 pCurrentElement->FileId.Vnode,
5245 pCurrentElement->FileId.Unique,
5246 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5251 AFSPrint("AFSDumpNameArray End\n\n");
5257 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5261 // Depending on the type of node, set the event
5264 switch( Fcb->Header.NodeTypeCode)
5267 case AFS_DIRECTORY_FCB:
5270 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5274 InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5283 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5287 InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5297 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5301 // Depending on the type of node, set the event
5304 switch( Fcb->Header.NodeTypeCode)
5307 case AFS_DIRECTORY_FCB:
5310 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5312 if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
5315 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5325 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5327 if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
5330 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5341 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5344 BOOLEAN bIsInProcess = FALSE;
5349 if( ObjectInfo->Fcb == NULL)
5352 try_return( bIsInProcess);
5356 // Depending on the type of node, set the event
5359 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5362 case AFS_DIRECTORY_FCB:
5365 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5368 bIsInProcess = TRUE;
5378 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5381 bIsInProcess = TRUE;
5393 return bIsInProcess;
5397 AFSVerifyVolume( IN ULONGLONG ProcessId,
5398 IN AFSVolumeCB *VolumeCB)
5401 NTSTATUS ntStatus = STATUS_SUCCESS;
5408 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5411 NTSTATUS ntStatus = STATUS_SUCCESS;
5412 AFSObjectInfoCB *pObjectInfoCB = NULL;
5413 AFSDirectoryCB *pDirNode = NULL;
5414 ULONG ulEntryLength = 0;
5415 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5420 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5423 if( pObjectInfoCB == NULL)
5426 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5429 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5430 AFS_TRACE_LEVEL_VERBOSE,
5431 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5434 pObjectInfoCB->ObjectReferenceCount = 1;
5436 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5438 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5440 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5442 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5446 if( pDirNode == NULL)
5449 AFSDeleteObjectInfo( pObjectInfoCB);
5451 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5454 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5455 sizeof( AFSNonPagedDirectoryCB),
5456 AFS_DIR_ENTRY_NP_TAG);
5458 if( pNonPagedDirEntry == NULL)
5461 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5464 RtlZeroMemory( pDirNode,
5467 RtlZeroMemory( pNonPagedDirEntry,
5468 sizeof( AFSNonPagedDirectoryCB));
5470 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5472 pDirNode->NonPaged = pNonPagedDirEntry;
5474 pDirNode->ObjectInformation = pObjectInfoCB;
5476 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5482 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5484 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5486 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5488 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5490 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5491 AFSPIOCtlName.Buffer,
5492 pDirNode->NameInformation.FileName.Length);
5494 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5497 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB = pDirNode;
5501 if ( !NT_SUCCESS( ntStatus))
5504 if ( pDirNode != NULL)
5507 AFSExFreePool( pDirNode);
5510 if ( pObjectInfoCB != NULL)
5513 AFSDeleteObjectInfo( pObjectInfoCB);
5522 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5523 IN AFSDirectoryCB *DirectoryCB,
5524 IN UNICODE_STRING *ParentPathName,
5525 IN AFSNameArrayHdr *RelatedNameArray,
5526 OUT AFSFileInfoCB *FileInfo)
5529 NTSTATUS ntStatus = STATUS_SUCCESS;
5530 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
5531 UNICODE_STRING uniFullPathName;
5532 AFSNameArrayHdr *pNameArray = NULL;
5533 AFSVolumeCB *pVolumeCB = NULL;
5534 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5535 WCHAR *pwchBuffer = NULL;
5536 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5537 ULONG ulNameDifference = 0;
5538 GUID *pAuthGroup = NULL;
5544 // Retrieve a target name for the entry
5547 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5550 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5553 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5555 if( ParentDirectoryCB->ObjectInformation->Fcb != NULL)
5557 pAuthGroup = &ParentDirectoryCB->ObjectInformation->Fcb->AuthGroup;
5559 else if( DirectoryCB->ObjectInformation->Fcb != NULL)
5561 pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
5564 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5569 if( !NT_SUCCESS( ntStatus) ||
5570 pDirEntry->TargetNameLength == 0)
5573 if( pDirEntry != NULL)
5576 ntStatus = STATUS_ACCESS_DENIED;
5579 try_return( ntStatus);
5582 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5585 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5589 // Update the target name
5592 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5593 &DirectoryCB->Flags,
5594 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5595 (USHORT)pDirEntry->TargetNameLength);
5597 if( !NT_SUCCESS( ntStatus))
5600 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5602 try_return( ntStatus);
5606 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5610 // Need to pass the full path in for parsing.
5613 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5616 uniFullPathName.Length = 0;
5617 uniFullPathName.MaximumLength = ParentPathName->Length +
5619 DirectoryCB->NameInformation.TargetName.Length;
5621 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5622 uniFullPathName.MaximumLength,
5623 AFS_NAME_BUFFER_SIX_TAG);
5625 if( uniFullPathName.Buffer == NULL)
5628 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5630 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5633 pwchBuffer = uniFullPathName.Buffer;
5635 RtlZeroMemory( uniFullPathName.Buffer,
5636 uniFullPathName.MaximumLength);
5638 RtlCopyMemory( uniFullPathName.Buffer,
5639 ParentPathName->Buffer,
5640 ParentPathName->Length);
5642 uniFullPathName.Length = ParentPathName->Length;
5644 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5645 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5648 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5650 uniFullPathName.Length += sizeof( WCHAR);
5653 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5654 DirectoryCB->NameInformation.TargetName.Buffer,
5655 DirectoryCB->NameInformation.TargetName.Length);
5657 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5659 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5660 uniParsedName.MaximumLength = uniParsedName.Length;
5662 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5664 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5667 // We populate up to the current parent
5670 if( RelatedNameArray != NULL)
5673 pNameArray = AFSInitNameArray( NULL,
5674 RelatedNameArray->MaxElementCount);
5676 if( pNameArray == NULL)
5679 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5682 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5689 pNameArray = AFSInitNameArray( NULL,
5692 if( pNameArray == NULL)
5695 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5698 ntStatus = AFSPopulateNameArray( pNameArray,
5703 if( !NT_SUCCESS( ntStatus))
5706 try_return( ntStatus);
5709 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5711 AFSAcquireShared( pVolumeCB->VolumeLock,
5714 pParentDirEntry = ParentDirectoryCB;
5719 uniFullPathName.Length = 0;
5720 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5722 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5723 uniFullPathName.MaximumLength,
5724 AFS_NAME_BUFFER_SEVEN_TAG);
5726 if( uniFullPathName.Buffer == NULL)
5729 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5731 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5734 pwchBuffer = uniFullPathName.Buffer;
5736 RtlZeroMemory( uniFullPathName.Buffer,
5737 uniFullPathName.MaximumLength);
5739 RtlCopyMemory( uniFullPathName.Buffer,
5740 DirectoryCB->NameInformation.TargetName.Buffer,
5741 DirectoryCB->NameInformation.TargetName.Length);
5743 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5746 // This name should begin with the \afs server so parse it off and check it
5749 FsRtlDissectName( uniFullPathName,
5753 if( RtlCompareUnicodeString( &uniComponentName,
5758 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5760 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5761 AFS_TRACE_LEVEL_ERROR,
5762 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5765 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5768 uniFullPathName = uniRemainingPath;
5770 uniParsedName = uniFullPathName;
5772 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5774 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5780 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5783 if( pNameArray == NULL)
5786 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5789 pVolumeCB = AFSGlobalRoot;
5791 AFSAcquireShared( pVolumeCB->VolumeLock,
5794 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5798 // Increment the ref count on the volume and dir entry for correct processing below
5801 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
5803 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5804 AFS_TRACE_LEVEL_VERBOSE,
5805 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
5807 pVolumeCB->VolumeReferenceCount);
5809 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
5811 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5812 AFS_TRACE_LEVEL_VERBOSE,
5813 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5814 &pParentDirEntry->NameInformation.FileName,
5817 pParentDirEntry->OpenReferenceCount);
5819 ntStatus = AFSLocateNameEntry( NULL,
5824 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5830 if( !NT_SUCCESS( ntStatus))
5834 // The volume lock was released on failure above
5835 // Except for STATUS_OBJECT_NAME_NOT_FOUND
5838 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
5841 if( pVolumeCB != NULL)
5844 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5846 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5847 AFS_TRACE_LEVEL_VERBOSE,
5848 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
5850 pVolumeCB->VolumeReferenceCount);
5852 AFSReleaseResource( pVolumeCB->VolumeLock);
5855 if( pDirectoryEntry != NULL)
5858 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5860 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5861 AFS_TRACE_LEVEL_VERBOSE,
5862 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5863 &pDirectoryEntry->NameInformation.FileName,
5866 pDirectoryEntry->OpenReferenceCount);
5871 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
5873 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5874 AFS_TRACE_LEVEL_VERBOSE,
5875 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5876 &pParentDirEntry->NameInformation.FileName,
5879 pParentDirEntry->OpenReferenceCount);
5885 try_return( ntStatus);
5889 // Store off the information
5892 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5895 // Check for the mount point being returned
5898 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
5901 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5903 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
5904 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5907 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5910 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5912 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5914 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5916 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5918 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5920 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5923 // Remove the reference made above
5926 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5928 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5929 AFS_TRACE_LEVEL_VERBOSE,
5930 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
5931 &pDirectoryEntry->NameInformation.FileName,
5934 pDirectoryEntry->OpenReferenceCount);
5938 if( pDirEntry != NULL)
5941 AFSExFreePool( pDirEntry);
5944 if( pVolumeCB != NULL)
5947 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5949 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5950 AFS_TRACE_LEVEL_VERBOSE,
5951 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
5953 pVolumeCB->VolumeReferenceCount);
5955 AFSReleaseResource( pVolumeCB->VolumeLock);
5958 if( pNameArray != NULL)
5961 AFSFreeNameArray( pNameArray);
5964 if( pwchBuffer != NULL)
5968 // Always free the buffer that we allocated as AFSLocateNameEntry
5969 // will not free it. If uniFullPathName.Buffer was allocated by
5970 // AFSLocateNameEntry, then we must free that as well.
5971 // Check that the uniFullPathName.Buffer in the string is not the same
5972 // offset by the length of the server name
5975 if( uniFullPathName.Length > 0 &&
5976 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
5979 AFSExFreePool( uniFullPathName.Buffer);
5982 AFSExFreePool( pwchBuffer);
5990 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
5991 IN ULONGLONG HashIndex)
5994 NTSTATUS ntStatus = STATUS_SUCCESS;
5995 AFSObjectInfoCB *pObjectInfo = NULL;
6000 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6001 sizeof( AFSObjectInfoCB),
6002 AFS_OBJECT_INFO_TAG);
6004 if( pObjectInfo == NULL)
6007 try_return( pObjectInfo);
6010 RtlZeroMemory( pObjectInfo,
6011 sizeof( AFSObjectInfoCB));
6013 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6014 sizeof( AFSNonPagedObjectInfoCB),
6015 AFS_NP_OBJECT_INFO_TAG);
6017 if( pObjectInfo->NonPagedInfo == NULL)
6020 AFSExFreePool( pObjectInfo);
6022 try_return( pObjectInfo = NULL);
6025 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6027 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6029 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6031 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6033 if( ParentObjectInfo != NULL)
6035 InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
6039 // Initialize the access time
6042 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6048 // Insert the entry into the object tree and list
6051 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6053 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6056 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6061 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6062 &pObjectInfo->TreeEntry);
6064 ASSERT( NT_SUCCESS( ntStatus));
6068 // And the object list in the volume
6071 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6074 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6079 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6081 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6084 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6087 // Indicate the object is in the hash tree and linked list in the volume
6090 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6102 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6105 BOOLEAN bAcquiredTreeLock = FALSE;
6107 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6110 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6112 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6115 bAcquiredTreeLock = TRUE;
6119 // Remove it from the tree and list if it was inserted
6122 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6125 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6126 &ObjectInfo->TreeEntry);
6129 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6132 if( ObjectInfo->ListEntry.fLink == NULL)
6135 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6137 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6140 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6146 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6149 if( ObjectInfo->ListEntry.bLink == NULL)
6152 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6154 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6157 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6163 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6167 if( ObjectInfo->ParentObjectInformation != NULL)
6169 InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
6172 if( bAcquiredTreeLock)
6175 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6179 // Release the fid in the service
6182 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6185 AFSReleaseFid( &ObjectInfo->FileId);
6188 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6190 AFSExFreePool( ObjectInfo->NonPagedInfo);
6192 AFSExFreePool( ObjectInfo);
6198 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6199 OUT AFSDirectoryCB **TargetDirEntry)
6202 NTSTATUS ntStatus = STATUS_SUCCESS;
6203 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6204 UNICODE_STRING uniFullPathName;
6205 AFSNameArrayHdr *pNameArray = NULL;
6206 AFSVolumeCB *pVolumeCB = NULL;
6207 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6208 WCHAR *pwchBuffer = NULL;
6209 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6210 ULONG ulNameDifference = 0;
6211 GUID *pAuthGroup = NULL;
6217 // Retrieve a target name for the entry
6220 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6223 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6226 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6228 if( DirectoryCB->ObjectInformation->Fcb != NULL)
6230 pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
6233 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6238 if( !NT_SUCCESS( ntStatus) ||
6239 pDirEntry->TargetNameLength == 0)
6242 if( pDirEntry != NULL)
6245 ntStatus = STATUS_ACCESS_DENIED;
6248 try_return( ntStatus);
6251 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6254 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6258 // Update the target name
6261 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6262 &DirectoryCB->Flags,
6263 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6264 (USHORT)pDirEntry->TargetNameLength);
6266 if( !NT_SUCCESS( ntStatus))
6269 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6271 try_return( ntStatus);
6275 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6279 // Need to pass the full path in for parsing.
6282 uniFullPathName.Length = 0;
6283 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6285 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6286 uniFullPathName.MaximumLength,
6287 AFS_NAME_BUFFER_EIGHT_TAG);
6289 if( uniFullPathName.Buffer == NULL)
6292 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6294 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6297 pwchBuffer = uniFullPathName.Buffer;
6299 RtlZeroMemory( uniFullPathName.Buffer,
6300 uniFullPathName.MaximumLength);
6302 RtlCopyMemory( uniFullPathName.Buffer,
6303 DirectoryCB->NameInformation.TargetName.Buffer,
6304 DirectoryCB->NameInformation.TargetName.Length);
6306 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6309 // This name should begin with the \afs server so parse it off and chech it
6312 FsRtlDissectName( uniFullPathName,
6316 if( RtlCompareUnicodeString( &uniComponentName,
6322 // Try evaluating the full path
6325 uniFullPathName.Buffer = pwchBuffer;
6327 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6329 uniFullPathName.MaximumLength = uniFullPathName.Length;
6334 uniFullPathName = uniRemainingPath;
6337 uniParsedName = uniFullPathName;
6339 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6341 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6347 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6350 if( pNameArray == NULL)
6353 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6356 pVolumeCB = AFSGlobalRoot;
6358 AFSAcquireShared( pVolumeCB->VolumeLock,
6361 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6363 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6365 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6366 AFS_TRACE_LEVEL_VERBOSE,
6367 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6369 pVolumeCB->VolumeReferenceCount);
6371 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6373 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6374 AFS_TRACE_LEVEL_VERBOSE,
6375 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6376 &pParentDirEntry->NameInformation.FileName,
6379 pParentDirEntry->OpenReferenceCount);
6381 ntStatus = AFSLocateNameEntry( NULL,
6392 if( !NT_SUCCESS( ntStatus))
6396 // The volume lock was released on failure above
6397 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6400 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6403 if( pVolumeCB != NULL)
6406 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6408 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6409 AFS_TRACE_LEVEL_VERBOSE,
6410 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
6412 pVolumeCB->VolumeReferenceCount);
6414 AFSReleaseResource( pVolumeCB->VolumeLock);
6417 if( pDirectoryEntry != NULL)
6420 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6422 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6423 AFS_TRACE_LEVEL_VERBOSE,
6424 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6425 &pDirectoryEntry->NameInformation.FileName,
6428 pDirectoryEntry->OpenReferenceCount);
6433 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6435 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6436 AFS_TRACE_LEVEL_VERBOSE,
6437 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6438 &pParentDirEntry->NameInformation.FileName,
6441 pParentDirEntry->OpenReferenceCount);
6447 try_return( ntStatus);
6451 // Pass back the target dir entry for this request
6454 *TargetDirEntry = pDirectoryEntry;
6458 if( pDirEntry != NULL)
6461 AFSExFreePool( pDirEntry);
6464 if( pVolumeCB != NULL)
6467 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6469 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6470 AFS_TRACE_LEVEL_VERBOSE,
6471 "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
6473 pVolumeCB->VolumeReferenceCount);
6475 AFSReleaseResource( pVolumeCB->VolumeLock);
6478 if( pNameArray != NULL)
6481 AFSFreeNameArray( pNameArray);
6484 if( pwchBuffer != NULL)
6488 // Always free the buffer that we allocated as AFSLocateNameEntry
6489 // will not free it. If uniFullPathName.Buffer was allocated by
6490 // AFSLocateNameEntry, then we must free that as well.
6491 // Check that the uniFullPathName.Buffer in the string is not the same
6492 // offset by the length of the server name
6495 if( uniFullPathName.Length > 0 &&
6496 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6499 AFSExFreePool( uniFullPathName.Buffer);
6502 AFSExFreePool( pwchBuffer);
6510 AFSCleanupFcb( IN AFSFcb *Fcb,
6511 IN BOOLEAN ForceFlush)
6514 NTSTATUS ntStatus = STATUS_SUCCESS;
6515 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6516 LARGE_INTEGER liTime;
6517 IO_STATUS_BLOCK stIoStatus;
6522 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6524 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6526 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6529 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6530 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6533 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6536 if( Fcb->OpenReferenceCount > 0)
6542 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6547 if( !NT_SUCCESS( stIoStatus.Status))
6550 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6551 AFS_TRACE_LEVEL_ERROR,
6552 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6553 Fcb->ObjectInformation->FileId.Cell,
6554 Fcb->ObjectInformation->FileId.Volume,
6555 Fcb->ObjectInformation->FileId.Vnode,
6556 Fcb->ObjectInformation->FileId.Unique,
6558 stIoStatus.Information);
6560 ntStatus = stIoStatus.Status;
6563 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6568 __except( EXCEPTION_EXECUTE_HANDLER)
6570 ntStatus = GetExceptionCode();
6574 AFSReleaseResource( &Fcb->NPFcb->Resource);
6577 // Wait for any currently running flush or release requests to complete
6580 AFSWaitOnQueuedFlushes( Fcb);
6583 // Now perform another flush on the file
6586 if( !NT_SUCCESS( AFSFlushExtents( Fcb)))
6589 AFSReleaseExtentsWithFlush( Fcb);
6593 if( Fcb->OpenReferenceCount == 0 ||
6594 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6595 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6598 AFSTearDownFcbExtents( Fcb);
6601 try_return( ntStatus);
6604 KeQueryTickCount( &liTime);
6607 // First up are there dirty extents in the cache to flush?
6611 ( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6612 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
6613 ( Fcb->Specific.File.ExtentsDirtyCount ||
6614 Fcb->Specific.File.ExtentCount) &&
6615 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6616 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6619 if( !NT_SUCCESS( AFSFlushExtents( Fcb)) &&
6620 Fcb->OpenReferenceCount == 0)
6623 AFSReleaseExtentsWithFlush( Fcb);
6626 else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6627 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6631 // The file has been marked as invalid. Dump it
6634 AFSTearDownFcbExtents( Fcb);
6638 // If there are extents and they haven't been used recently *and*
6639 // are not being used
6643 ( 0 != Fcb->Specific.File.ExtentCount &&
6644 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6645 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6646 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
6647 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6654 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6659 if( !NT_SUCCESS( stIoStatus.Status))
6662 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6663 AFS_TRACE_LEVEL_ERROR,
6664 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6665 Fcb->ObjectInformation->FileId.Cell,
6666 Fcb->ObjectInformation->FileId.Volume,
6667 Fcb->ObjectInformation->FileId.Vnode,
6668 Fcb->ObjectInformation->FileId.Unique,
6670 stIoStatus.Information);
6672 ntStatus = stIoStatus.Status;
6678 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6684 __except( EXCEPTION_EXECUTE_HANDLER)
6686 ntStatus = GetExceptionCode();
6689 AFSReleaseResource( &Fcb->NPFcb->Resource);
6691 if( Fcb->OpenReferenceCount == 0)
6695 // Tear em down we'll not be needing them again
6698 AFSTearDownFcbExtents( Fcb);
6711 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
6712 IN UNICODE_STRING *NewFileName)
6715 NTSTATUS ntStatus = STATUS_SUCCESS;
6716 WCHAR *pTmpBuffer = NULL;
6721 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
6724 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
6727 AFSExFreePool( DirectoryCB->NameInformation.FileName.Buffer);
6729 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6731 DirectoryCB->NameInformation.FileName.Buffer = NULL;
6735 // OK, we need to allocate a new name buffer
6738 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6739 NewFileName->Length,
6740 AFS_NAME_BUFFER_NINE_TAG);
6742 if( pTmpBuffer == NULL)
6745 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6748 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
6750 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
6752 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6755 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
6757 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
6758 NewFileName->Buffer,
6759 NewFileName->Length);
6770 AFSReadCacheFile( IN void *ReadBuffer,
6771 IN LARGE_INTEGER *ReadOffset,
6772 IN ULONG RequestedDataLength,
6773 IN OUT PULONG BytesRead)
6776 NTSTATUS ntStatus = STATUS_SUCCESS;
6779 PIO_STACK_LOCATION pIoStackLocation = NULL;
6780 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6781 DEVICE_OBJECT *pTargetDeviceObject = NULL;
6782 FILE_OBJECT *pCacheFileObject = NULL;
6787 pCacheFileObject = AFSReferenceCacheFileObject();
6789 if( pCacheFileObject == NULL)
6791 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
6794 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
6797 // Initialize the event
6800 KeInitializeEvent( &kEvent,
6801 SynchronizationEvent,
6805 // Allocate an irp for this request. This could also come from a
6806 // private pool, for instance.
6809 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
6815 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6819 // Build the IRP's main body
6822 pIrp->UserBuffer = ReadBuffer;
6824 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
6825 pIrp->RequestorMode = KernelMode;
6826 pIrp->Flags |= IRP_READ_OPERATION;
6829 // Set up the I/O stack location.
6832 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
6833 pIoStackLocation->MajorFunction = IRP_MJ_READ;
6834 pIoStackLocation->DeviceObject = pTargetDeviceObject;
6835 pIoStackLocation->FileObject = pCacheFileObject;
6836 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
6838 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
6841 // Set the completion routine.
6844 IoSetCompletionRoutine( pIrp,
6852 // Send it to the FSD
6855 ntStatus = IoCallDriver( pTargetDeviceObject,
6858 if( NT_SUCCESS( ntStatus))
6865 ntStatus = KeWaitForSingleObject( &kEvent,
6871 if( NT_SUCCESS( ntStatus))
6874 ntStatus = pIrp->IoStatus.Status;
6876 *BytesRead = (ULONG)pIrp->IoStatus.Information;
6882 if( pCacheFileObject != NULL)
6884 AFSReleaseCacheFileObject( pCacheFileObject);
6890 if( pIrp->MdlAddress != NULL)
6893 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
6896 MmUnlockPages( pIrp->MdlAddress);
6899 IoFreeMdl( pIrp->MdlAddress);
6902 pIrp->MdlAddress = NULL;
6916 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
6921 KEVENT *pEvent = (KEVENT *)Context;
6927 return STATUS_MORE_PROCESSING_REQUIRED;
6931 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
6934 BOOLEAN bIsEmpty = FALSE;
6935 AFSDirectoryCB *pDirEntry = NULL;
6940 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
6945 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
6948 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
6950 while( pDirEntry != NULL)
6953 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
6954 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
6962 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
6967 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
6974 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
6975 IN AFSDirectoryCB *DirEntry)
6978 NTSTATUS ntStatus = STATUS_SUCCESS;
6983 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
6986 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6987 AFS_TRACE_LEVEL_VERBOSE,
6988 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
6990 &DirEntry->NameInformation.FileName);
6992 try_return( ntStatus);
6995 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
6998 // Remove the entry from the parent tree
7001 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7002 AFS_TRACE_LEVEL_VERBOSE,
7003 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7005 &DirEntry->NameInformation.FileName);
7007 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7010 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7011 AFS_TRACE_LEVEL_VERBOSE,
7012 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7014 &DirEntry->NameInformation.FileName);
7016 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7019 if( ParentObjectInfo->Specific.Directory.ShortNameTree &&
7020 DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
7024 // From the short name tree
7027 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7028 AFS_TRACE_LEVEL_VERBOSE,
7029 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7031 &DirEntry->NameInformation.FileName);
7033 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7037 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7038 AFS_TRACE_LEVEL_VERBOSE,
7039 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7041 &DirEntry->NameInformation.FileName);
7043 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7054 AFSGetAuthenticationId()
7057 LARGE_INTEGER liAuthId = {0,0};
7058 NTSTATUS ntStatus = STATUS_SUCCESS;
7059 PACCESS_TOKEN hToken = NULL;
7060 PTOKEN_STATISTICS pTokenInfo = NULL;
7061 BOOLEAN bCopyOnOpen = FALSE;
7062 BOOLEAN bEffectiveOnly = FALSE;
7063 BOOLEAN bPrimaryToken = FALSE;
7064 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7069 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7072 &stImpersonationLevel);
7077 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7082 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7083 AFS_TRACE_LEVEL_ERROR,
7084 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7086 try_return( ntStatus);
7089 bPrimaryToken = TRUE;
7092 ntStatus = SeQueryInformationToken( hToken,
7094 (PVOID *)&pTokenInfo);
7096 if( !NT_SUCCESS( ntStatus))
7099 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7100 AFS_TRACE_LEVEL_ERROR,
7101 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7103 try_return( ntStatus);
7106 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7107 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7109 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7110 AFS_TRACE_LEVEL_VERBOSE,
7111 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7122 PsDereferenceImpersonationToken( hToken);
7127 PsDereferencePrimaryToken( hToken);
7131 if( pTokenInfo != NULL)
7134 AFSExFreePool( pTokenInfo);
7142 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7146 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7148 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7151 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7153 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7156 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7158 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7161 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7163 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7166 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7168 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7175 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7178 BOOLEAN bIsValid = TRUE;
7180 AFSDirectoryCB *pCurrentDirEntry = NULL;
7182 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7184 while( pCurrentDirEntry != NULL)
7187 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7192 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7195 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7198 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7200 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7202 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7211 AFSReferenceCacheFileObject()
7214 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7215 FILE_OBJECT *pCacheFileObject = NULL;
7217 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7220 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7222 if( pCacheFileObject != NULL)
7224 ObReferenceObject( pCacheFileObject);
7227 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7229 return pCacheFileObject;
7233 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7236 ASSERT( CacheFileObject != NULL);
7238 ObDereferenceObject( CacheFileObject);
7244 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7247 NTSTATUS ntStatus = STATUS_SUCCESS;
7248 AFSDeviceExt *pControlDevExt = NULL;
7249 ULONG ulTimeIncrement = 0;
7254 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7256 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7258 AFSServerName = LibraryInit->AFSServerName;
7260 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7263 // Callbacks in the framework
7266 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7268 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7270 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7272 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7274 AFSExFreePool = LibraryInit->AFSExFreePool;
7276 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7278 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7280 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7282 if( LibraryInit->AFSCacheBaseAddress != NULL)
7285 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7287 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7289 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7293 // Initialize some flush parameters
7296 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7298 ulTimeIncrement = KeQueryTimeIncrement();
7300 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7301 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_ONE_SECOND;
7302 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart *= AFS_SERVER_PURGE_DELAY;
7303 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7304 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)(AFS_ONE_SECOND * AFS_SERVER_FLUSH_DELAY) / (ULONGLONG)ulTimeIncrement);
7305 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7308 // Initialize the global root entry
7311 ntStatus = AFSInitVolume( NULL,
7312 &LibraryInit->GlobalRootFid,
7315 if( !NT_SUCCESS( ntStatus))
7318 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7319 AFS_TRACE_LEVEL_ERROR,
7320 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7323 try_return( ntStatus);
7326 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7329 if( !NT_SUCCESS( ntStatus))
7332 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7333 AFS_TRACE_LEVEL_ERROR,
7334 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7337 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7339 try_return( ntStatus);
7343 // Update the node type code to AFS_ROOT_ALL
7346 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7348 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7351 // Drop the locks acquired above
7354 AFSInitVolumeWorker( AFSGlobalRoot);
7356 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7358 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7372 NTSTATUS ntStatus = STATUS_SUCCESS;
7373 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7378 if( AFSGlobalDotDirEntry != NULL)
7381 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
7383 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7385 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7387 ExFreePool( AFSGlobalDotDirEntry);
7389 AFSGlobalDotDirEntry = NULL;
7392 if( AFSGlobalDotDotDirEntry != NULL)
7395 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
7397 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7399 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7401 ExFreePool( AFSGlobalDotDotDirEntry);
7403 AFSGlobalDotDotDirEntry = NULL;
7406 if( AFSSpecialShareNames != NULL)
7409 pDirNode = AFSSpecialShareNames;
7411 while( pDirNode != NULL)
7414 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7416 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
7418 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7420 ExFreePool( pDirNode->NonPaged);
7422 ExFreePool( pDirNode);
7424 pDirNode = pLastDirNode;
7427 AFSSpecialShareNames = NULL;
7435 AFSDefaultLogMsg( IN ULONG Subsystem,
7441 NTSTATUS ntStatus = STATUS_SUCCESS;
7443 char chDebugBuffer[ 256];
7448 va_start( va_args, Format);
7450 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7455 if( NT_SUCCESS( ntStatus))
7457 DbgPrint( chDebugBuffer);
7467 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7468 IN ULONG InputBufferLength,
7469 IN AFSStatusInfoCB *StatusInfo,
7470 OUT ULONG *ReturnLength)
7473 NTSTATUS ntStatus = STATUS_SUCCESS;
7474 AFSFcb *pFcb = NULL;
7475 AFSVolumeCB *pVolumeCB = NULL;
7476 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7477 AFSObjectInfoCB *pObjectInfo = NULL;
7478 ULONGLONG ullIndex = 0;
7479 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7480 AFSNameArrayHdr *pNameArray = NULL;
7481 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7487 // If we are given a FID then look up the entry by that, otherwise
7491 if( GetStatusInfo->FileID.Cell != 0 &&
7492 GetStatusInfo->FileID.Volume != 0 &&
7493 GetStatusInfo->FileID.Vnode != 0 &&
7494 GetStatusInfo->FileID.Unique != 0)
7497 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7500 // Locate the volume node
7503 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7505 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7507 (AFSBTreeEntry **)&pVolumeCB);
7509 if( pVolumeCB != NULL)
7512 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7514 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7515 AFS_TRACE_LEVEL_VERBOSE,
7516 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7518 pVolumeCB->VolumeReferenceCount);
7521 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7523 if( !NT_SUCCESS( ntStatus) ||
7526 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7529 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
7532 pObjectInfo = &pVolumeCB->ObjectInformation;
7534 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7536 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7541 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
7544 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7546 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7547 AFS_TRACE_LEVEL_VERBOSE,
7548 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7550 pVolumeCB->VolumeReferenceCount);
7552 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
7554 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
7556 (AFSBTreeEntry **)&pObjectInfo);
7558 if( pObjectInfo != NULL)
7562 // Reference the node so it won't be torn down
7565 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7567 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7568 AFS_TRACE_LEVEL_VERBOSE,
7569 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
7571 pObjectInfo->ObjectReferenceCount);
7574 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
7576 if( !NT_SUCCESS( ntStatus) ||
7577 pObjectInfo == NULL)
7579 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7586 if( GetStatusInfo->FileNameLength == 0 ||
7587 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
7589 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7592 uniFullPathName.Length = GetStatusInfo->FileNameLength;
7593 uniFullPathName.MaximumLength = uniFullPathName.Length;
7595 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
7598 // This name should begin with the \afs server so parse it off and check it
7601 FsRtlDissectName( uniFullPathName,
7605 if( RtlCompareUnicodeString( &uniComponentName,
7609 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7610 AFS_TRACE_LEVEL_ERROR,
7611 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
7614 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
7617 uniFullPathName = uniRemainingPath;
7619 uniParsedName = uniFullPathName;
7625 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7628 if( pNameArray == NULL)
7630 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7633 pVolumeCB = AFSGlobalRoot;
7635 AFSAcquireShared( pVolumeCB->VolumeLock,
7638 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7641 // Increment the ref count on the volume and dir entry for correct processing below
7644 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7646 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7647 AFS_TRACE_LEVEL_VERBOSE,
7648 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7650 pVolumeCB->VolumeReferenceCount);
7652 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
7654 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7655 AFS_TRACE_LEVEL_VERBOSE,
7656 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7657 &pParentDirEntry->NameInformation.FileName,
7660 pParentDirEntry->OpenReferenceCount);
7662 ntStatus = AFSLocateNameEntry( NULL,
7667 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
7668 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
7674 if( !NT_SUCCESS( ntStatus))
7678 // The volume lock was released on failure above
7679 // Except for STATUS_OBJECT_NAME_NOT_FOUND
7682 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
7685 if( pVolumeCB != NULL)
7688 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7690 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7691 AFS_TRACE_LEVEL_VERBOSE,
7692 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7694 pVolumeCB->VolumeReferenceCount);
7696 AFSReleaseResource( pVolumeCB->VolumeLock);
7699 if( pDirectoryEntry != NULL)
7702 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7704 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7705 AFS_TRACE_LEVEL_VERBOSE,
7706 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7707 &pDirectoryEntry->NameInformation.FileName,
7710 pDirectoryEntry->OpenReferenceCount);
7715 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
7717 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7718 AFS_TRACE_LEVEL_VERBOSE,
7719 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7720 &pParentDirEntry->NameInformation.FileName,
7723 pParentDirEntry->OpenReferenceCount);
7729 try_return( ntStatus);
7733 // Remove the reference made above
7736 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7738 pObjectInfo = pDirectoryEntry->ObjectInformation;
7740 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7742 if( pVolumeCB != NULL)
7745 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7747 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7748 AFS_TRACE_LEVEL_VERBOSE,
7749 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
7751 pVolumeCB->VolumeReferenceCount);
7753 AFSReleaseResource( pVolumeCB->VolumeLock);
7758 // At this point we have an object info block, return the information
7761 StatusInfo->FileId = pObjectInfo->FileId;
7763 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
7765 StatusInfo->Expiration = pObjectInfo->Expiration;
7767 StatusInfo->DataVersion = pObjectInfo->DataVersion;
7769 StatusInfo->FileType = pObjectInfo->FileType;
7771 StatusInfo->ObjectFlags = pObjectInfo->Flags;
7773 StatusInfo->CreationTime = pObjectInfo->CreationTime;
7775 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
7777 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
7779 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
7781 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
7783 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
7785 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
7787 StatusInfo->EaSize = pObjectInfo->EaSize;
7789 StatusInfo->Links = pObjectInfo->Links;
7792 // Return the information length
7795 *ReturnLength = sizeof( AFSStatusInfoCB);
7799 if( pObjectInfo != NULL)
7802 InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
7805 if( pNameArray != NULL)
7808 AFSFreeNameArray( pNameArray);
7816 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
7817 IN UNICODE_STRING *ComponentName)
7820 NTSTATUS ntStatus = STATUS_SUCCESS;
7821 AFSDirectoryCB *pDirEntry = NULL;
7828 // Search for the entry in the parent
7831 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7832 AFS_TRACE_LEVEL_VERBOSE_2,
7833 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
7836 ulCRC = AFSGenerateCRC( ComponentName,
7839 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7842 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7846 if( pDirEntry == NULL)
7850 // Missed so perform a case insensitive lookup
7853 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7854 AFS_TRACE_LEVEL_VERBOSE_2,
7855 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
7858 ulCRC = AFSGenerateCRC( ComponentName,
7861 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7865 if( pDirEntry == NULL)
7869 // OK, if this component is a valid short name then try
7870 // a lookup in the short name tree
7873 if( RtlIsNameLegalDOS8Dot3( ComponentName,
7878 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7879 AFS_TRACE_LEVEL_VERBOSE_2,
7880 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
7883 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
7890 if( pDirEntry != NULL)
7892 InterlockedIncrement( &pDirEntry->OpenReferenceCount);
7895 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7897 if( pDirEntry == NULL)
7900 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7901 AFS_TRACE_LEVEL_VERBOSE_2,
7902 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
7905 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
7909 // We have the symlink object but previously failed to process it so return access
7913 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7914 AFS_TRACE_LEVEL_VERBOSE_2,
7915 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ ACCESS_DENIED\n",
7918 ntStatus = STATUS_ACCESS_DENIED;
7920 InterlockedDecrement( &pDirEntry->OpenReferenceCount);
7931 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
7932 OUT UNICODE_STRING *ComponentName)
7935 NTSTATUS ntStatus = STATUS_SUCCESS;
7936 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
7938 uniFullPathName = *FullPathName;
7943 FsRtlDissectName( uniFullPathName,
7947 if( uniRemainingPath.Length == 0)
7952 uniFullPathName = uniRemainingPath;
7955 if( uniComponentName.Length > 0)
7957 *ComponentName = uniComponentName;
7964 AFSDumpTraceFiles_Default()
7970 AFSValidNameFormat( IN UNICODE_STRING *FileName)
7973 BOOLEAN bIsValidName = TRUE;
7979 while( usIndex < FileName->Length/sizeof( WCHAR))
7982 if( FileName->Buffer[ usIndex] == L':' ||
7983 FileName->Buffer[ usIndex] == L'*' ||
7984 FileName->Buffer[ usIndex] == L'?' ||
7985 FileName->Buffer[ usIndex] == L'"' ||
7986 FileName->Buffer[ usIndex] == L'<' ||
7987 FileName->Buffer[ usIndex] == L'>')
7989 bIsValidName = FALSE;
7997 return bIsValidName;
8001 AFSCreateDefaultSecurityDescriptor()
8004 NTSTATUS ntStatus = STATUS_SUCCESS;
8006 ULONG ulSACLSize = 0;
8007 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8008 ULONG ulACESize = 0;
8009 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8010 ULONG ulSDLength = 0;
8011 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8016 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8019 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8024 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8026 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8028 AFS_GENERIC_MEMORY_29_TAG);
8033 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8035 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8038 RtlZeroMemory( pACE,
8041 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8042 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8043 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8044 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8046 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8048 SeExports->SeLowMandatorySid);
8050 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8051 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8053 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8055 AFS_GENERIC_MEMORY_29_TAG);
8060 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8062 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8065 ntStatus = RtlCreateAcl( pSACL,
8069 if( !NT_SUCCESS( ntStatus))
8072 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8075 try_return( ntStatus);
8078 ntStatus = RtlAddAce( pSACL,
8082 pACE->Header.AceSize);
8084 if( !NT_SUCCESS( ntStatus))
8087 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8090 try_return( ntStatus);
8094 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8095 sizeof( SECURITY_DESCRIPTOR),
8096 AFS_GENERIC_MEMORY_27_TAG);
8098 if( pSecurityDescr == NULL)
8101 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8103 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8106 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8107 SECURITY_DESCRIPTOR_REVISION);
8109 if( !NT_SUCCESS( ntStatus))
8112 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8115 try_return( ntStatus);
8118 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8120 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8125 if( !NT_SUCCESS( ntStatus))
8128 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8131 try_return( ntStatus);
8135 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8138 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8140 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8143 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8145 AFS_GENERIC_MEMORY_27_TAG);
8147 if( pRelativeSecurityDescr == NULL)
8150 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8152 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8155 ulSDLength = PAGE_SIZE;
8157 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8158 pRelativeSecurityDescr,
8161 if( !NT_SUCCESS( ntStatus))
8164 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8167 try_return( ntStatus);
8170 AFSDefaultSD = pRelativeSecurityDescr;
8174 if( !NT_SUCCESS( ntStatus))
8177 if( pRelativeSecurityDescr != NULL)
8179 ExFreePool( pRelativeSecurityDescr);
8183 if( pSecurityDescr != NULL)
8185 ExFreePool( pSecurityDescr);