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: AFSGenerateCRC
331 // Given a device and filename this function generates a CRC
335 // A status is returned for the function
339 AFSGenerateCRC( IN PUNICODE_STRING FileName,
340 IN BOOLEAN UpperCaseName)
344 NTSTATUS ntStatus = STATUS_SUCCESS;
346 ntStatus = RtlHashUnicodeString( FileName,
348 HASH_STRING_ALGORITHM_DEFAULT,
351 if( !NT_SUCCESS( ntStatus))
360 AFSLockSystemBuffer( IN PIRP Irp,
364 NTSTATUS Status = STATUS_SUCCESS;
365 void *pAddress = NULL;
367 if( Irp->MdlAddress != NULL)
370 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
373 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
376 pAddress = Irp->AssociatedIrp.SystemBuffer;
378 else if( Irp->UserBuffer != NULL)
381 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
387 if( Irp->MdlAddress != NULL)
391 // Lock the new Mdl in memory.
396 PIO_STACK_LOCATION pIoStack;
397 pIoStack = IoGetCurrentIrpStackLocation( Irp);
400 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
401 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
403 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
406 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
409 IoFreeMdl( Irp->MdlAddress );
410 Irp->MdlAddress = NULL;
420 AFSLockUserBuffer( IN void *UserBuffer,
421 IN ULONG BufferLength,
425 NTSTATUS ntStatus = STATUS_SUCCESS;
426 void *pAddress = NULL;
432 pMdl = IoAllocateMdl( UserBuffer,
441 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
445 // Lock the new Mdl in memory.
451 MmProbeAndLockPages( pMdl,
455 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
458 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
481 AFSMapToService( IN PIRP Irp,
485 NTSTATUS ntStatus = STATUS_SUCCESS;
486 void *pMappedBuffer = NULL;
487 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
493 if( pDevExt->Specific.Control.ServiceProcess == NULL)
496 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
499 if( Irp->MdlAddress == NULL)
502 if( AFSLockSystemBuffer( Irp,
506 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
511 // Attach to the service process for mapping
514 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
515 (PRKAPC_STATE)&stApcState);
517 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
524 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
531 return pMappedBuffer;
535 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
539 NTSTATUS ntStatus = STATUS_SUCCESS;
540 void *pMappedBuffer = NULL;
541 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
547 if( pDevExt->Specific.Control.ServiceProcess == NULL)
550 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
557 // Attach to the service process for mapping
560 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
561 (PRKAPC_STATE)&stApcState);
563 MmUnmapLockedPages( MappedBuffer,
566 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
578 AFSInitializeLibraryDevice()
581 NTSTATUS ntStatus = STATUS_SUCCESS;
582 AFSDeviceExt *pDeviceExt = NULL;
587 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
590 // The PIOCtl file name
593 RtlInitUnicodeString( &AFSPIOCtlName,
594 AFS_PIOCTL_FILE_INTERFACE_NAME);
597 // And the global root share name
600 RtlInitUnicodeString( &AFSGlobalRootName,
601 AFS_GLOBAL_ROOT_SHARE_NAME);
609 AFSRemoveLibraryDevice()
612 NTSTATUS ntStatus = STATUS_SUCCESS;
623 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
627 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
628 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
630 AFSCompleteRequest( Irp,
637 AFSInitializeGlobalDirectoryEntries()
640 NTSTATUS ntStatus = STATUS_SUCCESS;
641 AFSDirectoryCB *pDirNode = NULL;
642 ULONG ulEntryLength = 0;
643 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
644 AFSObjectInfoCB *pObjectInfoCB = NULL;
645 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
652 // Initialize the global . entry
655 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
658 if( pObjectInfoCB == NULL)
661 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
662 AFS_TRACE_LEVEL_ERROR,
663 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
666 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
669 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
671 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
672 AFS_TRACE_LEVEL_VERBOSE,
673 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
677 ntStatus = STATUS_SUCCESS;
679 ulEntryLength = sizeof( AFSDirectoryCB) +
682 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
686 if( pDirNode == NULL)
689 AFSDeleteObjectInfo( pObjectInfoCB);
691 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
692 AFS_TRACE_LEVEL_ERROR,
693 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
695 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
698 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
699 sizeof( AFSNonPagedDirectoryCB),
700 AFS_DIR_ENTRY_NP_TAG);
702 if( pNonPagedDirEntry == NULL)
705 ExFreePool( pDirNode);
707 AFSDeleteObjectInfo( pObjectInfoCB);
709 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
710 AFS_TRACE_LEVEL_ERROR,
711 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
713 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
716 RtlZeroMemory( pDirNode,
719 RtlZeroMemory( pNonPagedDirEntry,
720 sizeof( AFSNonPagedDirectoryCB));
722 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
724 pDirNode->NonPaged = pNonPagedDirEntry;
726 pDirNode->ObjectInformation = pObjectInfoCB;
732 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
734 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
737 // Setup the names in the entry
740 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
742 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
744 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
746 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
749 // Populate the rest of the data
752 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
754 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
756 AFSGlobalDotDirEntry = pDirNode;
762 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
765 if( pObjectInfoCB == NULL)
768 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
769 AFS_TRACE_LEVEL_ERROR,
770 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
773 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
776 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
778 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
779 AFS_TRACE_LEVEL_VERBOSE,
780 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
784 ntStatus = STATUS_SUCCESS;
786 ulEntryLength = sizeof( AFSDirectoryCB) +
787 ( 2 * sizeof( WCHAR));
789 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
793 if( pDirNode == NULL)
796 AFSDeleteObjectInfo( pObjectInfoCB);
798 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
801 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
802 sizeof( AFSNonPagedDirectoryCB),
803 AFS_DIR_ENTRY_NP_TAG);
805 if( pNonPagedDirEntry == NULL)
808 ExFreePool( pDirNode);
810 AFSDeleteObjectInfo( pObjectInfoCB);
812 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
815 RtlZeroMemory( pDirNode,
818 RtlZeroMemory( pNonPagedDirEntry,
819 sizeof( AFSNonPagedDirectoryCB));
821 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
823 pDirNode->NonPaged = pNonPagedDirEntry;
825 pDirNode->ObjectInformation = pObjectInfoCB;
831 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
833 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
836 // Setup the names in the entry
839 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
841 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
843 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
845 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
847 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
850 // Populate the rest of the data
853 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
855 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
857 AFSGlobalDotDotDirEntry = pDirNode;
861 if( !NT_SUCCESS( ntStatus))
864 if( AFSGlobalDotDirEntry != NULL)
867 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
869 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
871 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
873 ExFreePool( AFSGlobalDotDirEntry);
875 AFSGlobalDotDirEntry = NULL;
878 if( AFSGlobalDotDotDirEntry != NULL)
881 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
883 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
885 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
887 ExFreePool( AFSGlobalDotDotDirEntry);
889 AFSGlobalDotDotDirEntry = NULL;
898 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
899 IN PUNICODE_STRING FileName,
900 IN PUNICODE_STRING TargetName,
901 IN AFSDirEnumEntry *DirEnumEntry,
905 AFSDirectoryCB *pDirNode = NULL;
906 NTSTATUS ntStatus = STATUS_SUCCESS;
907 ULONG ulEntryLength = 0;
908 AFSDirEnumEntry *pDirEnumCB = NULL;
909 AFSFileID stTargetFileID;
911 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
912 AFSObjectInfoCB *pObjectInfoCB = NULL;
913 BOOLEAN bAllocatedObjectCB = FALSE;
914 ULONGLONG ullIndex = 0;
915 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
921 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
922 AFS_TRACE_LEVEL_VERBOSE,
923 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
925 ParentObjectInfo->FileId.Cell,
926 ParentObjectInfo->FileId.Volume,
927 ParentObjectInfo->FileId.Vnode,
928 ParentObjectInfo->FileId.Unique);
931 // First thing is to locate/create our object information block
935 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
938 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
940 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
942 (AFSBTreeEntry **)&pObjectInfoCB);
944 if( !NT_SUCCESS( ntStatus) ||
945 pObjectInfoCB == NULL)
949 // Allocate our object info cb
952 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
955 if( pObjectInfoCB == NULL)
958 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
960 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
963 bAllocatedObjectCB = TRUE;
965 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
966 AFS_TRACE_LEVEL_VERBOSE,
967 "AFSInitDirEntry initialized object %08lX Parent Object %08lX for %wZ\n",
973 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
975 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
976 AFS_TRACE_LEVEL_VERBOSE,
977 "AFSInitDirEntry Increment count on object %08lX Cnt %d\n",
981 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
983 ntStatus = STATUS_SUCCESS;
985 ulEntryLength = sizeof( AFSDirectoryCB) +
988 if( TargetName != NULL)
991 ulEntryLength += TargetName->Length;
994 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
998 if( pDirNode == NULL)
1001 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1004 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1005 sizeof( AFSNonPagedDirectoryCB),
1006 AFS_DIR_ENTRY_NP_TAG);
1008 if( pNonPagedDirEntry == NULL)
1011 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1014 RtlZeroMemory( pDirNode,
1017 RtlZeroMemory( pNonPagedDirEntry,
1018 sizeof( AFSNonPagedDirectoryCB));
1020 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1022 pDirNode->NonPaged = pNonPagedDirEntry;
1024 pDirNode->ObjectInformation = pObjectInfoCB;
1027 // Set valid entry and NOT_IN_PARENT flag
1030 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1032 pDirNode->FileIndex = FileIndex;
1035 // Setup the names in the entry
1038 if( FileName->Length > 0)
1041 pDirNode->NameInformation.FileName.Length = FileName->Length;
1043 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1045 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1047 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1049 pDirNode->NameInformation.FileName.Length);
1052 // Create a CRC for the file
1055 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1058 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1062 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1063 AFS_TRACE_LEVEL_VERBOSE,
1064 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1067 ParentObjectInfo->FileId.Cell,
1068 ParentObjectInfo->FileId.Volume,
1069 ParentObjectInfo->FileId.Vnode,
1070 ParentObjectInfo->FileId.Unique);
1072 if( TargetName != NULL &&
1073 TargetName->Length > 0)
1076 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1078 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1080 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1081 sizeof( AFSDirectoryCB) +
1082 pDirNode->NameInformation.FileName.Length);
1084 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1086 pDirNode->NameInformation.TargetName.Length);
1090 // If we allocated the object information cb then update the information
1093 if( bAllocatedObjectCB)
1097 // Populate the rest of the data
1100 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1102 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1104 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1106 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1108 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1110 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1112 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1114 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1116 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1118 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1120 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1123 pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1126 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1127 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1130 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1133 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1136 // Object specific information
1139 pObjectInfoCB->Links = DirEnumEntry->Links;
1141 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1143 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1146 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1147 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1151 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1152 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1153 pObjectInfoCB->TargetFileId.Unique == 0 &&
1154 pDirNode->NameInformation.TargetName.Length == 0)
1158 // This will ensure we perform a validation on the node
1161 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1164 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1167 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1173 if( !NT_SUCCESS( ntStatus))
1176 if( pNonPagedDirEntry != NULL)
1179 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1181 AFSExFreePool( pNonPagedDirEntry);
1184 if( pDirNode != NULL)
1187 AFSExFreePool( pDirNode);
1193 // Dereference our object info block if we have one
1196 if( pObjectInfoCB != NULL)
1199 lCount = InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
1201 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1202 AFS_TRACE_LEVEL_VERBOSE,
1203 "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
1207 if( bAllocatedObjectCB)
1210 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1212 AFSDeleteObjectInfo( pObjectInfoCB);
1222 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1223 IN BOOLEAN DirectoryEntry)
1226 BOOLEAN bReturn = TRUE;
1227 ACCESS_MASK stAccessMask = 0;
1230 // Get rid of anything we don't know about
1233 DesiredAccess = (DesiredAccess &
1239 ACCESS_SYSTEM_SECURITY |
1243 FILE_READ_ATTRIBUTES |
1244 FILE_WRITE_ATTRIBUTES |
1245 FILE_LIST_DIRECTORY |
1251 // Our 'read only' access mask. These are the accesses we will
1252 // allow for a read only file
1255 stAccessMask = DELETE |
1260 ACCESS_SYSTEM_SECURITY |
1264 FILE_READ_ATTRIBUTES |
1265 FILE_WRITE_ATTRIBUTES |
1267 FILE_LIST_DIRECTORY |
1271 // For a directory, add in the directory specific accesses
1277 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1282 if( FlagOn( DesiredAccess, ~stAccessMask))
1286 // A write access is set ...
1296 AFSEvaluateNode( IN GUID *AuthGroup,
1297 IN AFSDirectoryCB *DirEntry)
1300 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1301 NTSTATUS ntStatus = STATUS_SUCCESS;
1302 AFSDirEnumEntry *pDirEntry = NULL;
1303 UNICODE_STRING uniTargetName;
1308 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1313 if( !NT_SUCCESS( ntStatus))
1316 try_return( ntStatus);
1319 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1321 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1323 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1325 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1327 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1329 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1331 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1333 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1335 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1337 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1339 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1341 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1344 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1347 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1348 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1351 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1354 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1356 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1359 // If we have a target name then see if it needs updating ...
1362 if( pDirEntry->TargetNameLength > 0)
1366 // Update the target name information if needed
1369 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1371 uniTargetName.MaximumLength = uniTargetName.Length;
1373 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1375 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1378 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1379 RtlCompareUnicodeString( &uniTargetName,
1380 &DirEntry->NameInformation.TargetName,
1385 // Update the target name
1388 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1390 uniTargetName.Buffer,
1391 uniTargetName.Length);
1393 if( !NT_SUCCESS( ntStatus))
1396 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1398 try_return( ntStatus);
1402 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1407 if( pDirEntry != NULL)
1410 AFSExFreePool( pDirEntry);
1418 AFSValidateSymLink( IN GUID *AuthGroup,
1419 IN AFSDirectoryCB *DirEntry)
1422 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1423 NTSTATUS ntStatus = STATUS_SUCCESS;
1424 AFSDirEnumEntry *pDirEntry = NULL;
1425 UNICODE_STRING uniTargetName;
1430 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1435 if( !NT_SUCCESS( ntStatus))
1438 try_return( ntStatus);
1441 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1442 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1445 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1448 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1450 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1452 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1455 // Update the target name information if needed
1458 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1460 uniTargetName.MaximumLength = uniTargetName.Length;
1462 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1464 if( uniTargetName.Length > 0)
1467 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1470 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1471 RtlCompareUnicodeString( &uniTargetName,
1472 &DirEntry->NameInformation.TargetName,
1477 // Update the target name
1480 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1482 uniTargetName.Buffer,
1483 uniTargetName.Length);
1485 if( !NT_SUCCESS( ntStatus))
1488 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1490 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1494 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1498 // If the FileType is the same then nothing to do since it IS
1502 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1505 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1507 try_return( ntStatus = STATUS_SUCCESS);
1510 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1512 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1514 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1516 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1518 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1520 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1522 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1524 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1526 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1529 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1532 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1533 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1536 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1539 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1541 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1545 if( pDirEntry != NULL)
1548 AFSExFreePool( pDirEntry);
1556 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1560 NTSTATUS ntStatus = STATUS_SUCCESS;
1561 IO_STATUS_BLOCK stIoStatus;
1564 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1565 AFS_TRACE_LEVEL_VERBOSE,
1566 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1567 (*ppObjectInfo)->FileType,
1568 (*ppObjectInfo)->FileId.Cell,
1569 (*ppObjectInfo)->FileId.Volume,
1570 (*ppObjectInfo)->FileId.Vnode,
1571 (*ppObjectInfo)->FileId.Unique,
1574 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1575 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1576 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1579 // We only act on the mount point itself, not the target. If the
1580 // node has been deleted then mark it as such otherwise indicate
1581 // it requires verification
1584 if( Reason == AFS_INVALIDATE_DELETED)
1586 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1591 if( Reason == AFS_INVALIDATE_FLUSHED)
1594 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1596 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1599 (*ppObjectInfo)->Expiration.QuadPart = 0;
1601 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1603 (*ppObjectInfo)->TargetFileId.Unique = 0;
1605 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1606 AFS_TRACE_LEVEL_VERBOSE,
1607 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1608 (*ppObjectInfo)->FileId.Cell,
1609 (*ppObjectInfo)->FileId.Volume,
1610 (*ppObjectInfo)->FileId.Vnode,
1611 (*ppObjectInfo)->FileId.Unique);
1613 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1616 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1618 if( Reason == AFS_INVALIDATE_CREDS)
1620 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1623 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1624 Reason == AFS_INVALIDATE_FLUSHED)
1626 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1630 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1633 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1636 FILE_ACTION_MODIFIED);
1638 try_return( ntStatus);
1642 // Depending on the reason for invalidation then perform work on the node
1648 case AFS_INVALIDATE_DELETED:
1652 // Mark this node as invalid
1655 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1657 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1658 AFS_TRACE_LEVEL_VERBOSE,
1659 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1660 (*ppObjectInfo)->FileId.Cell,
1661 (*ppObjectInfo)->FileId.Volume,
1662 (*ppObjectInfo)->FileId.Vnode,
1663 (*ppObjectInfo)->FileId.Unique);
1665 if( (*ppObjectInfo)->ParentObjectInformation != NULL)
1668 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1669 AFS_TRACE_LEVEL_VERBOSE,
1670 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1671 (*ppObjectInfo)->ParentObjectInformation->FileId.Cell,
1672 (*ppObjectInfo)->ParentObjectInformation->FileId.Volume,
1673 (*ppObjectInfo)->ParentObjectInformation->FileId.Vnode,
1674 (*ppObjectInfo)->ParentObjectInformation->FileId.Unique);
1676 SetFlag( (*ppObjectInfo)->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1678 (*ppObjectInfo)->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1680 (*ppObjectInfo)->ParentObjectInformation->Expiration.QuadPart = 0;
1683 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1685 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1689 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1692 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1695 FILE_ACTION_REMOVED);
1697 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1700 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1706 case AFS_INVALIDATE_FLUSHED:
1709 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1710 (*ppObjectInfo)->Fcb != NULL)
1713 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1714 AFS_TRACE_LEVEL_VERBOSE,
1715 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1716 (*ppObjectInfo)->FileId.Cell,
1717 (*ppObjectInfo)->FileId.Volume,
1718 (*ppObjectInfo)->FileId.Vnode,
1719 (*ppObjectInfo)->FileId.Unique);
1721 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1727 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1732 if( !NT_SUCCESS( stIoStatus.Status))
1735 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1736 AFS_TRACE_LEVEL_ERROR,
1737 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1738 (*ppObjectInfo)->FileId.Cell,
1739 (*ppObjectInfo)->FileId.Volume,
1740 (*ppObjectInfo)->FileId.Vnode,
1741 (*ppObjectInfo)->FileId.Unique,
1743 stIoStatus.Information);
1745 ntStatus = stIoStatus.Status;
1748 CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1753 __except( EXCEPTION_EXECUTE_HANDLER)
1756 ntStatus = GetExceptionCode();
1759 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->Resource);
1762 // Clear out the extents
1763 // Get rid of them (note this involves waiting
1764 // for any writes or reads to the cache to complete)
1767 (VOID) AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1771 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1774 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1777 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1778 AFS_TRACE_LEVEL_VERBOSE,
1779 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1780 (*ppObjectInfo)->FileId.Cell,
1781 (*ppObjectInfo)->FileId.Volume,
1782 (*ppObjectInfo)->FileId.Vnode,
1783 (*ppObjectInfo)->FileId.Unique);
1785 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1788 // Fall through to the default processing
1794 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1796 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1800 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1803 if( Reason == AFS_INVALIDATE_CREDS)
1805 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1808 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1810 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1814 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1817 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1820 FILE_ACTION_MODIFIED);
1823 // Indicate this node requires re-evaluation for the remaining reasons
1826 (*ppObjectInfo)->Expiration.QuadPart = 0;
1828 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1829 AFS_TRACE_LEVEL_VERBOSE,
1830 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1831 (*ppObjectInfo)->FileId.Cell,
1832 (*ppObjectInfo)->FileId.Volume,
1833 (*ppObjectInfo)->FileId.Vnode,
1834 (*ppObjectInfo)->FileId.Unique);
1836 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1838 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1839 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1840 ( Reason == AFS_INVALIDATE_CALLBACK ||
1841 Reason == AFS_INVALIDATE_EXPIRED))
1843 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1844 AFS_INVALIDATE_DATA_VERSION)))
1847 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1861 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1864 NTSTATUS ntStatus = STATUS_SUCCESS;
1865 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1866 AFSVolumeCB *pVolumeCB = NULL;
1867 AFSFcb *pTargetDcb = NULL;
1868 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1869 AFSDirectoryCB *pCurrentDirEntry = NULL;
1870 BOOLEAN bIsChild = FALSE;
1871 ULONGLONG ullIndex = 0;
1872 AFSObjectInfoCB *pObjectInfo = NULL;
1878 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1879 AFS_TRACE_LEVEL_VERBOSE,
1880 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1881 InvalidateCB->FileID.Cell,
1882 InvalidateCB->FileID.Volume,
1883 InvalidateCB->FileID.Vnode,
1884 InvalidateCB->FileID.Unique,
1885 InvalidateCB->FileType,
1886 InvalidateCB->WholeVolume,
1887 InvalidateCB->Reason);
1890 // Need to locate the Fcb for the directory to purge
1893 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1894 AFS_TRACE_LEVEL_VERBOSE,
1895 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1896 &pDevExt->Specific.RDR.VolumeTreeLock,
1897 PsGetCurrentThread());
1900 // Starve any exclusive waiters on this paticular call
1903 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1906 // Locate the volume node
1909 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1911 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1913 (AFSBTreeEntry **)&pVolumeCB);
1915 if( pVolumeCB != NULL)
1918 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1920 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1921 AFS_TRACE_LEVEL_VERBOSE,
1922 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1927 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1929 if( !NT_SUCCESS( ntStatus) ||
1933 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1934 AFS_TRACE_LEVEL_WARNING,
1935 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1936 InvalidateCB->FileID.Cell,
1937 InvalidateCB->FileID.Volume,
1938 InvalidateCB->FileID.Vnode,
1939 InvalidateCB->FileID.Unique,
1942 try_return( ntStatus = STATUS_SUCCESS);
1946 // If this is a whole volume invalidation then go do it now
1949 if( InvalidateCB->WholeVolume)
1952 ntStatus = AFSInvalidateVolume( pVolumeCB,
1953 InvalidateCB->Reason);
1955 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1957 try_return( ntStatus);
1960 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1963 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
1966 pObjectInfo = &pVolumeCB->ObjectInformation;
1971 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1973 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1974 AFS_TRACE_LEVEL_VERBOSE,
1975 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
1977 pVolumeCB->VolumeReferenceCount);
1979 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
1981 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
1983 (AFSBTreeEntry **)&pObjectInfo);
1986 if( pObjectInfo != NULL)
1990 // Reference the node so it won't be torn down
1993 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
1995 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1996 AFS_TRACE_LEVEL_VERBOSE,
1997 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
2002 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2004 if( !NT_SUCCESS( ntStatus) ||
2005 pObjectInfo == NULL)
2008 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2009 AFS_TRACE_LEVEL_WARNING,
2010 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2011 InvalidateCB->FileID.Cell,
2012 InvalidateCB->FileID.Volume,
2013 InvalidateCB->FileID.Vnode,
2014 InvalidateCB->FileID.Unique,
2017 try_return( ntStatus = STATUS_SUCCESS);
2020 AFSInvalidateObject( &pObjectInfo,
2021 InvalidateCB->Reason);
2025 if( pObjectInfo != NULL)
2028 lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
2030 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2031 AFS_TRACE_LEVEL_VERBOSE,
2032 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
2042 AFSIsChildOfParent( IN AFSFcb *Dcb,
2046 BOOLEAN bIsChild = FALSE;
2047 AFSFcb *pCurrentFcb = Fcb;
2049 while( pCurrentFcb != NULL)
2052 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2060 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2068 AFSCreateHighIndex( IN AFSFileID *FileID)
2071 ULONGLONG ullIndex = 0;
2073 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2080 AFSCreateLowIndex( IN AFSFileID *FileID)
2083 ULONGLONG ullIndex = 0;
2085 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2091 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2092 IN ACCESS_MASK GrantedAccess,
2093 IN BOOLEAN DirectoryEntry)
2096 BOOLEAN bAccessGranted = TRUE;
2099 // Check if we are asking for read/write and granted only read only
2100 // NOTE: There will be more checks here
2103 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2105 AFSCheckForReadOnlyAccess( GrantedAccess,
2109 bAccessGranted = FALSE;
2112 return bAccessGranted;
2116 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2119 NTSTATUS ntStatus = STATUS_SUCCESS;
2120 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2126 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2128 if( AFSGlobalRoot == NULL)
2135 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2138 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2145 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2152 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2153 IN UNICODE_STRING *SubstituteName,
2154 IN ULONG StringIndex)
2157 NTSTATUS ntStatus = STATUS_SUCCESS;
2158 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2159 AFSSysNameCB *pSysName = NULL;
2160 ERESOURCE *pSysNameLock = NULL;
2163 UNICODE_STRING uniSysName;
2170 if( IoIs32bitProcess( NULL))
2173 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2175 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2180 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2182 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2186 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2188 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2192 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2193 AFS_TRACE_LEVEL_VERBOSE,
2194 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2196 PsGetCurrentThread());
2198 AFSAcquireShared( pSysNameLock,
2202 // Find where we are in the list
2205 while( pSysName != NULL &&
2206 ulIndex < StringIndex)
2209 pSysName = pSysName->fLink;
2214 if( pSysName == NULL)
2217 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2220 RtlInitUnicodeString( &uniSysName,
2223 // If it is a full component of @SYS then just substitue the
2227 if( RtlCompareUnicodeString( &uniSysName,
2232 SubstituteName->Length = pSysName->SysName.Length;
2233 SubstituteName->MaximumLength = SubstituteName->Length;
2235 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2236 SubstituteName->Length,
2237 AFS_SUBST_BUFFER_TAG);
2239 if( SubstituteName->Buffer == NULL)
2242 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2245 RtlCopyMemory( SubstituteName->Buffer,
2246 pSysName->SysName.Buffer,
2247 pSysName->SysName.Length);
2254 while( ComponentName->Buffer[ usIndex] != L'@')
2260 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2261 SubstituteName->MaximumLength = SubstituteName->Length;
2263 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2264 SubstituteName->Length,
2265 AFS_SUBST_BUFFER_TAG);
2267 if( SubstituteName->Buffer == NULL)
2270 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2273 RtlCopyMemory( SubstituteName->Buffer,
2274 ComponentName->Buffer,
2275 usIndex * sizeof( WCHAR));
2277 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2278 pSysName->SysName.Buffer,
2279 pSysName->SysName.Length);
2284 AFSReleaseResource( pSysNameLock);
2291 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2292 IN OUT UNICODE_STRING *ComponentName,
2293 IN UNICODE_STRING *SubstituteName,
2294 IN OUT UNICODE_STRING *RemainingPath,
2295 IN BOOLEAN FreePathName)
2298 NTSTATUS ntStatus = STATUS_SUCCESS;
2299 UNICODE_STRING uniPathName;
2300 USHORT usPrefixNameLen = 0;
2301 SHORT sNameLenDelta = 0;
2307 // If the passed in name can handle the additional length
2308 // then just moves things around
2311 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2313 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2315 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2318 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2321 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2322 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2323 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2326 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2327 SubstituteName->Buffer,
2328 SubstituteName->Length);
2330 FullPathName->Length += sNameLenDelta;
2332 ComponentName->Length += sNameLenDelta;
2334 ComponentName->MaximumLength = ComponentName->Length;
2336 if ( RemainingPath->Buffer)
2339 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2342 try_return( ntStatus);
2346 // Need to re-allocate the buffer
2349 uniPathName.Length = FullPathName->Length -
2350 ComponentName->Length +
2351 SubstituteName->Length;
2353 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2355 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2356 uniPathName.MaximumLength,
2357 AFS_NAME_BUFFER_FOUR_TAG);
2359 if( uniPathName.Buffer == NULL)
2362 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2365 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2367 usPrefixNameLen *= sizeof( WCHAR);
2369 RtlZeroMemory( uniPathName.Buffer,
2370 uniPathName.MaximumLength);
2372 RtlCopyMemory( uniPathName.Buffer,
2373 FullPathName->Buffer,
2376 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2377 SubstituteName->Buffer,
2378 SubstituteName->Length);
2380 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2383 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2384 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2385 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2388 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2390 ComponentName->Length += sNameLenDelta;
2392 ComponentName->MaximumLength = ComponentName->Length;
2394 if ( RemainingPath->Buffer)
2397 RemainingPath->Buffer = uniPathName.Buffer
2398 + (RemainingPath->Buffer - FullPathName->Buffer)
2399 + sNameLenDelta/sizeof( WCHAR);
2404 AFSExFreePool( FullPathName->Buffer);
2407 *FullPathName = uniPathName;
2418 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2422 NTSTATUS ntStatus = STATUS_SUCCESS;
2423 AFSObjectInfoCB *pCurrentObject = NULL;
2424 AFSObjectInfoCB *pNextObject = NULL;
2426 AFSFcb *pFcb = NULL;
2432 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2433 AFS_TRACE_LEVEL_VERBOSE,
2434 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2435 VolumeCB->ObjectInformation.FileId.Cell,
2436 VolumeCB->ObjectInformation.FileId.Volume,
2437 VolumeCB->ObjectInformation.FileId.Vnode,
2438 VolumeCB->ObjectInformation.FileId.Unique,
2442 // Depending on the reason for invalidation then perform work on the node
2448 case AFS_INVALIDATE_DELETED:
2452 // Mark this volume as invalid
2455 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2457 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2464 // Invalidate the volume root directory
2467 pCurrentObject = &VolumeCB->ObjectInformation;
2469 if ( pCurrentObject )
2472 lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
2474 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2475 AFS_TRACE_LEVEL_VERBOSE,
2476 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2480 AFSInvalidateObject( &pCurrentObject,
2483 if ( pCurrentObject)
2486 lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
2488 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2489 AFS_TRACE_LEVEL_VERBOSE,
2490 "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
2497 // Apply invalidation to all other volume objects
2500 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2503 pCurrentObject = VolumeCB->ObjectInfoListHead;
2505 if ( pCurrentObject)
2509 // Reference the node so it won't be torn down
2512 lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
2514 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2515 AFS_TRACE_LEVEL_VERBOSE,
2516 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2521 while( pCurrentObject != NULL)
2524 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2530 // Reference the node so it won't be torn down
2533 lCount = InterlockedIncrement( &pNextObject->ObjectReferenceCount);
2535 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2536 AFS_TRACE_LEVEL_VERBOSE,
2537 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2542 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2544 AFSInvalidateObject( &pCurrentObject,
2547 if ( pCurrentObject )
2550 lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
2552 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2553 AFS_TRACE_LEVEL_VERBOSE,
2554 "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
2559 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2562 pCurrentObject = pNextObject;
2565 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2572 AFSInvalidateAllVolumes( VOID)
2574 AFSVolumeCB *pVolumeCB = NULL;
2575 AFSVolumeCB *pNextVolumeCB = NULL;
2576 AFSDeviceExt *pRDRDeviceExt = NULL;
2579 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2581 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2582 AFS_TRACE_LEVEL_VERBOSE,
2583 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %08lX SHARED %08lX\n",
2584 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2585 PsGetCurrentThread());
2587 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2590 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2595 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2596 AFS_TRACE_LEVEL_VERBOSE,
2597 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %08lX SHARED %08lX\n",
2598 pVolumeCB->ObjectInfoTree.TreeLock,
2599 PsGetCurrentThread());
2601 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
2604 while( pVolumeCB != NULL)
2607 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2612 lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
2615 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2617 // do I need to hold the volume lock here?
2619 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2621 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2624 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2626 pVolumeCB = pNextVolumeCB;
2629 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2633 AFSVerifyEntry( IN GUID *AuthGroup,
2634 IN AFSDirectoryCB *DirEntry)
2637 NTSTATUS ntStatus = STATUS_SUCCESS;
2638 AFSDirEnumEntry *pDirEnumEntry = NULL;
2639 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2640 IO_STATUS_BLOCK stIoStatus;
2645 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2646 AFS_TRACE_LEVEL_VERBOSE_2,
2647 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2648 &DirEntry->NameInformation.FileName,
2649 pObjectInfo->FileId.Cell,
2650 pObjectInfo->FileId.Volume,
2651 pObjectInfo->FileId.Vnode,
2652 pObjectInfo->FileId.Unique);
2654 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2659 if( !NT_SUCCESS( ntStatus))
2662 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2663 AFS_TRACE_LEVEL_ERROR,
2664 "AFSValidateEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2665 &DirEntry->NameInformation.FileName,
2666 pObjectInfo->FileId.Cell,
2667 pObjectInfo->FileId.Volume,
2668 pObjectInfo->FileId.Vnode,
2669 pObjectInfo->FileId.Unique,
2672 try_return( ntStatus);
2676 // Check the data version of the file
2679 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2681 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2684 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2685 AFS_TRACE_LEVEL_VERBOSE,
2686 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2687 pObjectInfo->DataVersion.QuadPart,
2688 &DirEntry->NameInformation.FileName,
2689 pObjectInfo->FileId.Cell,
2690 pObjectInfo->FileId.Volume,
2691 pObjectInfo->FileId.Vnode,
2692 pObjectInfo->FileId.Unique);
2695 // We are ok, just get out
2698 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2700 try_return( ntStatus = STATUS_SUCCESS);
2705 // New data version so we will need to process the node based on the type
2708 switch( pDirEnumEntry->FileType)
2711 case AFS_FILE_TYPE_MOUNTPOINT:
2715 // For a mount point we need to ensure the target is the same
2718 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2719 &pDirEnumEntry->TargetFileId))
2725 // Update the metadata for the entry
2728 ntStatus = AFSUpdateMetaData( DirEntry,
2731 if( NT_SUCCESS( ntStatus))
2734 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2740 case AFS_FILE_TYPE_SYMLINK:
2743 ASSERT( pDirEnumEntry->TargetNameLength > 0);
2746 // Update the metadata for the entry
2749 ntStatus = AFSUpdateMetaData( DirEntry,
2752 if( NT_SUCCESS( ntStatus))
2755 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2761 case AFS_FILE_TYPE_FILE:
2763 FILE_OBJECT * pCCFileObject = NULL;
2764 BOOLEAN bPurgeExtents = FALSE;
2766 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
2769 bPurgeExtents = TRUE;
2772 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);
2789 if( pObjectInfo->Fcb != NULL)
2792 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2793 AFS_TRACE_LEVEL_VERBOSE,
2794 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2795 &DirEntry->NameInformation.FileName,
2796 pObjectInfo->FileId.Cell,
2797 pObjectInfo->FileId.Volume,
2798 pObjectInfo->FileId.Vnode,
2799 pObjectInfo->FileId.Unique);
2801 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2807 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2812 if( !NT_SUCCESS( stIoStatus.Status))
2815 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2816 AFS_TRACE_LEVEL_ERROR,
2817 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2818 &DirEntry->NameInformation.FileName,
2819 pObjectInfo->FileId.Cell,
2820 pObjectInfo->FileId.Volume,
2821 pObjectInfo->FileId.Vnode,
2822 pObjectInfo->FileId.Unique,
2824 stIoStatus.Information);
2826 ntStatus = stIoStatus.Status;
2832 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2838 __except( EXCEPTION_EXECUTE_HANDLER)
2840 ntStatus = GetExceptionCode();
2842 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2843 AFS_TRACE_LEVEL_ERROR,
2844 "AFSVerifyEntry CcFlushCache or CcPurgeCacheSection Exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2845 &DirEntry->NameInformation.FileName,
2846 pObjectInfo->FileId.Cell,
2847 pObjectInfo->FileId.Volume,
2848 pObjectInfo->FileId.Vnode,
2849 pObjectInfo->FileId.Unique,
2853 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2857 AFSFlushExtents( pObjectInfo->Fcb,
2862 // Reacquire the Fcb to purge the cache
2865 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2866 AFS_TRACE_LEVEL_VERBOSE,
2867 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2868 &pObjectInfo->Fcb->NPFcb->Resource,
2869 PsGetCurrentThread());
2871 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2875 // Update the metadata for the entry
2878 ntStatus = AFSUpdateMetaData( DirEntry,
2881 if( !NT_SUCCESS( ntStatus))
2884 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2885 AFS_TRACE_LEVEL_ERROR,
2886 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2887 &DirEntry->NameInformation.FileName,
2888 pObjectInfo->FileId.Cell,
2889 pObjectInfo->FileId.Volume,
2890 pObjectInfo->FileId.Vnode,
2891 pObjectInfo->FileId.Unique,
2898 // Update file sizes
2901 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2902 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2903 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2905 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2907 if ( pCCFileObject != NULL)
2909 CcSetFileSizes( pCCFileObject,
2910 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
2913 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2919 // Update the metadata for the entry
2922 ntStatus = AFSUpdateMetaData( DirEntry,
2925 if( !NT_SUCCESS( ntStatus))
2928 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2929 AFS_TRACE_LEVEL_ERROR,
2930 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2931 &DirEntry->NameInformation.FileName,
2932 pObjectInfo->FileId.Cell,
2933 pObjectInfo->FileId.Volume,
2934 pObjectInfo->FileId.Vnode,
2935 pObjectInfo->FileId.Unique,
2941 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2942 AFS_TRACE_LEVEL_WARNING,
2943 "AFSValidateEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2944 &DirEntry->NameInformation.FileName,
2945 pObjectInfo->FileId.Cell,
2946 pObjectInfo->FileId.Volume,
2947 pObjectInfo->FileId.Vnode,
2948 pObjectInfo->FileId.Unique);
2951 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2956 case AFS_FILE_TYPE_DIRECTORY:
2959 AFSFcb *pCurrentFcb = NULL;
2960 AFSDirectoryCB *pCurrentDirEntry = NULL;
2963 // For a directory or root entry flush the content of
2964 // the directory enumeration.
2967 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2970 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2971 AFS_TRACE_LEVEL_VERBOSE_2,
2972 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2973 &DirEntry->NameInformation.FileName,
2974 pObjectInfo->FileId.Cell,
2975 pObjectInfo->FileId.Volume,
2976 pObjectInfo->FileId.Vnode,
2977 pObjectInfo->FileId.Unique);
2979 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2982 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
2985 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2987 if ( !NT_SUCCESS( ntStatus))
2990 try_return( ntStatus);
2995 // Update the metadata for the entry
2998 ntStatus = AFSUpdateMetaData( DirEntry,
3001 if( NT_SUCCESS( ntStatus))
3004 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3010 case AFS_FILE_TYPE_DFSLINK:
3013 UNICODE_STRING uniTargetName;
3016 // For a DFS link need to check the target name has not changed
3019 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3021 uniTargetName.MaximumLength = uniTargetName.Length;
3023 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3025 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3028 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3029 RtlCompareUnicodeString( &uniTargetName,
3030 &DirEntry->NameInformation.TargetName,
3035 // Update the target name
3038 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3040 uniTargetName.Buffer,
3041 uniTargetName.Length);
3043 if( !NT_SUCCESS( ntStatus))
3046 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3052 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3055 // Update the metadata for the entry
3058 ntStatus = AFSUpdateMetaData( DirEntry,
3061 if( NT_SUCCESS( ntStatus))
3064 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3072 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3073 AFS_TRACE_LEVEL_WARNING,
3074 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3075 pObjectInfo->FileType,
3076 &DirEntry->NameInformation.FileName,
3077 pObjectInfo->FileId.Cell,
3078 pObjectInfo->FileId.Volume,
3079 pObjectInfo->FileId.Vnode,
3080 pObjectInfo->FileId.Unique);
3087 if( pDirEnumEntry != NULL)
3090 AFSExFreePool( pDirEnumEntry);
3098 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3101 NTSTATUS ntStatus = STATUS_SUCCESS;
3102 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3103 ULONGLONG ullIndex = 0;
3104 AFSVolumeCB *pVolumeCB = NULL;
3105 AFSFcb *pFcb = NULL;
3106 AFSObjectInfoCB *pCurrentObject = NULL;
3112 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3113 AFS_TRACE_LEVEL_VERBOSE,
3114 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3115 VolumeStatus->Online,
3116 VolumeStatus->FileID.Cell,
3117 VolumeStatus->FileID.Volume);
3120 // Need to locate the Fcb for the directory to purge
3123 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3124 AFS_TRACE_LEVEL_VERBOSE,
3125 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3126 &pDevExt->Specific.RDR.VolumeTreeLock,
3127 PsGetCurrentThread());
3129 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3132 // Locate the volume node
3135 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3137 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3139 (AFSBTreeEntry **)&pVolumeCB);
3141 if( pVolumeCB != NULL)
3144 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3146 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3149 // Set the volume state accordingly
3152 if( VolumeStatus->Online)
3155 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3160 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3163 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3166 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3168 while( pCurrentObject != NULL)
3171 if( VolumeStatus->Online)
3174 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3176 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3178 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3183 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3186 pFcb = pCurrentObject->Fcb;
3189 !(VolumeStatus->Online) &&
3190 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3193 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3194 AFS_TRACE_LEVEL_ERROR,
3195 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3196 VolumeStatus->FileID.Cell,
3197 VolumeStatus->FileID.Volume);
3200 // Clear out the extents
3203 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3204 AFS_TRACE_LEVEL_VERBOSE,
3205 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3206 &pFcb->NPFcb->Specific.File.ExtentsResource,
3207 PsGetCurrentThread());
3209 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3212 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3214 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3218 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3219 AFS_TRACE_LEVEL_VERBOSE,
3220 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3221 &pFcb->NPFcb->Specific.File.ExtentsResource,
3222 PsGetCurrentThread());
3224 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3227 // And get rid of them (note this involves waiting
3228 // for any writes or reads to the cache to complete)
3231 (VOID) AFSTearDownFcbExtents( pFcb,
3235 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3238 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3240 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3245 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3253 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3256 NTSTATUS ntStatus = STATUS_SUCCESS;
3261 if( AFSGlobalRoot == NULL)
3264 try_return( ntStatus);
3267 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3271 // Set the network state according to the information
3274 if( NetworkStatus->Online)
3277 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3282 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3285 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3296 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3300 NTSTATUS ntStatus = STATUS_SUCCESS;
3301 BOOLEAN bAcquiredLock = FALSE;
3302 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3303 AFSFcb *pFcb = NULL;
3308 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3309 AFS_TRACE_LEVEL_VERBOSE,
3310 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3311 ObjectInfo->FileId.Cell,
3312 ObjectInfo->FileId.Volume,
3313 ObjectInfo->FileId.Vnode,
3314 ObjectInfo->FileId.Unique);
3316 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3319 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3320 AFS_TRACE_LEVEL_VERBOSE,
3321 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3322 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3323 PsGetCurrentThread());
3325 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3328 bAcquiredLock = TRUE;
3332 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3335 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3336 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3339 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3340 AFS_TRACE_LEVEL_ERROR,
3341 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
3342 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3343 ObjectInfo->FileId.Cell,
3344 ObjectInfo->FileId.Volume,
3345 ObjectInfo->FileId.Vnode,
3346 ObjectInfo->FileId.Unique);
3350 // Reset the directory list information by clearing all valid entries
3353 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3355 while( pCurrentDirEntry != NULL)
3358 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3360 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3364 // If this entry has been deleted then process it here
3367 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3368 pCurrentDirEntry->OpenReferenceCount == 0)
3371 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3372 AFS_TRACE_LEVEL_VERBOSE,
3373 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3375 &pCurrentDirEntry->NameInformation.FileName);
3377 AFSDeleteDirEntry( ObjectInfo,
3383 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3385 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3386 AFS_TRACE_LEVEL_VERBOSE,
3387 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3389 pCurrentDirEntry->OpenReferenceCount);
3392 // We pull the short name from the parent tree since it could change below
3395 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3398 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3399 AFS_TRACE_LEVEL_VERBOSE,
3400 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3402 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3403 &pCurrentDirEntry->NameInformation.FileName);
3405 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3408 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3413 pCurrentDirEntry = pNextDirEntry;
3417 // Reget the directory contents
3420 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3423 if ( !NT_SUCCESS( ntStatus))
3425 try_return( ntStatus);
3429 // Now start again and tear down any entries not valid
3432 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3434 while( pCurrentDirEntry != NULL)
3437 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3439 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3442 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3443 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3446 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3449 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3451 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3452 AFS_TRACE_LEVEL_VERBOSE,
3453 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3455 &pCurrentDirEntry->NameInformation.FileName);
3457 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3462 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3465 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3466 AFS_TRACE_LEVEL_VERBOSE,
3467 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3469 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3470 &pCurrentDirEntry->NameInformation.FileName);
3474 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3476 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3477 AFS_TRACE_LEVEL_VERBOSE,
3478 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3480 &pCurrentDirEntry->NameInformation.FileName);
3485 pCurrentDirEntry = pNextDirEntry;
3490 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3491 AFS_TRACE_LEVEL_VERBOSE,
3492 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3494 pCurrentDirEntry->OpenReferenceCount);
3496 if( pCurrentDirEntry->OpenReferenceCount == 0)
3499 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3500 AFS_TRACE_LEVEL_VERBOSE,
3501 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3502 &pCurrentDirEntry->NameInformation.FileName,
3503 ObjectInfo->FileId.Cell,
3504 ObjectInfo->FileId.Volume,
3505 ObjectInfo->FileId.Vnode,
3506 ObjectInfo->FileId.Unique);
3508 AFSDeleteDirEntry( ObjectInfo,
3514 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3515 AFS_TRACE_LEVEL_VERBOSE,
3516 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3518 &pCurrentDirEntry->NameInformation.FileName,
3519 ObjectInfo->FileId.Cell,
3520 ObjectInfo->FileId.Volume,
3521 ObjectInfo->FileId.Vnode,
3522 ObjectInfo->FileId.Unique);
3524 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3526 AFSRemoveNameEntry( ObjectInfo,
3530 pCurrentDirEntry = pNextDirEntry;
3534 if( !AFSValidateDirList( ObjectInfo))
3537 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3546 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3554 AFSIsVolumeFID( IN AFSFileID *FileID)
3557 BOOLEAN bIsVolume = FALSE;
3559 if( FileID->Vnode == 1 &&
3560 FileID->Unique == 1)
3570 AFSIsFinalNode( IN AFSFcb *Fcb)
3573 BOOLEAN bIsFinalNode = FALSE;
3575 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3576 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3577 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3578 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3579 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3582 bIsFinalNode = TRUE;
3587 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3588 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3591 return bIsFinalNode;
3595 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3596 IN AFSDirEnumEntry *DirEnumEntry)
3599 NTSTATUS ntStatus = STATUS_SUCCESS;
3600 UNICODE_STRING uniTargetName;
3601 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3606 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3608 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3610 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3612 pObjectInfo->FileType = DirEnumEntry->FileType;
3614 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3616 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3618 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3620 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3622 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3624 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3626 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3628 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3631 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3634 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3635 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3638 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3641 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3643 pObjectInfo->Links = DirEnumEntry->Links;
3645 if( DirEnumEntry->TargetNameLength > 0)
3649 // Update the target name information if needed
3652 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3654 uniTargetName.MaximumLength = uniTargetName.Length;
3656 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3658 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3661 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3662 RtlCompareUnicodeString( &uniTargetName,
3663 &DirEntry->NameInformation.TargetName,
3668 // Update the target name
3671 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3673 uniTargetName.Buffer,
3674 uniTargetName.Length);
3676 if( !NT_SUCCESS( ntStatus))
3679 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3681 try_return( ntStatus);
3685 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3687 else if( DirEntry->NameInformation.TargetName.Length > 0)
3690 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3693 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3694 DirEntry->NameInformation.TargetName.Buffer != NULL)
3696 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
3699 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3701 DirEntry->NameInformation.TargetName.Length = 0;
3702 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3703 DirEntry->NameInformation.TargetName.Buffer = NULL;
3705 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3717 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3719 IN BOOLEAN PurgeContent,
3720 IN BOOLEAN FastCall)
3723 NTSTATUS ntStatus = STATUS_SUCCESS;
3724 LARGE_INTEGER liSystemTime;
3725 AFSDirEnumEntry *pDirEnumEntry = NULL;
3726 AFSFcb *pCurrentFcb = NULL;
3727 BOOLEAN bReleaseFcb = FALSE;
3728 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3734 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3738 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3739 AFS_TRACE_LEVEL_VERBOSE_2,
3740 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX PurgeContent %u FastCall %u\n",
3741 &DirEntry->NameInformation.FileName,
3742 pObjectInfo->FileId.Cell,
3743 pObjectInfo->FileId.Volume,
3744 pObjectInfo->FileId.Vnode,
3745 pObjectInfo->FileId.Unique,
3750 // If this is a fake node then bail since the service knows nothing about it
3753 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3756 try_return( ntStatus);
3760 pObjectInfo->Fcb != NULL)
3763 pCurrentFcb = pObjectInfo->Fcb;
3765 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3768 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3769 AFS_TRACE_LEVEL_VERBOSE,
3770 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3771 &pCurrentFcb->NPFcb->Resource,
3772 PsGetCurrentThread());
3774 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3782 // This routine ensures that the current entry is valid by:
3784 // 1) Checking that the expiration time is non-zero and after where we
3788 KeQuerySystemTime( &liSystemTime);
3790 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3791 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3792 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3793 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3796 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3797 AFS_TRACE_LEVEL_VERBOSE_2,
3798 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3799 &DirEntry->NameInformation.FileName,
3800 pObjectInfo->FileId.Cell,
3801 pObjectInfo->FileId.Volume,
3802 pObjectInfo->FileId.Vnode,
3803 pObjectInfo->FileId.Unique);
3805 try_return( ntStatus);
3809 // This node requires updating
3812 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3817 if( !NT_SUCCESS( ntStatus))
3820 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3821 AFS_TRACE_LEVEL_ERROR,
3822 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3824 &DirEntry->NameInformation.FileName,
3825 pObjectInfo->FileId.Cell,
3826 pObjectInfo->FileId.Volume,
3827 pObjectInfo->FileId.Vnode,
3828 pObjectInfo->FileId.Unique,
3832 // Failed validation of node so return access-denied
3835 try_return( ntStatus);
3838 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3839 AFS_TRACE_LEVEL_VERBOSE,
3840 "AFSValidateEntry Validating entry Purge %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3843 &DirEntry->NameInformation.FileName,
3844 pObjectInfo->FileId.Cell,
3845 pObjectInfo->FileId.Volume,
3846 pObjectInfo->FileId.Vnode,
3847 pObjectInfo->FileId.Unique,
3848 pObjectInfo->DataVersion.QuadPart,
3849 pDirEnumEntry->DataVersion.QuadPart,
3850 pDirEnumEntry->FileType);
3854 // Based on the file type, process the node
3857 switch( pDirEnumEntry->FileType)
3860 case AFS_FILE_TYPE_MOUNTPOINT:
3864 // Update the metadata for the entry
3867 ntStatus = AFSUpdateMetaData( DirEntry,
3870 if( NT_SUCCESS( ntStatus))
3873 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3879 case AFS_FILE_TYPE_SYMLINK:
3880 case AFS_FILE_TYPE_DFSLINK:
3884 // Update the metadata for the entry
3887 ntStatus = AFSUpdateMetaData( DirEntry,
3890 if( NT_SUCCESS( ntStatus))
3893 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3899 case AFS_FILE_TYPE_FILE:
3903 // For a file where the data version has become invalid we need to
3904 // fail any current extent requests and purge the cache for the file
3905 // Can't hold the Fcb resource while doing this
3908 if( pCurrentFcb != NULL &&
3909 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3910 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3913 IO_STATUS_BLOCK stIoStatus;
3914 BOOLEAN bPurgeExtents = FALSE;
3916 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3917 AFS_TRACE_LEVEL_VERBOSE_2,
3918 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3919 &DirEntry->NameInformation.FileName,
3920 pObjectInfo->FileId.Cell,
3921 pObjectInfo->FileId.Volume,
3922 pObjectInfo->FileId.Vnode,
3923 pObjectInfo->FileId.Unique);
3925 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3927 bPurgeExtents = TRUE;
3929 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3930 AFS_TRACE_LEVEL_VERBOSE,
3931 "AFSVerifyEntry Clearing VERIFY_DATA flag %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 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3944 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
3949 if( !NT_SUCCESS( stIoStatus.Status))
3952 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3953 AFS_TRACE_LEVEL_ERROR,
3954 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3955 &DirEntry->NameInformation.FileName,
3956 pObjectInfo->FileId.Cell,
3957 pObjectInfo->FileId.Volume,
3958 pObjectInfo->FileId.Vnode,
3959 pObjectInfo->FileId.Unique,
3961 stIoStatus.Information);
3963 ntStatus = stIoStatus.Status;
3969 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3975 __except( EXCEPTION_EXECUTE_HANDLER)
3977 ntStatus = GetExceptionCode();
3979 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3980 AFS_TRACE_LEVEL_ERROR,
3981 "AFSValidateEntry CcFlushCache or CcPurgeCacheSection exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3982 &DirEntry->NameInformation.FileName,
3983 pObjectInfo->FileId.Cell,
3984 pObjectInfo->FileId.Volume,
3985 pObjectInfo->FileId.Vnode,
3986 pObjectInfo->FileId.Unique,
3991 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3995 AFSFlushExtents( pCurrentFcb,
4000 // Reacquire the Fcb to purge the cache
4003 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4004 AFS_TRACE_LEVEL_VERBOSE,
4005 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
4006 &pCurrentFcb->NPFcb->Resource,
4007 PsGetCurrentThread());
4009 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4014 // Update the metadata for the entry
4017 ntStatus = AFSUpdateMetaData( DirEntry,
4020 if( !NT_SUCCESS( ntStatus))
4023 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4024 AFS_TRACE_LEVEL_ERROR,
4025 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4026 &DirEntry->NameInformation.FileName,
4027 pObjectInfo->FileId.Cell,
4028 pObjectInfo->FileId.Volume,
4029 pObjectInfo->FileId.Vnode,
4030 pObjectInfo->FileId.Unique,
4036 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4039 // Update file sizes
4042 if( pObjectInfo->Fcb != NULL)
4044 FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4046 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4047 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4048 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4050 if ( pCCFileObject != NULL)
4052 CcSetFileSizes( pCCFileObject,
4053 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4060 case AFS_FILE_TYPE_DIRECTORY:
4063 AFSDirectoryCB *pCurrentDirEntry = NULL;
4065 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4069 // For a directory or root entry flush the content of
4070 // the directory enumeration.
4073 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4074 AFS_TRACE_LEVEL_VERBOSE,
4075 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4076 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4077 PsGetCurrentThread());
4079 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4082 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4083 AFS_TRACE_LEVEL_VERBOSE_2,
4084 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4085 &DirEntry->NameInformation.FileName,
4086 pObjectInfo->FileId.Cell,
4087 pObjectInfo->FileId.Volume,
4088 pObjectInfo->FileId.Vnode,
4089 pObjectInfo->FileId.Unique);
4091 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4094 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4097 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4100 if( !NT_SUCCESS( ntStatus))
4103 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4104 AFS_TRACE_LEVEL_ERROR,
4105 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4106 &DirEntry->NameInformation.FileName,
4107 pObjectInfo->FileId.Cell,
4108 pObjectInfo->FileId.Volume,
4109 pObjectInfo->FileId.Vnode,
4110 pObjectInfo->FileId.Unique,
4118 // Update the metadata for the entry
4121 ntStatus = AFSUpdateMetaData( DirEntry,
4124 if( NT_SUCCESS( ntStatus))
4127 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4135 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4136 AFS_TRACE_LEVEL_WARNING,
4137 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4138 pObjectInfo->FileType,
4140 &DirEntry->NameInformation.FileName,
4141 pObjectInfo->FileId.Cell,
4142 pObjectInfo->FileId.Volume,
4143 pObjectInfo->FileId.Vnode,
4144 pObjectInfo->FileId.Unique);
4154 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4157 if( pDirEnumEntry != NULL)
4160 AFSExFreePool( pDirEnumEntry);
4168 AFSInitializeSpecialShareNameList()
4171 NTSTATUS ntStatus = STATUS_SUCCESS;
4172 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4173 AFSObjectInfoCB *pObjectInfoCB = NULL;
4174 UNICODE_STRING uniShareName;
4175 ULONG ulEntryLength = 0;
4176 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4181 RtlInitUnicodeString( &uniShareName,
4184 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4187 if( pObjectInfoCB == NULL)
4190 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4193 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4194 AFS_TRACE_LEVEL_VERBOSE,
4195 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
4198 pObjectInfoCB->ObjectReferenceCount = 1;
4200 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4202 ulEntryLength = sizeof( AFSDirectoryCB) +
4203 uniShareName.Length;
4205 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4209 if( pDirNode == NULL)
4212 AFSDeleteObjectInfo( pObjectInfoCB);
4214 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4217 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4218 sizeof( AFSNonPagedDirectoryCB),
4219 AFS_DIR_ENTRY_NP_TAG);
4221 if( pNonPagedDirEntry == NULL)
4224 ExFreePool( pDirNode);
4226 AFSDeleteObjectInfo( pObjectInfoCB);
4228 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4231 RtlZeroMemory( pDirNode,
4234 RtlZeroMemory( pNonPagedDirEntry,
4235 sizeof( AFSNonPagedDirectoryCB));
4237 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4239 pDirNode->NonPaged = pNonPagedDirEntry;
4241 pDirNode->ObjectInformation = pObjectInfoCB;
4247 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
4249 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4251 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4253 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4255 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4256 uniShareName.Buffer,
4257 pDirNode->NameInformation.FileName.Length);
4259 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4262 AFSSpecialShareNames = pDirNode;
4264 pLastDirNode = pDirNode;
4266 RtlInitUnicodeString( &uniShareName,
4269 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4272 if( pObjectInfoCB == NULL)
4275 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4278 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4279 AFS_TRACE_LEVEL_VERBOSE,
4280 "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
4283 pObjectInfoCB->ObjectReferenceCount = 1;
4285 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4287 ulEntryLength = sizeof( AFSDirectoryCB) +
4288 uniShareName.Length;
4290 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4294 if( pDirNode == NULL)
4297 AFSDeleteObjectInfo( pObjectInfoCB);
4299 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4302 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4303 sizeof( AFSNonPagedDirectoryCB),
4304 AFS_DIR_ENTRY_NP_TAG);
4306 if( pNonPagedDirEntry == NULL)
4309 ExFreePool( pDirNode);
4311 AFSDeleteObjectInfo( pObjectInfoCB);
4313 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4316 RtlZeroMemory( pDirNode,
4319 RtlZeroMemory( pNonPagedDirEntry,
4320 sizeof( AFSNonPagedDirectoryCB));
4322 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4324 pDirNode->NonPaged = pNonPagedDirEntry;
4326 pDirNode->ObjectInformation = pObjectInfoCB;
4332 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
4334 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4336 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4338 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4340 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4341 uniShareName.Buffer,
4342 pDirNode->NameInformation.FileName.Length);
4344 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4347 pLastDirNode->ListEntry.fLink = pDirNode;
4349 pDirNode->ListEntry.bLink = pLastDirNode;
4351 pLastDirNode = pDirNode;
4353 RtlInitUnicodeString( &uniShareName,
4356 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4359 if( pObjectInfoCB == NULL)
4362 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4365 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4366 AFS_TRACE_LEVEL_VERBOSE,
4367 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4370 pObjectInfoCB->ObjectReferenceCount = 1;
4372 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4374 ulEntryLength = sizeof( AFSDirectoryCB) +
4375 uniShareName.Length;
4377 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4381 if( pDirNode == NULL)
4384 AFSDeleteObjectInfo( pObjectInfoCB);
4386 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4389 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4390 sizeof( AFSNonPagedDirectoryCB),
4391 AFS_DIR_ENTRY_NP_TAG);
4393 if( pNonPagedDirEntry == NULL)
4396 ExFreePool( pDirNode);
4398 AFSDeleteObjectInfo( pObjectInfoCB);
4400 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4403 RtlZeroMemory( pDirNode,
4406 RtlZeroMemory( pNonPagedDirEntry,
4407 sizeof( AFSNonPagedDirectoryCB));
4409 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4411 pDirNode->NonPaged = pNonPagedDirEntry;
4413 pDirNode->ObjectInformation = pObjectInfoCB;
4419 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4421 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4423 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4425 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4427 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4428 uniShareName.Buffer,
4429 pDirNode->NameInformation.FileName.Length);
4431 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4434 pLastDirNode->ListEntry.fLink = pDirNode;
4436 pDirNode->ListEntry.bLink = pLastDirNode;
4440 if( !NT_SUCCESS( ntStatus))
4443 if( AFSSpecialShareNames != NULL)
4446 pDirNode = AFSSpecialShareNames;
4448 while( pDirNode != NULL)
4451 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4453 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4455 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4457 ExFreePool( pDirNode->NonPaged);
4459 ExFreePool( pDirNode);
4461 pDirNode = pLastDirNode;
4464 AFSSpecialShareNames = NULL;
4473 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4474 IN UNICODE_STRING *SecondaryName)
4477 AFSDirectoryCB *pDirectoryCB = NULL;
4478 ULONGLONG ullHash = 0;
4479 UNICODE_STRING uniFullShareName;
4485 // Build up the entire name here. We are guaranteed that if there is a
4486 // secondary name, it is pointing to a portion of the share name buffer
4489 if( SecondaryName->Length > 0 &&
4490 SecondaryName->Buffer != NULL)
4493 uniFullShareName = *SecondaryName;
4496 // The calling routine strips off the leading slash so add it back in
4499 uniFullShareName.Buffer--;
4500 uniFullShareName.Length += sizeof( WCHAR);
4501 uniFullShareName.MaximumLength += sizeof( WCHAR);
4504 // And the share name
4507 uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
4508 uniFullShareName.Length += ShareName->Length;
4509 uniFullShareName.MaximumLength += ShareName->Length;
4514 uniFullShareName = *ShareName;
4518 // Generate our hash value
4521 ullHash = AFSGenerateCRC( &uniFullShareName,
4525 // Loop through our special share names to see if this is one of them
4528 pDirectoryCB = AFSSpecialShareNames;
4530 while( pDirectoryCB != NULL)
4533 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4539 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4543 return pDirectoryCB;
4547 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4551 // Block on the queue flush event
4554 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4564 AFSWaitOnQueuedReleases()
4567 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4570 // Block on the queue flush event
4573 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4583 AFSIsEqualFID( IN AFSFileID *FileId1,
4584 IN AFSFileID *FileId2)
4587 BOOLEAN bIsEqual = FALSE;
4589 if( FileId1->Hash == FileId2->Hash &&
4590 FileId1->Unique == FileId2->Unique &&
4591 FileId1->Vnode == FileId2->Vnode &&
4592 FileId1->Volume == FileId2->Volume &&
4593 FileId1->Cell == FileId2->Cell)
4603 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4606 NTSTATUS ntStatus = STATUS_SUCCESS;
4607 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4612 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4615 // Reset the directory list information
4618 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4620 while( pCurrentDirEntry != NULL)
4623 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4625 if( pCurrentDirEntry->OpenReferenceCount == 0)
4628 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4629 AFS_TRACE_LEVEL_VERBOSE,
4630 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4632 &pCurrentDirEntry->NameInformation.FileName);
4634 AFSDeleteDirEntry( ObjectInfoCB,
4640 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4641 AFS_TRACE_LEVEL_VERBOSE,
4642 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4644 &pCurrentDirEntry->NameInformation.FileName);
4646 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4648 AFSRemoveNameEntry( ObjectInfoCB,
4652 pCurrentDirEntry = pNextDirEntry;
4655 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4657 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4659 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4661 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4663 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4665 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4667 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4668 AFS_TRACE_LEVEL_VERBOSE,
4669 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4670 ObjectInfoCB->FileId.Cell,
4671 ObjectInfoCB->FileId.Volume,
4672 ObjectInfoCB->FileId.Vnode,
4673 ObjectInfoCB->FileId.Unique);
4680 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4683 NTSTATUS ntStatus = STATUS_SUCCESS;
4684 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4685 UNICODE_STRING uniFullName;
4690 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4691 AFS_TRACE_LEVEL_VERBOSE,
4692 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4693 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4694 PsGetCurrentThread());
4696 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4699 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4702 try_return( ntStatus);
4706 // Initialize the root information
4709 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4712 // Enumerate the shares in the volume
4715 ntStatus = AFSEnumerateDirectory( AuthGroup,
4716 &AFSGlobalRoot->ObjectInformation,
4719 if( !NT_SUCCESS( ntStatus))
4722 try_return( ntStatus);
4725 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4728 // Indicate the node is initialized
4731 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4733 uniFullName.MaximumLength = PAGE_SIZE;
4734 uniFullName.Length = 0;
4736 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4737 uniFullName.MaximumLength,
4738 AFS_GENERIC_MEMORY_12_TAG);
4740 if( uniFullName.Buffer == NULL)
4744 // Reset the directory content
4747 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4749 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4751 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4755 // Populate our list of entries in the NP enumeration list
4758 while( pDirGlobalDirNode != NULL)
4761 uniFullName.Buffer[ 0] = L'\\';
4762 uniFullName.Buffer[ 1] = L'\\';
4764 uniFullName.Length = 2 * sizeof( WCHAR);
4766 RtlCopyMemory( &uniFullName.Buffer[ 2],
4767 AFSServerName.Buffer,
4768 AFSServerName.Length);
4770 uniFullName.Length += AFSServerName.Length;
4772 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4774 uniFullName.Length += sizeof( WCHAR);
4776 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4777 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4778 pDirGlobalDirNode->NameInformation.FileName.Length);
4780 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4782 AFSAddConnectionEx( &uniFullName,
4783 RESOURCEDISPLAYTYPE_SHARE,
4786 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4789 AFSExFreePool( uniFullName.Buffer);
4793 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4800 AFSIsRelativeName( IN UNICODE_STRING *Name)
4803 BOOLEAN bIsRelative = FALSE;
4805 if( Name->Buffer[ 0] != L'\\')
4815 AFSUpdateName( IN UNICODE_STRING *Name)
4820 while( usIndex < Name->Length/sizeof( WCHAR))
4823 if( Name->Buffer[ usIndex] == L'/')
4826 Name->Buffer[ usIndex] = L'\\';
4836 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4837 IN OUT ULONG *Flags,
4838 IN WCHAR *NameBuffer,
4839 IN USHORT NameLength)
4842 NTSTATUS ntStatus = STATUS_SUCCESS;
4843 WCHAR *pTmpBuffer = NULL;
4849 // If we have enough space then just move in the name otherwise
4850 // allocate a new buffer
4853 if( TargetName->Length < NameLength)
4856 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4858 AFS_NAME_BUFFER_FIVE_TAG);
4860 if( pTmpBuffer == NULL)
4863 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4866 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4869 AFSExFreePool( TargetName->Buffer);
4872 TargetName->MaximumLength = NameLength;
4874 TargetName->Buffer = pTmpBuffer;
4876 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4879 TargetName->Length = NameLength;
4881 RtlCopyMemory( TargetName->Buffer,
4883 TargetName->Length);
4886 // Update the name in the buffer
4889 AFSUpdateName( TargetName);
4900 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4901 IN ULONG InitialElementCount)
4904 AFSNameArrayHdr *pNameArray = NULL;
4905 AFSNameArrayCB *pCurrentElement = NULL;
4906 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4912 if( InitialElementCount == 0)
4915 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
4918 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
4919 sizeof( AFSNameArrayHdr) +
4920 (InitialElementCount * sizeof( AFSNameArrayCB)),
4921 AFS_NAME_ARRAY_TAG);
4923 if( pNameArray == NULL)
4926 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
4927 AFS_TRACE_LEVEL_ERROR,
4928 "AFSInitNameArray Failed to allocate name array\n");
4930 try_return( pNameArray);
4933 RtlZeroMemory( pNameArray,
4934 sizeof( AFSNameArrayHdr) +
4935 (InitialElementCount * sizeof( AFSNameArrayCB)));
4937 pNameArray->MaxElementCount = InitialElementCount;
4939 if( DirectoryCB != NULL)
4942 pCurrentElement = &pNameArray->ElementArray[ 0];
4944 pNameArray->CurrentEntry = pCurrentElement;
4946 pNameArray->Count = 1;
4948 pNameArray->LinkCount = 0;
4950 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
4952 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4953 AFS_TRACE_LEVEL_VERBOSE,
4954 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
4955 &DirectoryCB->NameInformation.FileName,
4959 pCurrentElement->DirectoryCB = DirectoryCB;
4961 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
4963 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
4965 if( pCurrentElement->FileId.Vnode == 1)
4968 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
4971 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
4972 AFS_TRACE_LEVEL_VERBOSE,
4973 "AFSInitNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
4975 pCurrentElement->DirectoryCB,
4976 pCurrentElement->FileId.Cell,
4977 pCurrentElement->FileId.Volume,
4978 pCurrentElement->FileId.Vnode,
4979 pCurrentElement->FileId.Unique,
4980 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4981 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
4993 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
4994 IN UNICODE_STRING *Path,
4995 IN AFSDirectoryCB *DirectoryCB)
4998 NTSTATUS ntStatus = STATUS_SUCCESS;
4999 AFSNameArrayCB *pCurrentElement = NULL;
5000 UNICODE_STRING uniComponentName, uniRemainingPath;
5001 AFSObjectInfoCB *pCurrentObject = NULL;
5002 ULONG ulTotalCount = 0;
5004 USHORT usLength = 0;
5010 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5011 AFS_TRACE_LEVEL_VERBOSE,
5012 "AFSPopulateNameArray [NA:%p] passed Path %wZ DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5016 DirectoryCB->ObjectInformation->FileId.Cell,
5017 DirectoryCB->ObjectInformation->FileId.Volume,
5018 DirectoryCB->ObjectInformation->FileId.Vnode,
5019 DirectoryCB->ObjectInformation->FileId.Unique,
5020 &DirectoryCB->NameInformation.FileName,
5021 DirectoryCB->ObjectInformation->FileType);
5024 // Init some info in the header
5027 pCurrentElement = &NameArray->ElementArray[ 0];
5029 NameArray->CurrentEntry = pCurrentElement;
5032 // The first entry points at the root
5035 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
5037 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5039 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5040 AFS_TRACE_LEVEL_VERBOSE,
5041 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
5042 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5043 pCurrentElement->DirectoryCB,
5046 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
5048 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
5050 pCurrentElement->Flags = 0;
5052 if( pCurrentElement->FileId.Vnode == 1)
5055 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5058 NameArray->Count = 1;
5060 NameArray->LinkCount = 0;
5062 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5063 AFS_TRACE_LEVEL_VERBOSE,
5064 "AFSPopulateNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5066 pCurrentElement->DirectoryCB,
5067 pCurrentElement->FileId.Cell,
5068 pCurrentElement->FileId.Volume,
5069 pCurrentElement->FileId.Vnode,
5070 pCurrentElement->FileId.Unique,
5071 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5072 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5075 // If the root is the parent then we are done ...
5078 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
5080 try_return( ntStatus);
5092 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
5093 IN AFSNameArrayHdr *RelatedNameArray,
5094 IN AFSDirectoryCB *DirectoryCB)
5097 NTSTATUS ntStatus = STATUS_SUCCESS;
5098 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
5099 UNICODE_STRING uniComponentName, uniRemainingPath;
5100 AFSObjectInfoCB *pObjectInfo = NULL;
5101 ULONG ulTotalCount = 0;
5103 USHORT usLength = 0;
5109 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5110 AFS_TRACE_LEVEL_VERBOSE,
5111 "AFSPopulateNameArray [NA:%p] passed RelatedNameArray %p DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5115 DirectoryCB->ObjectInformation->FileId.Cell,
5116 DirectoryCB->ObjectInformation->FileId.Volume,
5117 DirectoryCB->ObjectInformation->FileId.Vnode,
5118 DirectoryCB->ObjectInformation->FileId.Unique,
5119 &DirectoryCB->NameInformation.FileName,
5120 DirectoryCB->ObjectInformation->FileType);
5123 // Init some info in the header
5126 pCurrentElement = &NameArray->ElementArray[ 0];
5128 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5130 NameArray->Count = 0;
5132 NameArray->LinkCount = RelatedNameArray->LinkCount;
5135 // Populate the name array with the data from the related array
5141 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5143 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5145 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5147 pCurrentElement->Flags = 0;
5149 if( pCurrentElement->FileId.Vnode == 1)
5152 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5155 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5157 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5158 AFS_TRACE_LEVEL_VERBOSE,
5159 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
5160 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5161 pCurrentElement->DirectoryCB,
5164 lCount = InterlockedIncrement( &NameArray->Count);
5166 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5167 AFS_TRACE_LEVEL_VERBOSE,
5168 "AFSPopulateNameArrayFromRelatedArray [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5171 pCurrentElement->DirectoryCB,
5172 pCurrentElement->FileId.Cell,
5173 pCurrentElement->FileId.Volume,
5174 pCurrentElement->FileId.Vnode,
5175 pCurrentElement->FileId.Unique,
5176 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5177 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5179 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5180 NameArray->Count == RelatedNameArray->Count)
5192 pCurrentRelatedElement++;
5195 NameArray->CurrentEntry = NameArray->Count > 0 ? pCurrentElement : NULL;
5202 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5205 NTSTATUS ntStatus = STATUS_SUCCESS;
5206 AFSNameArrayCB *pCurrentElement = NULL;
5207 LONG lCount, lElement;
5212 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5213 AFS_TRACE_LEVEL_VERBOSE,
5214 "AFSFreeNameArray [NA:%p]\n",
5217 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5220 pCurrentElement = &NameArray->ElementArray[ lElement];
5222 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5224 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5225 AFS_TRACE_LEVEL_VERBOSE,
5226 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
5227 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5228 pCurrentElement->DirectoryCB,
5232 AFSExFreePool( NameArray);
5239 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5240 IN AFSDirectoryCB *DirectoryCB)
5243 NTSTATUS ntStatus = STATUS_SUCCESS;
5244 AFSNameArrayCB *pCurrentElement = NULL;
5250 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5251 AFS_TRACE_LEVEL_VERBOSE,
5252 "AFSInsertNextElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5255 DirectoryCB->ObjectInformation->FileId.Cell,
5256 DirectoryCB->ObjectInformation->FileId.Volume,
5257 DirectoryCB->ObjectInformation->FileId.Vnode,
5258 DirectoryCB->ObjectInformation->FileId.Unique,
5259 &DirectoryCB->NameInformation.FileName,
5260 DirectoryCB->ObjectInformation->FileType);
5262 if( NameArray->Count == NameArray->MaxElementCount)
5265 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5266 AFS_TRACE_LEVEL_ERROR,
5267 "AFSInsertNextElement [NA:%p] Name has reached Maximum Size\n",
5270 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5273 for ( lCount = 0; lCount < NameArray->Count; lCount++)
5276 if ( AFSIsEqualFID( &NameArray->ElementArray[ lCount].FileId,
5277 &DirectoryCB->ObjectInformation->FileId) )
5280 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5281 AFS_TRACE_LEVEL_WARNING,
5282 "AFSInsertNextElement [NA:%p] DE %p recursion Status %08X\n",
5285 STATUS_ACCESS_DENIED);
5287 try_return( ntStatus = STATUS_ACCESS_DENIED);
5291 if( NameArray->Count > 0)
5294 NameArray->CurrentEntry++;
5298 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5301 pCurrentElement = NameArray->CurrentEntry;
5303 lCount = InterlockedIncrement( &NameArray->Count);
5305 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5307 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5308 AFS_TRACE_LEVEL_VERBOSE,
5309 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
5310 &DirectoryCB->NameInformation.FileName,
5314 pCurrentElement->DirectoryCB = DirectoryCB;
5316 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5318 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5320 pCurrentElement->Flags = 0;
5322 if( pCurrentElement->FileId.Vnode == 1)
5325 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5328 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5329 AFS_TRACE_LEVEL_VERBOSE,
5330 "AFSInsertNextElement [NA:%p] Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5332 NameArray->Count - 1,
5333 pCurrentElement->DirectoryCB,
5334 pCurrentElement->FileId.Cell,
5335 pCurrentElement->FileId.Volume,
5336 pCurrentElement->FileId.Vnode,
5337 pCurrentElement->FileId.Unique,
5338 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5339 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5350 AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
5351 IN AFSDirectoryCB *DirectoryCB)
5353 AFSNameArrayCB *pCurrentElement = NULL;
5356 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5357 AFS_TRACE_LEVEL_VERBOSE,
5358 "AFSReplaceCurrentElement [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5361 DirectoryCB->ObjectInformation->FileId.Cell,
5362 DirectoryCB->ObjectInformation->FileId.Volume,
5363 DirectoryCB->ObjectInformation->FileId.Vnode,
5364 DirectoryCB->ObjectInformation->FileId.Unique,
5365 &DirectoryCB->NameInformation.FileName,
5366 DirectoryCB->ObjectInformation->FileType);
5368 ASSERT( NameArray->CurrentEntry != NULL);
5370 pCurrentElement = NameArray->CurrentEntry;
5372 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5373 AFS_TRACE_LEVEL_VERBOSE,
5374 "AFSReplaceCurrentElement [NA:%p] Replacing Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5376 NameArray->Count - 1,
5377 pCurrentElement->DirectoryCB,
5378 pCurrentElement->FileId.Cell,
5379 pCurrentElement->FileId.Volume,
5380 pCurrentElement->FileId.Vnode,
5381 pCurrentElement->FileId.Unique,
5382 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5383 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5385 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5387 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5388 AFS_TRACE_LEVEL_VERBOSE,
5389 "AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
5390 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5391 pCurrentElement->DirectoryCB,
5394 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5396 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5397 AFS_TRACE_LEVEL_VERBOSE,
5398 "AFSReplaceCurrentElement Increment count on %wZ DE %p Cnt %d\n",
5399 &DirectoryCB->NameInformation.FileName,
5403 pCurrentElement->DirectoryCB = DirectoryCB;
5405 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5407 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5409 pCurrentElement->Flags = 0;
5411 if( pCurrentElement->FileId.Vnode == 1)
5414 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5421 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5424 AFSDirectoryCB *pDirectoryCB = NULL;
5425 AFSNameArrayCB *pCurrentElement = NULL;
5431 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5432 AFS_TRACE_LEVEL_VERBOSE,
5433 "AFSBackupEntry [NA:%p]\n",
5436 if( NameArray->Count == 0)
5439 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5440 AFS_TRACE_LEVEL_ERROR,
5441 "AFSBackupEntry [NA:%p] No more entries\n",
5444 try_return( pCurrentElement);
5447 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5449 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5450 AFS_TRACE_LEVEL_VERBOSE,
5451 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5452 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5453 NameArray->CurrentEntry->DirectoryCB,
5456 NameArray->CurrentEntry->DirectoryCB = NULL;
5458 lCount = InterlockedDecrement( &NameArray->Count);
5462 NameArray->CurrentEntry = NULL;
5464 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5465 AFS_TRACE_LEVEL_ERROR,
5466 "AFSBackupEntry [NA:%p] No more entries\n",
5471 NameArray->CurrentEntry--;
5473 pCurrentElement = NameArray->CurrentEntry;
5475 pDirectoryCB = pCurrentElement->DirectoryCB;
5477 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5478 AFS_TRACE_LEVEL_VERBOSE,
5479 "AFSBackupEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5481 NameArray->Count - 1,
5482 pCurrentElement->DirectoryCB,
5483 pCurrentElement->FileId.Cell,
5484 pCurrentElement->FileId.Volume,
5485 pCurrentElement->FileId.Vnode,
5486 pCurrentElement->FileId.Unique,
5487 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5488 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5496 return pDirectoryCB;
5500 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5503 AFSDirectoryCB *pDirEntry = NULL;
5504 AFSNameArrayCB *pElement = NULL;
5509 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5510 AFS_TRACE_LEVEL_VERBOSE,
5511 "AFSGetParentEntry [NA:%p]\n",
5514 if( NameArray->Count == 0 ||
5515 NameArray->Count == 1)
5518 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5519 AFS_TRACE_LEVEL_ERROR,
5520 "AFSGetParentEntry [NA:%p] No more entries\n",
5523 try_return( pDirEntry = NULL);
5526 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5528 pDirEntry = pElement->DirectoryCB;
5530 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5531 AFS_TRACE_LEVEL_VERBOSE,
5532 "AFSGetParentEntry [NA:%p] Returning Element[%d] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5534 NameArray->Count - 2,
5535 pElement->DirectoryCB,
5536 pElement->FileId.Cell,
5537 pElement->FileId.Volume,
5538 pElement->FileId.Vnode,
5539 pElement->FileId.Unique,
5540 &pElement->DirectoryCB->NameInformation.FileName,
5541 pElement->DirectoryCB->ObjectInformation->FileType);
5552 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5553 IN AFSDirectoryCB *DirectoryCB)
5556 AFSNameArrayCB *pCurrentElement = NULL;
5557 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5558 LONG lCount, lElement;
5563 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5564 AFS_TRACE_LEVEL_VERBOSE,
5565 "AFSResetNameArray [NA:%p] passed DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5568 DirectoryCB->ObjectInformation->FileId.Cell,
5569 DirectoryCB->ObjectInformation->FileId.Volume,
5570 DirectoryCB->ObjectInformation->FileId.Vnode,
5571 DirectoryCB->ObjectInformation->FileId.Unique,
5572 &DirectoryCB->NameInformation.FileName,
5573 DirectoryCB->ObjectInformation->FileType);
5575 // Dereference previous name array contents
5578 for ( lElement = 0; lElement < NameArray->Count; lElement++)
5581 pCurrentElement = &NameArray->ElementArray[ lElement];
5583 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5585 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5586 AFS_TRACE_LEVEL_VERBOSE,
5587 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5588 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5589 pCurrentElement->DirectoryCB,
5593 RtlZeroMemory( NameArray,
5594 sizeof( AFSNameArrayHdr) +
5595 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5597 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5599 if( DirectoryCB != NULL)
5602 pCurrentElement = &NameArray->ElementArray[ 0];
5604 NameArray->CurrentEntry = pCurrentElement;
5606 NameArray->Count = 1;
5608 NameArray->LinkCount = 0;
5610 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5612 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5613 AFS_TRACE_LEVEL_VERBOSE,
5614 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5615 &DirectoryCB->NameInformation.FileName,
5619 pCurrentElement->DirectoryCB = DirectoryCB;
5621 pCurrentElement->Component = DirectoryCB->NameInformation.FileName;
5623 pCurrentElement->FileId = DirectoryCB->ObjectInformation->FileId;
5625 pCurrentElement->Flags = 0;
5627 if( pCurrentElement->FileId.Vnode == 1)
5630 SetFlag( pCurrentElement->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5633 AFSDbgLogMsg( AFS_SUBSYSTEM_NAME_ARRAY_PROCESSING,
5634 AFS_TRACE_LEVEL_VERBOSE,
5635 "AFSResetNameArray [NA:%p] Element[0] DE %p FID %08lX-%08lX-%08lX-%08lX %wZ Type %d\n",
5637 pCurrentElement->DirectoryCB,
5638 pCurrentElement->FileId.Cell,
5639 pCurrentElement->FileId.Volume,
5640 pCurrentElement->FileId.Vnode,
5641 pCurrentElement->FileId.Unique,
5642 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5643 pCurrentElement->DirectoryCB->ObjectInformation->FileType);
5651 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5654 AFSNameArrayCB *pCurrentElement = NULL;
5656 pCurrentElement = &NameArray->ElementArray[ 0];
5658 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5660 while( pCurrentElement->DirectoryCB != NULL)
5663 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5664 pCurrentElement->FileId.Cell,
5665 pCurrentElement->FileId.Volume,
5666 pCurrentElement->FileId.Vnode,
5667 pCurrentElement->FileId.Unique,
5668 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5673 AFSPrint("AFSDumpNameArray End\n\n");
5679 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5684 // Depending on the type of node, set the event
5687 switch( Fcb->Header.NodeTypeCode)
5690 case AFS_DIRECTORY_FCB:
5695 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5705 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5711 // Depending on the type of node, set the event
5714 switch( Fcb->Header.NodeTypeCode)
5717 case AFS_DIRECTORY_FCB:
5722 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5724 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5734 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5737 BOOLEAN bIsInProcess = FALSE;
5742 if( ObjectInfo->Fcb == NULL)
5745 try_return( bIsInProcess);
5748 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5751 case AFS_DIRECTORY_FCB:
5756 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5759 bIsInProcess = TRUE;
5771 return bIsInProcess;
5775 AFSVerifyVolume( IN ULONGLONG ProcessId,
5776 IN AFSVolumeCB *VolumeCB)
5779 NTSTATUS ntStatus = STATUS_SUCCESS;
5786 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5789 NTSTATUS ntStatus = STATUS_SUCCESS;
5790 AFSObjectInfoCB *pObjectInfoCB = NULL;
5791 AFSDirectoryCB *pDirNode = NULL;
5792 ULONG ulEntryLength = 0;
5793 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5799 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5802 if( pObjectInfoCB == NULL)
5805 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5808 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5809 AFS_TRACE_LEVEL_VERBOSE,
5810 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5813 pObjectInfoCB->ObjectReferenceCount = 1;
5815 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5817 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5819 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5821 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5825 if( pDirNode == NULL)
5828 AFSDeleteObjectInfo( pObjectInfoCB);
5830 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5833 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5834 sizeof( AFSNonPagedDirectoryCB),
5835 AFS_DIR_ENTRY_NP_TAG);
5837 if( pNonPagedDirEntry == NULL)
5840 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5843 RtlZeroMemory( pDirNode,
5846 RtlZeroMemory( pNonPagedDirEntry,
5847 sizeof( AFSNonPagedDirectoryCB));
5849 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5851 pDirNode->NonPaged = pNonPagedDirEntry;
5853 pDirNode->ObjectInformation = pObjectInfoCB;
5855 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5861 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5863 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5865 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5867 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5869 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5870 AFSPIOCtlName.Buffer,
5871 pDirNode->NameInformation.FileName.Length);
5873 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5876 if ( InterlockedCompareExchangePointer( (PVOID *)&ObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5879 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5880 AFS_TRACE_LEVEL_WARNING,
5881 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %08lX pFcb %08lX\n",
5882 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5886 // Increment the open reference and handle on the node
5889 lCount = InterlockedIncrement( &pDirNode->ObjectInformation->ObjectReferenceCount);
5891 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
5892 AFS_TRACE_LEVEL_VERBOSE,
5893 "AFSInitPIOCtlDirectoryCB Increment count on Object %08lX Cnt %d\n",
5894 pDirNode->ObjectInformation,
5897 try_return( ntStatus = STATUS_REPARSE);
5902 if ( ntStatus != STATUS_SUCCESS)
5905 if ( pDirNode != NULL)
5908 AFSExFreePool( pDirNode);
5911 if ( pObjectInfoCB != NULL)
5914 AFSDeleteObjectInfo( pObjectInfoCB);
5923 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5924 IN AFSDirectoryCB *DirectoryCB,
5925 IN UNICODE_STRING *ParentPathName,
5926 IN AFSNameArrayHdr *RelatedNameArray,
5928 OUT AFSFileInfoCB *FileInfo)
5931 NTSTATUS ntStatus = STATUS_SUCCESS;
5932 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
5933 UNICODE_STRING uniFullPathName;
5934 AFSNameArrayHdr *pNameArray = NULL;
5935 AFSVolumeCB *pVolumeCB = NULL;
5936 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5937 WCHAR *pwchBuffer = NULL;
5938 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5939 ULONG ulNameDifference = 0;
5946 // Retrieve a target name for the entry
5949 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5952 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5955 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5957 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5962 if( !NT_SUCCESS( ntStatus) ||
5963 pDirEntry->TargetNameLength == 0)
5966 if( pDirEntry != NULL)
5969 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5972 try_return( ntStatus);
5975 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5978 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5982 // Update the target name
5985 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5986 &DirectoryCB->Flags,
5987 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5988 (USHORT)pDirEntry->TargetNameLength);
5990 if( !NT_SUCCESS( ntStatus))
5993 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5995 try_return( ntStatus);
5999 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6003 // Need to pass the full path in for parsing.
6006 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
6009 uniFullPathName.Length = 0;
6010 uniFullPathName.MaximumLength = ParentPathName->Length +
6012 DirectoryCB->NameInformation.TargetName.Length;
6014 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6015 uniFullPathName.MaximumLength,
6016 AFS_NAME_BUFFER_SIX_TAG);
6018 if( uniFullPathName.Buffer == NULL)
6021 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6023 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6026 pwchBuffer = uniFullPathName.Buffer;
6028 RtlZeroMemory( uniFullPathName.Buffer,
6029 uniFullPathName.MaximumLength);
6031 RtlCopyMemory( uniFullPathName.Buffer,
6032 ParentPathName->Buffer,
6033 ParentPathName->Length);
6035 uniFullPathName.Length = ParentPathName->Length;
6037 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
6038 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
6041 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
6043 uniFullPathName.Length += sizeof( WCHAR);
6046 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
6047 DirectoryCB->NameInformation.TargetName.Buffer,
6048 DirectoryCB->NameInformation.TargetName.Length);
6050 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
6052 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
6053 uniParsedName.MaximumLength = uniParsedName.Length;
6055 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
6057 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6060 // We populate up to the current parent
6063 if( RelatedNameArray != NULL)
6066 pNameArray = AFSInitNameArray( NULL,
6067 RelatedNameArray->MaxElementCount);
6069 if( pNameArray == NULL)
6072 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6075 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
6082 pNameArray = AFSInitNameArray( NULL,
6085 if( pNameArray == NULL)
6088 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6091 ntStatus = AFSPopulateNameArray( pNameArray,
6096 if( !NT_SUCCESS( ntStatus))
6099 try_return( ntStatus);
6102 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
6104 pParentDirEntry = ParentDirectoryCB;
6109 uniFullPathName.Length = 0;
6110 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6112 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6113 uniFullPathName.MaximumLength,
6114 AFS_NAME_BUFFER_SEVEN_TAG);
6116 if( uniFullPathName.Buffer == NULL)
6119 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6121 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6124 pwchBuffer = uniFullPathName.Buffer;
6126 RtlZeroMemory( uniFullPathName.Buffer,
6127 uniFullPathName.MaximumLength);
6129 RtlCopyMemory( uniFullPathName.Buffer,
6130 DirectoryCB->NameInformation.TargetName.Buffer,
6131 DirectoryCB->NameInformation.TargetName.Length);
6133 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6136 // This name should begin with the \afs server so parse it off and check it
6139 FsRtlDissectName( uniFullPathName,
6143 if( RtlCompareUnicodeString( &uniComponentName,
6148 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6150 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6151 AFS_TRACE_LEVEL_ERROR,
6152 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
6155 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
6158 uniFullPathName = uniRemainingPath;
6160 uniParsedName = uniFullPathName;
6162 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6164 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6170 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6173 if( pNameArray == NULL)
6176 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6179 pVolumeCB = AFSGlobalRoot;
6181 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6185 // Increment the ref count on the volume and dir entry for correct processing below
6188 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6190 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6191 AFS_TRACE_LEVEL_VERBOSE,
6192 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
6196 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6198 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6199 AFS_TRACE_LEVEL_VERBOSE,
6200 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6201 &pParentDirEntry->NameInformation.FileName,
6206 ntStatus = AFSLocateNameEntry( NULL,
6211 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
6217 if( !NT_SUCCESS( ntStatus))
6221 // The volume lock was released on failure above
6222 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6225 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6228 if( pVolumeCB != NULL)
6231 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6233 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6234 AFS_TRACE_LEVEL_VERBOSE,
6235 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
6240 if( pDirectoryEntry != NULL)
6243 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6245 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6246 AFS_TRACE_LEVEL_VERBOSE,
6247 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6248 &pDirectoryEntry->NameInformation.FileName,
6256 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6258 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6259 AFS_TRACE_LEVEL_VERBOSE,
6260 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6261 &pParentDirEntry->NameInformation.FileName,
6270 try_return( ntStatus);
6274 // Store off the information
6277 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6280 // Check for the mount point being returned
6283 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
6286 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6288 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
6289 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6292 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6295 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6300 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6304 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6306 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6308 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6310 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6312 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6314 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6317 // Remove the reference made above
6320 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6322 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6323 AFS_TRACE_LEVEL_VERBOSE,
6324 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
6325 &pDirectoryEntry->NameInformation.FileName,
6332 if( pDirEntry != NULL)
6335 AFSExFreePool( pDirEntry);
6338 if( pVolumeCB != NULL)
6341 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6343 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6344 AFS_TRACE_LEVEL_VERBOSE,
6345 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
6350 if( pNameArray != NULL)
6353 AFSFreeNameArray( pNameArray);
6356 if( pwchBuffer != NULL)
6360 // Always free the buffer that we allocated as AFSLocateNameEntry
6361 // will not free it. If uniFullPathName.Buffer was allocated by
6362 // AFSLocateNameEntry, then we must free that as well.
6363 // Check that the uniFullPathName.Buffer in the string is not the same
6364 // offset by the length of the server name
6367 if( uniFullPathName.Length > 0 &&
6368 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6371 AFSExFreePool( uniFullPathName.Buffer);
6374 AFSExFreePool( pwchBuffer);
6382 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6383 IN ULONGLONG HashIndex)
6386 NTSTATUS ntStatus = STATUS_SUCCESS;
6387 AFSObjectInfoCB *pObjectInfo = NULL;
6393 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6394 sizeof( AFSObjectInfoCB),
6395 AFS_OBJECT_INFO_TAG);
6397 if( pObjectInfo == NULL)
6400 try_return( pObjectInfo);
6403 RtlZeroMemory( pObjectInfo,
6404 sizeof( AFSObjectInfoCB));
6406 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6407 sizeof( AFSNonPagedObjectInfoCB),
6408 AFS_NP_OBJECT_INFO_TAG);
6410 if( pObjectInfo->NonPagedInfo == NULL)
6413 AFSExFreePool( pObjectInfo);
6415 try_return( pObjectInfo = NULL);
6418 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6420 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6422 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6424 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6426 if( ParentObjectInfo != NULL)
6428 lCount = InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
6432 // Initialize the access time
6435 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6441 // Insert the entry into the object tree and list
6444 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6446 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6449 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6454 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6455 &pObjectInfo->TreeEntry);
6457 ASSERT( NT_SUCCESS( ntStatus));
6461 // And the object list in the volume
6464 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6467 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6472 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6474 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6477 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6480 // Indicate the object is in the hash tree and linked list in the volume
6483 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6495 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6498 BOOLEAN bAcquiredTreeLock = FALSE;
6501 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6504 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6506 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6509 bAcquiredTreeLock = TRUE;
6513 // Remove it from the tree and list if it was inserted
6516 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6519 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6520 &ObjectInfo->TreeEntry);
6523 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6526 if( ObjectInfo->ListEntry.fLink == NULL)
6529 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6531 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6534 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6540 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6543 if( ObjectInfo->ListEntry.bLink == NULL)
6546 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6548 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6551 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6557 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6561 if( ObjectInfo->ParentObjectInformation != NULL)
6564 lCount = InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
6567 if( bAcquiredTreeLock)
6570 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6574 // Release the fid in the service
6577 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6580 AFSReleaseFid( &ObjectInfo->FileId);
6583 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6585 AFSExFreePool( ObjectInfo->NonPagedInfo);
6587 AFSExFreePool( ObjectInfo);
6593 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6594 OUT AFSDirectoryCB **TargetDirEntry)
6597 NTSTATUS ntStatus = STATUS_SUCCESS;
6598 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6599 UNICODE_STRING uniFullPathName;
6600 AFSNameArrayHdr *pNameArray = NULL;
6601 AFSVolumeCB *pVolumeCB = NULL;
6602 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6603 WCHAR *pwchBuffer = NULL;
6604 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6605 ULONG ulNameDifference = 0;
6612 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6613 DirectoryCB->ObjectInformation,
6617 if( !NT_SUCCESS( ntStatus))
6619 try_return( ntStatus);
6623 // Retrieve a target name for the entry
6626 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6629 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6632 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6634 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6639 if( !NT_SUCCESS( ntStatus) ||
6640 pDirEntry->TargetNameLength == 0)
6643 if( pDirEntry != NULL)
6646 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6649 try_return( ntStatus);
6652 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6655 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6659 // Update the target name
6662 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6663 &DirectoryCB->Flags,
6664 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6665 (USHORT)pDirEntry->TargetNameLength);
6667 if( !NT_SUCCESS( ntStatus))
6670 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6672 try_return( ntStatus);
6676 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6680 // Need to pass the full path in for parsing.
6683 uniFullPathName.Length = 0;
6684 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6686 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6687 uniFullPathName.MaximumLength,
6688 AFS_NAME_BUFFER_EIGHT_TAG);
6690 if( uniFullPathName.Buffer == NULL)
6693 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6695 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6698 pwchBuffer = uniFullPathName.Buffer;
6700 RtlZeroMemory( uniFullPathName.Buffer,
6701 uniFullPathName.MaximumLength);
6703 RtlCopyMemory( uniFullPathName.Buffer,
6704 DirectoryCB->NameInformation.TargetName.Buffer,
6705 DirectoryCB->NameInformation.TargetName.Length);
6707 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6710 // This name should begin with the \afs server so parse it off and chech it
6713 FsRtlDissectName( uniFullPathName,
6717 if( RtlCompareUnicodeString( &uniComponentName,
6723 // Try evaluating the full path
6726 uniFullPathName.Buffer = pwchBuffer;
6728 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6730 uniFullPathName.MaximumLength = uniFullPathName.Length;
6735 uniFullPathName = uniRemainingPath;
6738 uniParsedName = uniFullPathName;
6740 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6742 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6748 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6751 if( pNameArray == NULL)
6754 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6757 pVolumeCB = AFSGlobalRoot;
6759 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6761 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6763 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6764 AFS_TRACE_LEVEL_VERBOSE,
6765 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6769 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6771 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6772 AFS_TRACE_LEVEL_VERBOSE,
6773 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6774 &pParentDirEntry->NameInformation.FileName,
6779 ntStatus = AFSLocateNameEntry( NULL,
6790 if( !NT_SUCCESS( ntStatus))
6794 // The volume lock was released on failure above
6795 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6798 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6801 if( pVolumeCB != NULL)
6804 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6806 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6807 AFS_TRACE_LEVEL_VERBOSE,
6808 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
6813 if( pDirectoryEntry != NULL)
6816 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6818 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6819 AFS_TRACE_LEVEL_VERBOSE,
6820 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6821 &pDirectoryEntry->NameInformation.FileName,
6829 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6831 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6832 AFS_TRACE_LEVEL_VERBOSE,
6833 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6834 &pParentDirEntry->NameInformation.FileName,
6843 try_return( ntStatus);
6847 // Pass back the target dir entry for this request
6850 *TargetDirEntry = pDirectoryEntry;
6854 if( pDirEntry != NULL)
6857 AFSExFreePool( pDirEntry);
6860 if( pVolumeCB != NULL)
6863 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6865 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6866 AFS_TRACE_LEVEL_VERBOSE,
6867 "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
6872 if( pNameArray != NULL)
6875 AFSFreeNameArray( pNameArray);
6878 if( pwchBuffer != NULL)
6882 // Always free the buffer that we allocated as AFSLocateNameEntry
6883 // will not free it. If uniFullPathName.Buffer was allocated by
6884 // AFSLocateNameEntry, then we must free that as well.
6885 // Check that the uniFullPathName.Buffer in the string is not the same
6886 // offset by the length of the server name
6889 if( uniFullPathName.Length > 0 &&
6890 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6893 AFSExFreePool( uniFullPathName.Buffer);
6896 AFSExFreePool( pwchBuffer);
6904 AFSCleanupFcb( IN AFSFcb *Fcb,
6905 IN BOOLEAN ForceFlush)
6908 NTSTATUS ntStatus = STATUS_SUCCESS;
6909 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6910 LARGE_INTEGER liTime;
6911 IO_STATUS_BLOCK stIoStatus;
6916 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6918 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6920 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6923 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6924 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6927 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6930 if( Fcb->OpenReferenceCount > 0)
6936 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6941 if( !NT_SUCCESS( stIoStatus.Status))
6944 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6945 AFS_TRACE_LEVEL_ERROR,
6946 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6947 Fcb->ObjectInformation->FileId.Cell,
6948 Fcb->ObjectInformation->FileId.Volume,
6949 Fcb->ObjectInformation->FileId.Vnode,
6950 Fcb->ObjectInformation->FileId.Unique,
6952 stIoStatus.Information);
6954 ntStatus = stIoStatus.Status;
6957 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6962 __except( EXCEPTION_EXECUTE_HANDLER)
6964 ntStatus = GetExceptionCode();
6968 AFSReleaseResource( &Fcb->NPFcb->Resource);
6971 // Wait for any currently running flush or release requests to complete
6974 AFSWaitOnQueuedFlushes( Fcb);
6977 // Now perform another flush on the file
6980 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6984 AFSReleaseExtentsWithFlush( Fcb,
6989 if( Fcb->OpenReferenceCount == 0 ||
6990 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6991 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6994 AFSTearDownFcbExtents( Fcb,
6998 try_return( ntStatus);
7001 KeQueryTickCount( &liTime);
7004 // First up are there dirty extents in the cache to flush?
7008 ( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
7009 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
7010 ( Fcb->Specific.File.ExtentsDirtyCount ||
7011 Fcb->Specific.File.ExtentCount) &&
7012 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7013 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7015 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7017 Fcb->OpenReferenceCount == 0)
7020 AFSReleaseExtentsWithFlush( Fcb,
7024 else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7025 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7029 // The file has been marked as invalid. Dump it
7032 AFSTearDownFcbExtents( Fcb,
7037 // If there are extents and they haven't been used recently *and*
7038 // are not being used
7042 ( 0 != Fcb->Specific.File.ExtentCount &&
7043 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7044 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7045 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
7046 AFSAcquireExcl( &Fcb->NPFcb->Resource,
7053 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7058 if( !NT_SUCCESS( stIoStatus.Status))
7061 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
7062 AFS_TRACE_LEVEL_ERROR,
7063 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7064 Fcb->ObjectInformation->FileId.Cell,
7065 Fcb->ObjectInformation->FileId.Volume,
7066 Fcb->ObjectInformation->FileId.Vnode,
7067 Fcb->ObjectInformation->FileId.Unique,
7069 stIoStatus.Information);
7071 ntStatus = stIoStatus.Status;
7077 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7083 __except( EXCEPTION_EXECUTE_HANDLER)
7085 ntStatus = GetExceptionCode();
7088 AFSReleaseResource( &Fcb->NPFcb->Resource);
7090 if( Fcb->OpenReferenceCount == 0)
7094 // Tear em down we'll not be needing them again
7097 AFSTearDownFcbExtents( Fcb,
7111 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7112 IN UNICODE_STRING *NewFileName)
7115 NTSTATUS ntStatus = STATUS_SUCCESS;
7116 WCHAR *pTmpBuffer = NULL;
7121 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7124 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7127 AFSExFreePool( DirectoryCB->NameInformation.FileName.Buffer);
7129 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7131 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7135 // OK, we need to allocate a new name buffer
7138 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7139 NewFileName->Length,
7140 AFS_NAME_BUFFER_NINE_TAG);
7142 if( pTmpBuffer == NULL)
7145 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7148 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7150 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7152 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7155 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7157 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7158 NewFileName->Buffer,
7159 NewFileName->Length);
7170 AFSReadCacheFile( IN void *ReadBuffer,
7171 IN LARGE_INTEGER *ReadOffset,
7172 IN ULONG RequestedDataLength,
7173 IN OUT PULONG BytesRead)
7176 NTSTATUS ntStatus = STATUS_SUCCESS;
7179 PIO_STACK_LOCATION pIoStackLocation = NULL;
7180 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7181 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7182 FILE_OBJECT *pCacheFileObject = NULL;
7187 pCacheFileObject = AFSReferenceCacheFileObject();
7189 if( pCacheFileObject == NULL)
7191 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7194 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7197 // Initialize the event
7200 KeInitializeEvent( &kEvent,
7201 SynchronizationEvent,
7205 // Allocate an irp for this request. This could also come from a
7206 // private pool, for instance.
7209 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7215 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7219 // Build the IRP's main body
7222 pIrp->UserBuffer = ReadBuffer;
7224 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7225 pIrp->RequestorMode = KernelMode;
7226 pIrp->Flags |= IRP_READ_OPERATION;
7229 // Set up the I/O stack location.
7232 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7233 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7234 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7235 pIoStackLocation->FileObject = pCacheFileObject;
7236 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7238 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7241 // Set the completion routine.
7244 IoSetCompletionRoutine( pIrp,
7252 // Send it to the FSD
7255 ntStatus = IoCallDriver( pTargetDeviceObject,
7258 if( NT_SUCCESS( ntStatus))
7265 ntStatus = KeWaitForSingleObject( &kEvent,
7271 if( NT_SUCCESS( ntStatus))
7274 ntStatus = pIrp->IoStatus.Status;
7276 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7282 if( pCacheFileObject != NULL)
7284 AFSReleaseCacheFileObject( pCacheFileObject);
7290 if( pIrp->MdlAddress != NULL)
7293 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7296 MmUnlockPages( pIrp->MdlAddress);
7299 IoFreeMdl( pIrp->MdlAddress);
7302 pIrp->MdlAddress = NULL;
7316 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7321 KEVENT *pEvent = (KEVENT *)Context;
7327 return STATUS_MORE_PROCESSING_REQUIRED;
7331 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7334 BOOLEAN bIsEmpty = FALSE;
7335 AFSDirectoryCB *pDirEntry = NULL;
7340 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7345 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7348 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7350 while( pDirEntry != NULL)
7353 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7354 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7362 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7367 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7374 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7375 IN AFSDirectoryCB *DirEntry)
7378 NTSTATUS ntStatus = STATUS_SUCCESS;
7383 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7386 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7387 AFS_TRACE_LEVEL_VERBOSE,
7388 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7390 &DirEntry->NameInformation.FileName);
7392 try_return( ntStatus);
7395 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7398 // Remove the entry from the parent tree
7401 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7402 AFS_TRACE_LEVEL_VERBOSE,
7403 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7405 &DirEntry->NameInformation.FileName);
7407 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7410 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7411 AFS_TRACE_LEVEL_VERBOSE,
7412 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7414 &DirEntry->NameInformation.FileName);
7416 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7419 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7423 // From the short name tree
7426 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7427 AFS_TRACE_LEVEL_VERBOSE,
7428 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7430 &DirEntry->NameInformation.FileName);
7432 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7435 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7438 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7439 AFS_TRACE_LEVEL_VERBOSE,
7440 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7442 &DirEntry->NameInformation.FileName);
7444 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7446 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7457 AFSGetAuthenticationId()
7460 LARGE_INTEGER liAuthId = {0,0};
7461 NTSTATUS ntStatus = STATUS_SUCCESS;
7462 PACCESS_TOKEN hToken = NULL;
7463 PTOKEN_STATISTICS pTokenInfo = NULL;
7464 BOOLEAN bCopyOnOpen = FALSE;
7465 BOOLEAN bEffectiveOnly = FALSE;
7466 BOOLEAN bPrimaryToken = FALSE;
7467 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7472 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7475 &stImpersonationLevel);
7480 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7485 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7486 AFS_TRACE_LEVEL_ERROR,
7487 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7489 try_return( ntStatus);
7492 bPrimaryToken = TRUE;
7495 ntStatus = SeQueryInformationToken( hToken,
7497 (PVOID *)&pTokenInfo);
7499 if( !NT_SUCCESS( ntStatus))
7502 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7503 AFS_TRACE_LEVEL_ERROR,
7504 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7506 try_return( ntStatus);
7509 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7510 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7512 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7513 AFS_TRACE_LEVEL_VERBOSE,
7514 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7525 PsDereferenceImpersonationToken( hToken);
7530 PsDereferencePrimaryToken( hToken);
7534 if( pTokenInfo != NULL)
7537 AFSExFreePool( pTokenInfo);
7545 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7549 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7551 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7554 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7556 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7559 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7561 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7564 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7566 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7569 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7571 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7578 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7581 BOOLEAN bIsValid = TRUE;
7583 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7585 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7587 while( pCurrentDirEntry != NULL)
7590 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7594 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7599 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7600 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7603 if( pDirEntry == NULL)
7610 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7613 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7616 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7618 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7620 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7629 AFSReferenceCacheFileObject()
7632 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7633 FILE_OBJECT *pCacheFileObject = NULL;
7635 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7638 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7640 if( pCacheFileObject != NULL)
7642 ObReferenceObject( pCacheFileObject);
7645 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7647 return pCacheFileObject;
7651 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7654 ASSERT( CacheFileObject != NULL);
7656 ObDereferenceObject( CacheFileObject);
7662 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7665 NTSTATUS ntStatus = STATUS_SUCCESS;
7666 AFSDeviceExt *pControlDevExt = NULL;
7667 ULONG ulTimeIncrement = 0;
7672 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7674 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7676 AFSServerName = LibraryInit->AFSServerName;
7678 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7681 // Callbacks in the framework
7684 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7686 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7688 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7690 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7692 AFSExFreePool = LibraryInit->AFSExFreePool;
7694 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7696 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7698 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7700 if( LibraryInit->AFSCacheBaseAddress != NULL)
7703 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7705 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7707 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7711 // Initialize some flush parameters
7714 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7716 ulTimeIncrement = KeQueryTimeIncrement();
7718 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7719 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7720 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7721 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7722 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7725 // Initialize the global root entry
7728 ntStatus = AFSInitVolume( NULL,
7729 &LibraryInit->GlobalRootFid,
7732 if( !NT_SUCCESS( ntStatus))
7735 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7736 AFS_TRACE_LEVEL_ERROR,
7737 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7740 try_return( ntStatus);
7743 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7746 if( !NT_SUCCESS( ntStatus))
7749 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7750 AFS_TRACE_LEVEL_ERROR,
7751 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7754 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7756 try_return( ntStatus);
7760 // Update the node type code to AFS_ROOT_ALL
7763 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7765 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7768 // Invalidate all known volumes since contact with the service and therefore
7769 // the file server was lost.
7772 AFSInvalidateAllVolumes();
7775 // Drop the locks acquired above
7778 AFSInitVolumeWorker( AFSGlobalRoot);
7780 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7782 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7796 NTSTATUS ntStatus = STATUS_SUCCESS;
7797 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7802 if( AFSGlobalDotDirEntry != NULL)
7805 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
7807 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7809 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7811 ExFreePool( AFSGlobalDotDirEntry);
7813 AFSGlobalDotDirEntry = NULL;
7816 if( AFSGlobalDotDotDirEntry != NULL)
7819 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
7821 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7823 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7825 ExFreePool( AFSGlobalDotDotDirEntry);
7827 AFSGlobalDotDotDirEntry = NULL;
7830 if( AFSSpecialShareNames != NULL)
7833 pDirNode = AFSSpecialShareNames;
7835 while( pDirNode != NULL)
7838 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7840 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
7842 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7844 ExFreePool( pDirNode->NonPaged);
7846 ExFreePool( pDirNode);
7848 pDirNode = pLastDirNode;
7851 AFSSpecialShareNames = NULL;
7859 AFSDefaultLogMsg( IN ULONG Subsystem,
7865 NTSTATUS ntStatus = STATUS_SUCCESS;
7867 char chDebugBuffer[ 256];
7872 va_start( va_args, Format);
7874 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7879 if( NT_SUCCESS( ntStatus))
7881 DbgPrint( chDebugBuffer);
7891 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7892 IN ULONG InputBufferLength,
7893 IN AFSStatusInfoCB *StatusInfo,
7894 OUT ULONG *ReturnLength)
7897 NTSTATUS ntStatus = STATUS_SUCCESS;
7898 AFSFcb *pFcb = NULL;
7899 AFSVolumeCB *pVolumeCB = NULL;
7900 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7901 AFSObjectInfoCB *pObjectInfo = NULL;
7902 ULONGLONG ullIndex = 0;
7903 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7904 AFSNameArrayHdr *pNameArray = NULL;
7905 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7912 // If we are given a FID then look up the entry by that, otherwise
7916 if( GetStatusInfo->FileID.Cell != 0 &&
7917 GetStatusInfo->FileID.Volume != 0 &&
7918 GetStatusInfo->FileID.Vnode != 0 &&
7919 GetStatusInfo->FileID.Unique != 0)
7922 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7925 // Locate the volume node
7928 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7930 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7932 (AFSBTreeEntry **)&pVolumeCB);
7934 if( pVolumeCB != NULL)
7937 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7939 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7940 AFS_TRACE_LEVEL_VERBOSE,
7941 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7946 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7948 if( !NT_SUCCESS( ntStatus) ||
7951 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7954 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
7957 pObjectInfo = &pVolumeCB->ObjectInformation;
7959 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7961 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7966 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
7969 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7971 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7972 AFS_TRACE_LEVEL_VERBOSE,
7973 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7977 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
7979 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
7981 (AFSBTreeEntry **)&pObjectInfo);
7983 if( pObjectInfo != NULL)
7987 // Reference the node so it won't be torn down
7990 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7992 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7993 AFS_TRACE_LEVEL_VERBOSE,
7994 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
7999 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8001 if( !NT_SUCCESS( ntStatus) ||
8002 pObjectInfo == NULL)
8004 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8011 if( GetStatusInfo->FileNameLength == 0 ||
8012 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8014 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8017 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8018 uniFullPathName.MaximumLength = uniFullPathName.Length;
8020 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8023 // This name should begin with the \afs server so parse it off and check it
8026 FsRtlDissectName( uniFullPathName,
8030 if( RtlCompareUnicodeString( &uniComponentName,
8034 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8035 AFS_TRACE_LEVEL_ERROR,
8036 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8039 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8042 uniFullPathName = uniRemainingPath;
8044 uniParsedName = uniFullPathName;
8050 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8053 if( pNameArray == NULL)
8055 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8058 pVolumeCB = AFSGlobalRoot;
8060 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8063 // Increment the ref count on the volume and dir entry for correct processing below
8066 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
8068 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8069 AFS_TRACE_LEVEL_VERBOSE,
8070 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
8074 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
8076 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8077 AFS_TRACE_LEVEL_VERBOSE,
8078 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8079 &pParentDirEntry->NameInformation.FileName,
8084 ntStatus = AFSLocateNameEntry( NULL,
8089 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8090 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8096 if( !NT_SUCCESS( ntStatus))
8100 // The volume lock was released on failure above
8101 // Except for STATUS_OBJECT_NAME_NOT_FOUND
8104 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
8107 if( pVolumeCB != NULL)
8110 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8112 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8113 AFS_TRACE_LEVEL_VERBOSE,
8114 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
8119 if( pDirectoryEntry != NULL)
8122 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
8124 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8125 AFS_TRACE_LEVEL_VERBOSE,
8126 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8127 &pDirectoryEntry->NameInformation.FileName,
8135 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
8137 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8138 AFS_TRACE_LEVEL_VERBOSE,
8139 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8140 &pParentDirEntry->NameInformation.FileName,
8149 try_return( ntStatus);
8153 // Remove the reference made above
8156 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
8158 pObjectInfo = pDirectoryEntry->ObjectInformation;
8160 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
8162 if( pVolumeCB != NULL)
8165 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
8167 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8168 AFS_TRACE_LEVEL_VERBOSE,
8169 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
8171 pVolumeCB->VolumeReferenceCount);
8176 // At this point we have an object info block, return the information
8179 StatusInfo->FileId = pObjectInfo->FileId;
8181 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8183 StatusInfo->Expiration = pObjectInfo->Expiration;
8185 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8187 StatusInfo->FileType = pObjectInfo->FileType;
8189 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8191 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8193 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8195 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8197 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8199 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8201 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8203 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8205 StatusInfo->EaSize = pObjectInfo->EaSize;
8207 StatusInfo->Links = pObjectInfo->Links;
8210 // Return the information length
8213 *ReturnLength = sizeof( AFSStatusInfoCB);
8217 if( pObjectInfo != NULL)
8220 lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
8223 if( pNameArray != NULL)
8226 AFSFreeNameArray( pNameArray);
8234 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8235 IN UNICODE_STRING *ComponentName)
8238 NTSTATUS ntStatus = STATUS_SUCCESS;
8239 AFSDirectoryCB *pDirEntry = NULL;
8247 // Search for the entry in the parent
8250 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8251 AFS_TRACE_LEVEL_VERBOSE_2,
8252 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8255 ulCRC = AFSGenerateCRC( ComponentName,
8258 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8261 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8265 if( pDirEntry == NULL)
8269 // Missed so perform a case insensitive lookup
8272 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8273 AFS_TRACE_LEVEL_VERBOSE_2,
8274 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8277 ulCRC = AFSGenerateCRC( ComponentName,
8280 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8284 if( pDirEntry == NULL)
8288 // OK, if this component is a valid short name then try
8289 // a lookup in the short name tree
8292 if( RtlIsNameLegalDOS8Dot3( ComponentName,
8297 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8298 AFS_TRACE_LEVEL_VERBOSE_2,
8299 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8302 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8309 if( pDirEntry != NULL)
8311 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
8314 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8316 if( pDirEntry == NULL)
8319 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8320 AFS_TRACE_LEVEL_VERBOSE_2,
8321 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
8324 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8328 // We have the symlink object but previously failed to process it so return access
8332 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8333 AFS_TRACE_LEVEL_VERBOSE_2,
8334 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8337 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8339 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
8350 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8351 OUT UNICODE_STRING *ComponentName)
8354 NTSTATUS ntStatus = STATUS_SUCCESS;
8355 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8357 uniFullPathName = *FullPathName;
8362 FsRtlDissectName( uniFullPathName,
8366 if( uniRemainingPath.Length == 0)
8371 uniFullPathName = uniRemainingPath;
8374 if( uniComponentName.Length > 0)
8376 *ComponentName = uniComponentName;
8383 AFSDumpTraceFiles_Default()
8389 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8392 BOOLEAN bIsValidName = TRUE;
8398 while( usIndex < FileName->Length/sizeof( WCHAR))
8401 if( FileName->Buffer[ usIndex] == L':' ||
8402 FileName->Buffer[ usIndex] == L'*' ||
8403 FileName->Buffer[ usIndex] == L'?' ||
8404 FileName->Buffer[ usIndex] == L'"' ||
8405 FileName->Buffer[ usIndex] == L'<' ||
8406 FileName->Buffer[ usIndex] == L'>')
8408 bIsValidName = FALSE;
8416 return bIsValidName;
8420 AFSCreateDefaultSecurityDescriptor()
8423 NTSTATUS ntStatus = STATUS_SUCCESS;
8425 ULONG ulSACLSize = 0;
8426 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8427 ULONG ulACESize = 0;
8428 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8429 ULONG ulSDLength = 0;
8430 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8431 PSID pWorldSID = NULL;
8432 ULONG *pulSubAuthority = NULL;
8433 ULONG ulWorldSIDLEngth = 0;
8438 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8440 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8442 AFS_GENERIC_MEMORY_29_TAG);
8444 if( pWorldSID == NULL)
8446 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8447 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8450 RtlZeroMemory( pWorldSID,
8453 RtlInitializeSid( pWorldSID,
8454 &SeWorldSidAuthority,
8457 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8458 *pulSubAuthority = SECURITY_WORLD_RID;
8460 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8463 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8468 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8470 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8472 AFS_GENERIC_MEMORY_29_TAG);
8477 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8479 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8482 RtlZeroMemory( pACE,
8485 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8486 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8487 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8488 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8490 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8492 SeExports->SeLowMandatorySid);
8494 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8495 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8497 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8499 AFS_GENERIC_MEMORY_29_TAG);
8504 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8506 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8509 ntStatus = RtlCreateAcl( pSACL,
8513 if( !NT_SUCCESS( ntStatus))
8516 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8519 try_return( ntStatus);
8522 ntStatus = RtlAddAce( pSACL,
8526 pACE->Header.AceSize);
8528 if( !NT_SUCCESS( ntStatus))
8531 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8534 try_return( ntStatus);
8538 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8539 sizeof( SECURITY_DESCRIPTOR),
8540 AFS_GENERIC_MEMORY_27_TAG);
8542 if( pSecurityDescr == NULL)
8545 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8547 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8550 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8551 SECURITY_DESCRIPTOR_REVISION);
8553 if( !NT_SUCCESS( ntStatus))
8556 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8559 try_return( ntStatus);
8562 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8564 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8569 if( !NT_SUCCESS( ntStatus))
8572 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8575 try_return( ntStatus);
8580 // Add in the group and owner to the SD
8583 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8585 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8589 if( !NT_SUCCESS( ntStatus))
8592 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8595 try_return( ntStatus);
8599 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8603 if( !NT_SUCCESS( ntStatus))
8606 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8609 try_return( ntStatus);
8612 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8615 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8617 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8620 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8622 AFS_GENERIC_MEMORY_27_TAG);
8624 if( pRelativeSecurityDescr == NULL)
8627 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8629 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8632 ulSDLength = PAGE_SIZE;
8634 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8635 pRelativeSecurityDescr,
8638 if( !NT_SUCCESS( ntStatus))
8641 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8644 try_return( ntStatus);
8647 AFSDefaultSD = pRelativeSecurityDescr;
8651 if( !NT_SUCCESS( ntStatus))
8654 if( pRelativeSecurityDescr != NULL)
8656 ExFreePool( pRelativeSecurityDescr);
8660 if( pSecurityDescr != NULL)
8662 ExFreePool( pSecurityDescr);
8675 if( pWorldSID != NULL)
8677 ExFreePool( pWorldSID);
8685 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8686 OUT UNICODE_STRING *ParentPath)
8691 *ParentPath = *FullFileName;
8694 // If the final character is a \, jump over it
8697 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8699 ParentPath->Length -= sizeof( WCHAR);
8702 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8704 ParentPath->Length -= sizeof( WCHAR);
8708 // And the separator
8711 ParentPath->Length -= sizeof( WCHAR);
8717 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8718 IN AFSObjectInfoCB *ObjectInfo,
8719 IN BOOLEAN WriteAccess,
8720 OUT GUID *AuthGroup)
8723 NTSTATUS ntStatus = STATUS_SUCCESS;
8724 GUID stAuthGroup, stZeroAuthGroup;
8725 BOOLEAN bFoundAuthGroup = FALSE;
8726 AFSCcb *pCcb = NULL;
8732 RtlZeroMemory( &stAuthGroup,
8735 RtlZeroMemory( &stZeroAuthGroup,
8741 if( ObjectInfo != NULL &&
8742 ObjectInfo->Fcb != NULL)
8744 pFcb = ObjectInfo->Fcb;
8751 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8754 pCcb = Fcb->CcbListHead;
8756 while( pCcb != NULL)
8760 pCcb->GrantedAccess & FILE_WRITE_DATA)
8762 RtlCopyMemory( &stAuthGroup,
8766 bFoundAuthGroup = TRUE;
8770 else if( pCcb->GrantedAccess & FILE_READ_DATA)
8773 // At least get the read-only access
8776 RtlCopyMemory( &stAuthGroup,
8780 bFoundAuthGroup = TRUE;
8783 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
8786 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
8789 if( !bFoundAuthGroup)
8792 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
8793 (ULONGLONG)PsGetCurrentThreadId(),
8796 if( RtlCompareMemory( &stZeroAuthGroup,
8798 sizeof( GUID)) == sizeof( GUID))
8801 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
8803 try_return( ntStatus = STATUS_ACCESS_DENIED);
8807 RtlCopyMemory( AuthGroup,
8820 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
8821 IN ULONG InvalidateReason)
8824 NTSTATUS ntStatus = STATUS_SUCCESS;
8825 IO_STATUS_BLOCK stIoStatus;
8828 ULONG ulProcessCount = 0;
8834 switch( InvalidateReason)
8837 case AFS_INVALIDATE_DELETED:
8840 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8841 ObjectInfo->Fcb != NULL)
8846 // Clear out the extents
8847 // And get rid of them (note this involves waiting
8848 // for any writes or reads to the cache to complete)
8851 (VOID) AFSTearDownFcbExtents( ObjectInfo->Fcb,
8858 case AFS_INVALIDATE_DATA_VERSION:
8861 LARGE_INTEGER liCurrentOffset = {0,0};
8862 LARGE_INTEGER liFlushLength = {0,0};
8863 ULONG ulFlushLength = 0;
8864 BOOLEAN bLocked = FALSE;
8865 BOOLEAN bExtentsLocked = FALSE;
8866 BOOLEAN bCleanExtents = FALSE;
8868 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8869 ObjectInfo->Fcb != NULL)
8872 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
8877 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
8878 AFS_TRACE_LEVEL_VERBOSE,
8879 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %08lX SHARED %08lX\n",
8880 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
8881 PsGetCurrentThread());
8883 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
8886 bExtentsLocked = TRUE;
8889 // There are several possibilities here:
8891 // 0. If there are no extents or all of the extents are dirty, do nothing.
8893 // 1. There could be nothing dirty and an open reference count of zero
8894 // in which case we can just tear down all of the extents without
8895 // holding any resources.
8897 // 2. There could be nothing dirty and a non-zero open reference count
8898 // in which case we can issue a CcPurge against the entire file
8899 // while holding just the Fcb Resource.
8901 // 3. There can be dirty extents in which case we need to identify
8902 // the non-dirty ranges and then perform a CcPurge on just the
8903 // non-dirty ranges while holding just the Fcb Resource.
8906 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
8909 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
8912 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
8915 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
8917 bExtentsLocked = FALSE;
8919 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
8923 (VOID) AFSTearDownFcbExtents( ObjectInfo->Fcb,
8932 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
8934 bExtentsLocked = FALSE;
8936 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
8941 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
8946 bCleanExtents = TRUE;
8949 __except( EXCEPTION_EXECUTE_HANDLER)
8952 ntStatus = GetExceptionCode();
8956 "EXCEPTION - AFSPerformObjectInvalidate Status %08lX\n",
8965 // Must build a list of non-dirty ranges from the beginning of the file
8966 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
8967 // ranges. In all but the most extreme random data write scenario there will
8968 // be significantly fewer.
8970 // For each range we need offset and size.
8973 AFSByteRange * ByteRangeList = NULL;
8974 ULONG ulByteRangeCount = 0;
8976 BOOLEAN bPurgeOnClose = FALSE;
8981 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
8984 if ( ByteRangeList != NULL ||
8985 ulByteRangeCount == 0)
8988 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
8990 bExtentsLocked = FALSE;
8992 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
8999 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9001 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9002 &ByteRangeList[ulIndex].FileOffset,
9007 bPurgeOnClose = TRUE;
9012 bCleanExtents = TRUE;
9015 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9017 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9019 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9026 // We couldn't allocate the memory to build the purge list
9027 // so just walk the extent list while holding the ExtentsList Resource.
9028 // This could deadlock but we do not have much choice.
9031 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9035 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9039 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9041 while( ulProcessCount < ulCount)
9043 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9045 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9047 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9048 &pEntry->FileOffset,
9053 bPurgeOnClose = TRUE;
9058 bCleanExtents = TRUE;
9062 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9065 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9067 while( liFlushLength.QuadPart > 0)
9070 if( liFlushLength.QuadPart > 512 * 1024000)
9072 ulFlushLength = 512 * 1024000;
9076 ulFlushLength = liFlushLength.LowPart;
9079 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9085 bPurgeOnClose = TRUE;
9090 bCleanExtents = TRUE;
9093 liFlushLength.QuadPart -= ulFlushLength;
9097 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9105 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9111 bPurgeOnClose = TRUE;
9116 bCleanExtents = TRUE;
9123 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9127 __except( EXCEPTION_EXECUTE_HANDLER)
9130 ntStatus = GetExceptionCode();
9134 "EXCEPTION - AFSPerformObjectInvalidate Status %08lX\n",
9140 if ( bExtentsLocked)
9143 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9149 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9155 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9164 if( ObjectInfo != NULL)
9166 InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);