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;
651 // Initialize the global . entry
654 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
657 if( pObjectInfoCB == NULL)
660 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
661 AFS_TRACE_LEVEL_ERROR,
662 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
665 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
668 InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
670 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
671 AFS_TRACE_LEVEL_VERBOSE,
672 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
674 pObjectInfoCB->ObjectReferenceCount);
676 ntStatus = STATUS_SUCCESS;
678 ulEntryLength = sizeof( AFSDirectoryCB) +
681 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
685 if( pDirNode == NULL)
688 AFSDeleteObjectInfo( pObjectInfoCB);
690 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
691 AFS_TRACE_LEVEL_ERROR,
692 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
694 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
697 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
698 sizeof( AFSNonPagedDirectoryCB),
699 AFS_DIR_ENTRY_NP_TAG);
701 if( pNonPagedDirEntry == NULL)
704 ExFreePool( pDirNode);
706 AFSDeleteObjectInfo( pObjectInfoCB);
708 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
709 AFS_TRACE_LEVEL_ERROR,
710 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
712 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
715 RtlZeroMemory( pDirNode,
718 RtlZeroMemory( pNonPagedDirEntry,
719 sizeof( AFSNonPagedDirectoryCB));
721 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
723 pDirNode->NonPaged = pNonPagedDirEntry;
725 pDirNode->ObjectInformation = pObjectInfoCB;
731 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
733 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
736 // Setup the names in the entry
739 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
741 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
743 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
745 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
748 // Populate the rest of the data
751 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
753 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
755 AFSGlobalDotDirEntry = pDirNode;
761 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
764 if( pObjectInfoCB == NULL)
767 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
768 AFS_TRACE_LEVEL_ERROR,
769 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
772 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
775 InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
777 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
778 AFS_TRACE_LEVEL_VERBOSE,
779 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
781 pObjectInfoCB->ObjectReferenceCount);
783 ntStatus = STATUS_SUCCESS;
785 ulEntryLength = sizeof( AFSDirectoryCB) +
786 ( 2 * sizeof( WCHAR));
788 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
792 if( pDirNode == NULL)
795 AFSDeleteObjectInfo( pObjectInfoCB);
797 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
800 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
801 sizeof( AFSNonPagedDirectoryCB),
802 AFS_DIR_ENTRY_NP_TAG);
804 if( pNonPagedDirEntry == NULL)
807 ExFreePool( pDirNode);
809 AFSDeleteObjectInfo( pObjectInfoCB);
811 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
814 RtlZeroMemory( pDirNode,
817 RtlZeroMemory( pNonPagedDirEntry,
818 sizeof( AFSNonPagedDirectoryCB));
820 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
822 pDirNode->NonPaged = pNonPagedDirEntry;
824 pDirNode->ObjectInformation = pObjectInfoCB;
830 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
832 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
835 // Setup the names in the entry
838 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
840 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
842 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
844 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
846 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
849 // Populate the rest of the data
852 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
854 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
856 AFSGlobalDotDotDirEntry = pDirNode;
860 if( !NT_SUCCESS( ntStatus))
863 if( AFSGlobalDotDirEntry != NULL)
866 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
868 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
870 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
872 ExFreePool( AFSGlobalDotDirEntry);
874 AFSGlobalDotDirEntry = NULL;
877 if( AFSGlobalDotDotDirEntry != NULL)
880 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
882 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
884 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
886 ExFreePool( AFSGlobalDotDotDirEntry);
888 AFSGlobalDotDotDirEntry = NULL;
897 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
898 IN PUNICODE_STRING FileName,
899 IN PUNICODE_STRING TargetName,
900 IN AFSDirEnumEntry *DirEnumEntry,
904 AFSDirectoryCB *pDirNode = NULL;
905 NTSTATUS ntStatus = STATUS_SUCCESS;
906 ULONG ulEntryLength = 0;
907 AFSDirEnumEntry *pDirEnumCB = NULL;
908 AFSFileID stTargetFileID;
910 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
911 AFSObjectInfoCB *pObjectInfoCB = NULL;
912 BOOLEAN bAllocatedObjectCB = FALSE;
913 ULONGLONG ullIndex = 0;
914 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
919 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
920 AFS_TRACE_LEVEL_VERBOSE,
921 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
923 ParentObjectInfo->FileId.Cell,
924 ParentObjectInfo->FileId.Volume,
925 ParentObjectInfo->FileId.Vnode,
926 ParentObjectInfo->FileId.Unique);
929 // First thing is to locate/create our object information block
933 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
936 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
938 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
940 (AFSBTreeEntry **)&pObjectInfoCB);
942 if( !NT_SUCCESS( ntStatus) ||
943 pObjectInfoCB == NULL)
947 // Allocate our object info cb
950 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
953 if( pObjectInfoCB == NULL)
956 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
958 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
961 bAllocatedObjectCB = TRUE;
963 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
964 AFS_TRACE_LEVEL_VERBOSE,
965 "AFSInitDirEntry initialized object %08lX Parent Object %08lX for %wZ\n",
971 InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
973 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
974 AFS_TRACE_LEVEL_VERBOSE,
975 "AFSInitDirEntry Increment count on object %08lX Cnt %d\n",
977 pObjectInfoCB->ObjectReferenceCount);
979 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
981 ntStatus = STATUS_SUCCESS;
983 ulEntryLength = sizeof( AFSDirectoryCB) +
986 if( TargetName != NULL)
989 ulEntryLength += TargetName->Length;
992 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
996 if( pDirNode == NULL)
999 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1002 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1003 sizeof( AFSNonPagedDirectoryCB),
1004 AFS_DIR_ENTRY_NP_TAG);
1006 if( pNonPagedDirEntry == NULL)
1009 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1012 RtlZeroMemory( pDirNode,
1015 RtlZeroMemory( pNonPagedDirEntry,
1016 sizeof( AFSNonPagedDirectoryCB));
1018 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1020 pDirNode->NonPaged = pNonPagedDirEntry;
1022 pDirNode->ObjectInformation = pObjectInfoCB;
1025 // Set valid entry and NOT_IN_PARENT flag
1028 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1030 pDirNode->FileIndex = FileIndex;
1033 // Setup the names in the entry
1036 if( FileName->Length > 0)
1039 pDirNode->NameInformation.FileName.Length = FileName->Length;
1041 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1043 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1045 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1047 pDirNode->NameInformation.FileName.Length);
1050 // Create a CRC for the file
1053 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1056 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1060 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1061 AFS_TRACE_LEVEL_VERBOSE,
1062 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1065 ParentObjectInfo->FileId.Cell,
1066 ParentObjectInfo->FileId.Volume,
1067 ParentObjectInfo->FileId.Vnode,
1068 ParentObjectInfo->FileId.Unique);
1070 if( TargetName != NULL &&
1071 TargetName->Length > 0)
1074 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1076 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1078 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1079 sizeof( AFSDirectoryCB) +
1080 pDirNode->NameInformation.FileName.Length);
1082 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1084 pDirNode->NameInformation.TargetName.Length);
1088 // If we allocated the object information cb then update the information
1091 if( bAllocatedObjectCB)
1095 // Populate the rest of the data
1098 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1100 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1102 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1104 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1106 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1108 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1110 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1112 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1114 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1116 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1118 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1121 pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1124 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1125 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1128 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1131 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1134 // Object specific information
1137 pObjectInfoCB->Links = DirEnumEntry->Links;
1139 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1141 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1144 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1145 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1149 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1150 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1151 pObjectInfoCB->TargetFileId.Unique == 0 &&
1152 pDirNode->NameInformation.TargetName.Length == 0)
1156 // This will ensure we perform a validation on the node
1159 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1162 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1165 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1171 if( !NT_SUCCESS( ntStatus))
1174 if( pNonPagedDirEntry != NULL)
1177 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1179 AFSExFreePool( pNonPagedDirEntry);
1182 if( pDirNode != NULL)
1185 AFSExFreePool( pDirNode);
1191 // Dereference our object info block if we have one
1194 if( pObjectInfoCB != NULL)
1197 InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
1199 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1200 AFS_TRACE_LEVEL_VERBOSE,
1201 "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
1203 pObjectInfoCB->ObjectReferenceCount);
1205 if( bAllocatedObjectCB)
1208 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1210 AFSDeleteObjectInfo( pObjectInfoCB);
1220 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1221 IN BOOLEAN DirectoryEntry)
1224 BOOLEAN bReturn = TRUE;
1225 ACCESS_MASK stAccessMask = 0;
1228 // Get rid of anything we don't know about
1231 DesiredAccess = (DesiredAccess &
1237 ACCESS_SYSTEM_SECURITY |
1241 FILE_READ_ATTRIBUTES |
1242 FILE_WRITE_ATTRIBUTES |
1243 FILE_LIST_DIRECTORY |
1249 // Our 'read only' access mask. These are the accesses we will
1250 // allow for a read only file
1253 stAccessMask = DELETE |
1258 ACCESS_SYSTEM_SECURITY |
1262 FILE_READ_ATTRIBUTES |
1263 FILE_WRITE_ATTRIBUTES |
1265 FILE_LIST_DIRECTORY |
1269 // For a directory, add in the directory specific accesses
1275 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1280 if( FlagOn( DesiredAccess, ~stAccessMask))
1284 // A write access is set ...
1294 AFSEvaluateNode( IN GUID *AuthGroup,
1295 IN AFSDirectoryCB *DirEntry)
1298 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1299 NTSTATUS ntStatus = STATUS_SUCCESS;
1300 AFSDirEnumEntry *pDirEntry = NULL;
1301 UNICODE_STRING uniTargetName;
1306 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1311 if( !NT_SUCCESS( ntStatus))
1314 try_return( ntStatus);
1317 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1319 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1321 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1323 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1325 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1327 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1329 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1331 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1333 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1335 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1337 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1339 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1342 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1345 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1346 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1349 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1352 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1354 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1357 // If we have a target name then see if it needs updating ...
1360 if( pDirEntry->TargetNameLength > 0)
1364 // Update the target name information if needed
1367 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1369 uniTargetName.MaximumLength = uniTargetName.Length;
1371 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1373 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1376 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1377 RtlCompareUnicodeString( &uniTargetName,
1378 &DirEntry->NameInformation.TargetName,
1383 // Update the target name
1386 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1388 uniTargetName.Buffer,
1389 uniTargetName.Length);
1391 if( !NT_SUCCESS( ntStatus))
1394 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1396 try_return( ntStatus);
1400 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1405 if( pDirEntry != NULL)
1408 AFSExFreePool( pDirEntry);
1416 AFSValidateSymLink( IN GUID *AuthGroup,
1417 IN AFSDirectoryCB *DirEntry)
1420 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1421 NTSTATUS ntStatus = STATUS_SUCCESS;
1422 AFSDirEnumEntry *pDirEntry = NULL;
1423 UNICODE_STRING uniTargetName;
1428 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1433 if( !NT_SUCCESS( ntStatus))
1436 try_return( ntStatus);
1439 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1440 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1443 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1446 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1448 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1450 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1453 // Update the target name information if needed
1456 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1458 uniTargetName.MaximumLength = uniTargetName.Length;
1460 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1462 if( uniTargetName.Length > 0)
1465 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1468 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1469 RtlCompareUnicodeString( &uniTargetName,
1470 &DirEntry->NameInformation.TargetName,
1475 // Update the target name
1478 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1480 uniTargetName.Buffer,
1481 uniTargetName.Length);
1483 if( !NT_SUCCESS( ntStatus))
1486 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1488 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1492 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1496 // If the FileType is the same then nothing to do since it IS
1500 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1503 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1505 try_return( ntStatus = STATUS_SUCCESS);
1508 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1510 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1512 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1514 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1516 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1518 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1520 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1522 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1524 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1527 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1530 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1531 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1534 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1537 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1539 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1543 if( pDirEntry != NULL)
1546 AFSExFreePool( pDirEntry);
1554 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1557 NTSTATUS ntStatus = STATUS_SUCCESS;
1558 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1559 AFSVolumeCB *pVolumeCB = NULL;
1560 AFSFcb *pTargetDcb = NULL;
1561 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1562 AFSDirectoryCB *pCurrentDirEntry = NULL;
1563 BOOLEAN bIsChild = FALSE;
1564 ULONGLONG ullIndex = 0;
1565 AFSObjectInfoCB *pObjectInfo = NULL;
1566 IO_STATUS_BLOCK stIoStatus;
1573 // Need to locate the Fcb for the directory to purge
1576 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1577 AFS_TRACE_LEVEL_VERBOSE,
1578 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1579 &pDevExt->Specific.RDR.VolumeTreeLock,
1580 PsGetCurrentThread());
1583 // Starve any exclusive waiters on this paticular call
1586 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1589 // Locate the volume node
1592 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1594 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1596 (AFSBTreeEntry **)&pVolumeCB);
1598 if( pVolumeCB != NULL)
1601 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1603 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1604 AFS_TRACE_LEVEL_VERBOSE,
1605 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1607 pVolumeCB->VolumeReferenceCount);
1610 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1612 if( !NT_SUCCESS( ntStatus) ||
1615 try_return( ntStatus = STATUS_SUCCESS);
1619 // If this is a whole volume invalidation then go do it now
1622 if( InvalidateCB->WholeVolume ||
1623 AFSIsVolumeFID( &InvalidateCB->FileID))
1626 ntStatus = AFSInvalidateVolume( pVolumeCB,
1627 InvalidateCB->Reason);
1629 AFSFsRtlNotifyFullReportChange( &pVolumeCB->ObjectInformation,
1631 FILE_NOTIFY_CHANGE_FILE_NAME |
1632 FILE_NOTIFY_CHANGE_DIR_NAME |
1633 FILE_NOTIFY_CHANGE_NAME |
1634 FILE_NOTIFY_CHANGE_ATTRIBUTES |
1635 FILE_NOTIFY_CHANGE_SIZE,
1636 FILE_ACTION_MODIFIED);
1638 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1640 try_return( ntStatus);
1643 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1646 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1648 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1649 AFS_TRACE_LEVEL_VERBOSE,
1650 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
1652 pVolumeCB->VolumeReferenceCount);
1654 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
1656 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
1658 (AFSBTreeEntry **)&pObjectInfo);
1660 if( pObjectInfo != NULL)
1664 // Reference the node so it won't be torn down
1667 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
1669 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1670 AFS_TRACE_LEVEL_VERBOSE,
1671 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
1673 pObjectInfo->ObjectReferenceCount);
1676 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1678 if( !NT_SUCCESS( ntStatus) ||
1679 pObjectInfo == NULL)
1681 try_return( ntStatus = STATUS_SUCCESS);
1684 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
1685 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK ||
1686 pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1689 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1690 AFS_TRACE_LEVEL_VERBOSE,
1691 "AFSInvalidateCache Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1692 pObjectInfo->FileType,
1693 pObjectInfo->FileId.Cell,
1694 pObjectInfo->FileId.Volume,
1695 pObjectInfo->FileId.Vnode,
1696 pObjectInfo->FileId.Unique,
1697 InvalidateCB->Reason);
1700 // We only act on the mount point itself, not the target. If the
1701 // node has been deleted then mark it as such otherwise indicate
1702 // it requires verification
1705 if( InvalidateCB->Reason == AFS_INVALIDATE_DELETED)
1707 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1712 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED)
1715 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1717 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1720 pObjectInfo->Expiration.QuadPart = 0;
1722 pObjectInfo->TargetFileId.Vnode = 0;
1724 pObjectInfo->TargetFileId.Unique = 0;
1726 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1727 AFS_TRACE_LEVEL_VERBOSE,
1728 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1729 pObjectInfo->FileId.Cell,
1730 pObjectInfo->FileId.Volume,
1731 pObjectInfo->FileId.Vnode,
1732 pObjectInfo->FileId.Unique);
1734 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1737 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1739 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1741 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1744 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION ||
1745 InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED)
1747 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1751 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1754 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1756 FILE_NOTIFY_CHANGE_FILE_NAME |
1757 FILE_NOTIFY_CHANGE_ATTRIBUTES,
1758 FILE_ACTION_MODIFIED);
1760 try_return( ntStatus);
1764 // Depending on the reason for invalidation then perform work on the node
1767 switch( InvalidateCB->Reason)
1770 case AFS_INVALIDATE_DELETED:
1774 // Mark this node as invalid
1777 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
1779 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1780 AFS_TRACE_LEVEL_VERBOSE,
1781 "AFSInvalidateCache Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1782 pObjectInfo->FileId.Cell,
1783 pObjectInfo->FileId.Volume,
1784 pObjectInfo->FileId.Vnode,
1785 pObjectInfo->FileId.Unique);
1787 if( pObjectInfo->ParentObjectInformation != NULL)
1790 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1791 AFS_TRACE_LEVEL_VERBOSE,
1792 "AFSInvalidateCache Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1793 pObjectInfo->ParentObjectInformation->FileId.Cell,
1794 pObjectInfo->ParentObjectInformation->FileId.Volume,
1795 pObjectInfo->ParentObjectInformation->FileId.Vnode,
1796 pObjectInfo->ParentObjectInformation->FileId.Unique);
1798 SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1799 pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1800 pObjectInfo->ParentObjectInformation->Expiration.QuadPart = 0;
1803 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1805 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1809 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1812 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1815 FILE_ACTION_REMOVED);
1817 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
1818 pObjectInfo->Fcb != NULL)
1823 // Clear out the extents
1824 // And get rid of them (note this involves waiting
1825 // for any writes or reads to the cache to complete)
1828 (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb,
1835 case AFS_INVALIDATE_FLUSHED:
1838 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
1839 pObjectInfo->Fcb != NULL)
1842 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1843 AFS_TRACE_LEVEL_VERBOSE,
1844 "AFSInvalidateCache Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1845 pObjectInfo->FileId.Cell,
1846 pObjectInfo->FileId.Volume,
1847 pObjectInfo->FileId.Vnode,
1848 pObjectInfo->FileId.Unique);
1850 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
1856 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1861 if( !NT_SUCCESS( stIoStatus.Status))
1864 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1865 AFS_TRACE_LEVEL_ERROR,
1866 "AFSInvalidateCache CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1867 pObjectInfo->FileId.Cell,
1868 pObjectInfo->FileId.Volume,
1869 pObjectInfo->FileId.Vnode,
1870 pObjectInfo->FileId.Unique,
1872 stIoStatus.Information);
1874 ntStatus = stIoStatus.Status;
1877 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1882 __except( EXCEPTION_EXECUTE_HANDLER)
1885 ntStatus = GetExceptionCode();
1888 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
1891 // Clear out the extents
1892 // Get rid of them (note this involves waiting
1893 // for any writes or reads to the cache to complete)
1896 (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb,
1900 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1903 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
1906 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1907 AFS_TRACE_LEVEL_VERBOSE,
1908 "AFSInvalidateCache Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1909 pObjectInfo->FileId.Cell,
1910 pObjectInfo->FileId.Volume,
1911 pObjectInfo->FileId.Vnode,
1912 pObjectInfo->FileId.Unique);
1914 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1917 // Fall through to the default processing
1923 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1925 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1929 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1932 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1934 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1937 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1939 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1943 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1946 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1949 FILE_ACTION_MODIFIED);
1952 // Indicate this node requires re-evaluation for the remaining reasons
1955 pObjectInfo->Expiration.QuadPart = 0;
1957 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1958 AFS_TRACE_LEVEL_VERBOSE,
1959 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1960 pObjectInfo->FileId.Cell,
1961 pObjectInfo->FileId.Volume,
1962 pObjectInfo->FileId.Vnode,
1963 pObjectInfo->FileId.Unique);
1965 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1973 if( pObjectInfo != NULL)
1976 InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
1978 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1979 AFS_TRACE_LEVEL_VERBOSE,
1980 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
1982 pObjectInfo->ObjectReferenceCount);
1990 AFSIsChildOfParent( IN AFSFcb *Dcb,
1994 BOOLEAN bIsChild = FALSE;
1995 AFSFcb *pCurrentFcb = Fcb;
1997 while( pCurrentFcb != NULL)
2000 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2008 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2016 AFSCreateHighIndex( IN AFSFileID *FileID)
2019 ULONGLONG ullIndex = 0;
2021 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2028 AFSCreateLowIndex( IN AFSFileID *FileID)
2031 ULONGLONG ullIndex = 0;
2033 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2039 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2040 IN ACCESS_MASK GrantedAccess,
2041 IN BOOLEAN DirectoryEntry)
2044 BOOLEAN bAccessGranted = TRUE;
2047 // Check if we are asking for read/write and granted only read only
2048 // NOTE: There will be more checks here
2051 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2053 AFSCheckForReadOnlyAccess( GrantedAccess,
2057 bAccessGranted = FALSE;
2060 return bAccessGranted;
2064 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2067 NTSTATUS ntStatus = STATUS_SUCCESS;
2068 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2074 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2076 if( AFSGlobalRoot == NULL)
2083 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2086 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2093 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2100 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2101 IN UNICODE_STRING *SubstituteName,
2102 IN ULONG StringIndex)
2105 NTSTATUS ntStatus = STATUS_SUCCESS;
2106 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2107 AFSSysNameCB *pSysName = NULL;
2108 ERESOURCE *pSysNameLock = NULL;
2111 UNICODE_STRING uniSysName;
2118 if( IoIs32bitProcess( NULL))
2121 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2123 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2128 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2130 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2134 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2136 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2140 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2141 AFS_TRACE_LEVEL_VERBOSE,
2142 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2144 PsGetCurrentThread());
2146 AFSAcquireShared( pSysNameLock,
2150 // Find where we are in the list
2153 while( pSysName != NULL &&
2154 ulIndex < StringIndex)
2157 pSysName = pSysName->fLink;
2162 if( pSysName == NULL)
2165 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2168 RtlInitUnicodeString( &uniSysName,
2171 // If it is a full component of @SYS then just substitue the
2175 if( RtlCompareUnicodeString( &uniSysName,
2180 SubstituteName->Length = pSysName->SysName.Length;
2181 SubstituteName->MaximumLength = SubstituteName->Length;
2183 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2184 SubstituteName->Length,
2185 AFS_SUBST_BUFFER_TAG);
2187 if( SubstituteName->Buffer == NULL)
2190 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2193 RtlCopyMemory( SubstituteName->Buffer,
2194 pSysName->SysName.Buffer,
2195 pSysName->SysName.Length);
2202 while( ComponentName->Buffer[ usIndex] != L'@')
2208 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2209 SubstituteName->MaximumLength = SubstituteName->Length;
2211 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2212 SubstituteName->Length,
2213 AFS_SUBST_BUFFER_TAG);
2215 if( SubstituteName->Buffer == NULL)
2218 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2221 RtlCopyMemory( SubstituteName->Buffer,
2222 ComponentName->Buffer,
2223 usIndex * sizeof( WCHAR));
2225 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2226 pSysName->SysName.Buffer,
2227 pSysName->SysName.Length);
2232 AFSReleaseResource( pSysNameLock);
2239 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2240 IN OUT UNICODE_STRING *ComponentName,
2241 IN UNICODE_STRING *SubstituteName,
2242 IN OUT UNICODE_STRING *RemainingPath,
2243 IN BOOLEAN FreePathName)
2246 NTSTATUS ntStatus = STATUS_SUCCESS;
2247 UNICODE_STRING uniPathName;
2248 USHORT usPrefixNameLen = 0;
2249 SHORT sNameLenDelta = 0;
2255 // If the passed in name can handle the additional length
2256 // then just moves things around
2259 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2261 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2263 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2266 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2269 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2270 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2271 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2274 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2275 SubstituteName->Buffer,
2276 SubstituteName->Length);
2278 FullPathName->Length += sNameLenDelta;
2280 ComponentName->Length += sNameLenDelta;
2282 ComponentName->MaximumLength = ComponentName->Length;
2284 if ( RemainingPath->Buffer)
2287 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2290 try_return( ntStatus);
2294 // Need to re-allocate the buffer
2297 uniPathName.Length = FullPathName->Length -
2298 ComponentName->Length +
2299 SubstituteName->Length;
2301 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2303 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2304 uniPathName.MaximumLength,
2305 AFS_NAME_BUFFER_FOUR_TAG);
2307 if( uniPathName.Buffer == NULL)
2310 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2313 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2315 usPrefixNameLen *= sizeof( WCHAR);
2317 RtlZeroMemory( uniPathName.Buffer,
2318 uniPathName.MaximumLength);
2320 RtlCopyMemory( uniPathName.Buffer,
2321 FullPathName->Buffer,
2324 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2325 SubstituteName->Buffer,
2326 SubstituteName->Length);
2328 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2331 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2332 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2333 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2336 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2338 ComponentName->Length += sNameLenDelta;
2340 ComponentName->MaximumLength = ComponentName->Length;
2342 if ( RemainingPath->Buffer)
2345 RemainingPath->Buffer = uniPathName.Buffer
2346 + (RemainingPath->Buffer - FullPathName->Buffer)
2347 + sNameLenDelta/sizeof( WCHAR);
2352 AFSExFreePool( FullPathName->Buffer);
2355 *FullPathName = uniPathName;
2366 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2370 NTSTATUS ntStatus = STATUS_SUCCESS;
2371 AFSFcb *pFcb = NULL;
2372 AFSObjectInfoCB *pCurrentObject = NULL;
2378 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2379 AFS_TRACE_LEVEL_VERBOSE,
2380 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2381 VolumeCB->ObjectInformation.FileId.Cell,
2382 VolumeCB->ObjectInformation.FileId.Volume,
2383 VolumeCB->ObjectInformation.FileId.Vnode,
2384 VolumeCB->ObjectInformation.FileId.Unique,
2388 // Depending on the reason for invalidation then perform work on the node
2394 case AFS_INVALIDATE_DELETED:
2398 // Mark this volume as invalid
2401 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2403 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2405 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2407 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2409 FILE_NOTIFY_CHANGE_DIR_NAME,
2410 FILE_ACTION_REMOVED);
2412 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2415 pCurrentObject = VolumeCB->ObjectInfoListHead;
2417 while( pCurrentObject != NULL)
2420 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2422 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2426 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2429 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2432 FILE_ACTION_REMOVED);
2434 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2436 pFcb = pCurrentObject->Fcb;
2439 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2444 // Clear out the extents
2445 // And get rid of them (note this involves waiting
2446 // for any writes or reads to the cache to complete)
2449 (VOID) AFSTearDownFcbExtents( pFcb,
2453 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2456 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2465 // Indicate this node requires re-evaluation for the remaining reasons
2468 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2470 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2471 AFS_TRACE_LEVEL_VERBOSE,
2472 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2473 VolumeCB->ObjectInformation.FileId.Cell,
2474 VolumeCB->ObjectInformation.FileId.Volume,
2475 VolumeCB->ObjectInformation.FileId.Vnode,
2476 VolumeCB->ObjectInformation.FileId.Unique);
2478 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY);
2480 if( Reason == AFS_INVALIDATE_FLUSHED)
2483 VolumeCB->ObjectInformation.DataVersion.QuadPart = (ULONGLONG)-1;
2487 // Notify anyone that cares
2490 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2492 if( Reason == AFS_INVALIDATE_CREDS)
2494 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2497 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2498 Reason == AFS_INVALIDATE_FLUSHED)
2500 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2504 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2507 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2510 FILE_ACTION_MODIFIED);
2513 // Volume invalidations require all objects in the volume be re-verified
2516 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2519 pCurrentObject = VolumeCB->ObjectInfoListHead;
2521 while( pCurrentObject != NULL)
2524 pCurrentObject->Expiration.QuadPart = 0;
2526 pCurrentObject->TargetFileId.Vnode = 0;
2528 pCurrentObject->TargetFileId.Unique = 0;
2530 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2531 AFS_TRACE_LEVEL_VERBOSE,
2532 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2533 pCurrentObject->FileId.Cell,
2534 pCurrentObject->FileId.Volume,
2535 pCurrentObject->FileId.Vnode,
2536 pCurrentObject->FileId.Unique);
2538 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
2540 if( Reason == AFS_INVALIDATE_FLUSHED)
2543 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
2546 if( Reason == AFS_INVALIDATE_FLUSHED &&
2547 pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
2550 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2551 AFS_TRACE_LEVEL_VERBOSE,
2552 "AFSInvalidateVolume Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
2553 pCurrentObject->FileId.Cell,
2554 pCurrentObject->FileId.Volume,
2555 pCurrentObject->FileId.Vnode,
2556 pCurrentObject->FileId.Unique);
2558 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2561 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2563 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2567 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2570 if( Reason == AFS_INVALIDATE_CREDS)
2572 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2575 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2576 Reason == AFS_INVALIDATE_FLUSHED)
2578 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2582 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2585 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2588 FILE_ACTION_MODIFIED);
2590 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2593 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2604 AFSVerifyEntry( IN GUID *AuthGroup,
2605 IN AFSDirectoryCB *DirEntry)
2608 NTSTATUS ntStatus = STATUS_SUCCESS;
2609 AFSDirEnumEntry *pDirEnumEntry = NULL;
2610 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2611 IO_STATUS_BLOCK stIoStatus;
2616 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2617 AFS_TRACE_LEVEL_VERBOSE_2,
2618 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2619 &DirEntry->NameInformation.FileName,
2620 pObjectInfo->FileId.Cell,
2621 pObjectInfo->FileId.Volume,
2622 pObjectInfo->FileId.Vnode,
2623 pObjectInfo->FileId.Unique);
2625 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2630 if( !NT_SUCCESS( ntStatus))
2633 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2634 AFS_TRACE_LEVEL_ERROR,
2635 "AFSValidateEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2636 &DirEntry->NameInformation.FileName,
2637 pObjectInfo->FileId.Cell,
2638 pObjectInfo->FileId.Volume,
2639 pObjectInfo->FileId.Vnode,
2640 pObjectInfo->FileId.Unique,
2643 try_return( ntStatus);
2647 // Check the data version of the file
2650 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2651 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2654 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2655 AFS_TRACE_LEVEL_VERBOSE,
2656 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2657 pObjectInfo->DataVersion.QuadPart,
2658 &DirEntry->NameInformation.FileName,
2659 pObjectInfo->FileId.Cell,
2660 pObjectInfo->FileId.Volume,
2661 pObjectInfo->FileId.Vnode,
2662 pObjectInfo->FileId.Unique);
2665 // We are ok, just get out
2668 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2670 try_return( ntStatus = STATUS_SUCCESS);
2674 // New data version so we will need to process the node based on the type
2677 switch( pDirEnumEntry->FileType)
2680 case AFS_FILE_TYPE_MOUNTPOINT:
2684 // For a mount point we need to ensure the target is the same
2687 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2688 &pDirEnumEntry->TargetFileId))
2694 // Update the metadata for the entry
2697 ntStatus = AFSUpdateMetaData( DirEntry,
2700 if( NT_SUCCESS( ntStatus))
2703 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2709 case AFS_FILE_TYPE_SYMLINK:
2712 ASSERT( pDirEnumEntry->TargetNameLength > 0);
2715 // Update the metadata for the entry
2718 ntStatus = AFSUpdateMetaData( DirEntry,
2721 if( NT_SUCCESS( ntStatus))
2724 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2730 case AFS_FILE_TYPE_FILE:
2732 FILE_OBJECT * pCCFileObject = NULL;
2733 BOOLEAN bPurgeExtents = FALSE;
2735 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2737 bPurgeExtents = TRUE;
2739 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2740 AFS_TRACE_LEVEL_VERBOSE,
2741 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2742 &DirEntry->NameInformation.FileName,
2743 pObjectInfo->FileId.Cell,
2744 pObjectInfo->FileId.Volume,
2745 pObjectInfo->FileId.Vnode,
2746 pObjectInfo->FileId.Unique);
2748 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2752 // Update the metadata for the entry
2755 ntStatus = AFSUpdateMetaData( DirEntry,
2758 if( !NT_SUCCESS( ntStatus))
2761 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2762 AFS_TRACE_LEVEL_ERROR,
2763 "AFSInvalidateCache Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2764 &DirEntry->NameInformation.FileName,
2765 pObjectInfo->FileId.Cell,
2766 pObjectInfo->FileId.Volume,
2767 pObjectInfo->FileId.Vnode,
2768 pObjectInfo->FileId.Unique,
2774 if( pObjectInfo->Fcb != NULL)
2777 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2778 AFS_TRACE_LEVEL_VERBOSE,
2779 "AFSVerifyEntry Flush/purge entry %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 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2792 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2797 if( !NT_SUCCESS( stIoStatus.Status))
2800 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2801 AFS_TRACE_LEVEL_ERROR,
2802 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2803 &DirEntry->NameInformation.FileName,
2804 pObjectInfo->FileId.Cell,
2805 pObjectInfo->FileId.Volume,
2806 pObjectInfo->FileId.Vnode,
2807 pObjectInfo->FileId.Unique,
2809 stIoStatus.Information);
2811 ntStatus = stIoStatus.Status;
2817 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2823 __except( EXCEPTION_EXECUTE_HANDLER)
2825 ntStatus = GetExceptionCode();
2827 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2828 AFS_TRACE_LEVEL_ERROR,
2829 "AFSVerifyEntry CcFlushCache or CcPurgeCacheSection Exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2830 &DirEntry->NameInformation.FileName,
2831 pObjectInfo->FileId.Cell,
2832 pObjectInfo->FileId.Volume,
2833 pObjectInfo->FileId.Vnode,
2834 pObjectInfo->FileId.Unique,
2838 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2842 AFSFlushExtents( pObjectInfo->Fcb,
2847 // Reacquire the Fcb to purge the cache
2850 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2851 AFS_TRACE_LEVEL_VERBOSE,
2852 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2853 &pObjectInfo->Fcb->NPFcb->Resource,
2854 PsGetCurrentThread());
2856 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2860 // Update file sizes
2863 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2864 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2865 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2867 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2869 if ( pCCFileObject != NULL)
2871 CcSetFileSizes( pCCFileObject,
2872 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
2875 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2879 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2880 AFS_TRACE_LEVEL_WARNING,
2881 "AFSValidateEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2882 &DirEntry->NameInformation.FileName,
2883 pObjectInfo->FileId.Cell,
2884 pObjectInfo->FileId.Volume,
2885 pObjectInfo->FileId.Vnode,
2886 pObjectInfo->FileId.Unique);
2889 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2894 case AFS_FILE_TYPE_DIRECTORY:
2897 AFSFcb *pCurrentFcb = NULL;
2898 AFSDirectoryCB *pCurrentDirEntry = NULL;
2901 // For a directory or root entry flush the content of
2902 // the directory enumeration.
2905 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2908 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2909 AFS_TRACE_LEVEL_VERBOSE_2,
2910 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2911 &DirEntry->NameInformation.FileName,
2912 pObjectInfo->FileId.Cell,
2913 pObjectInfo->FileId.Volume,
2914 pObjectInfo->FileId.Vnode,
2915 pObjectInfo->FileId.Unique);
2917 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2920 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
2923 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2925 if ( !NT_SUCCESS( ntStatus))
2928 try_return( ntStatus);
2933 // Update the metadata for the entry
2936 ntStatus = AFSUpdateMetaData( DirEntry,
2939 if( NT_SUCCESS( ntStatus))
2942 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2948 case AFS_FILE_TYPE_DFSLINK:
2951 UNICODE_STRING uniTargetName;
2954 // For a DFS link need to check the target name has not changed
2957 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
2959 uniTargetName.MaximumLength = uniTargetName.Length;
2961 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
2963 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
2966 if( DirEntry->NameInformation.TargetName.Length == 0 ||
2967 RtlCompareUnicodeString( &uniTargetName,
2968 &DirEntry->NameInformation.TargetName,
2973 // Update the target name
2976 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
2978 uniTargetName.Buffer,
2979 uniTargetName.Length);
2981 if( !NT_SUCCESS( ntStatus))
2984 AFSReleaseResource( &DirEntry->NonPaged->Lock);
2990 AFSReleaseResource( &DirEntry->NonPaged->Lock);
2993 // Update the metadata for the entry
2996 ntStatus = AFSUpdateMetaData( DirEntry,
2999 if( NT_SUCCESS( ntStatus))
3002 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3010 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3011 AFS_TRACE_LEVEL_WARNING,
3012 "AFSVerifyEntry Attempt to verify node of type %d\n",
3013 pObjectInfo->FileType);
3020 if( pDirEnumEntry != NULL)
3023 AFSExFreePool( pDirEnumEntry);
3031 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3034 NTSTATUS ntStatus = STATUS_SUCCESS;
3035 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3036 ULONGLONG ullIndex = 0;
3037 AFSVolumeCB *pVolumeCB = NULL;
3038 AFSFcb *pFcb = NULL;
3039 AFSObjectInfoCB *pCurrentObject = NULL;
3044 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3045 AFS_TRACE_LEVEL_VERBOSE,
3046 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3047 VolumeStatus->Online,
3048 VolumeStatus->FileID.Cell,
3049 VolumeStatus->FileID.Volume);
3052 // Need to locate the Fcb for the directory to purge
3055 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3056 AFS_TRACE_LEVEL_VERBOSE,
3057 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3058 &pDevExt->Specific.RDR.VolumeTreeLock,
3059 PsGetCurrentThread());
3061 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3064 // Locate the volume node
3067 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3069 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3071 (AFSBTreeEntry **)&pVolumeCB);
3073 if( pVolumeCB != NULL)
3076 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3078 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3081 // Set the volume state accordingly
3084 if( VolumeStatus->Online)
3087 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3092 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3095 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3098 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3100 while( pCurrentObject != NULL)
3103 if( VolumeStatus->Online)
3106 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3108 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3110 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3115 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3118 pFcb = pCurrentObject->Fcb;
3121 !(VolumeStatus->Online) &&
3122 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3125 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3126 AFS_TRACE_LEVEL_ERROR,
3127 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3128 VolumeStatus->FileID.Cell,
3129 VolumeStatus->FileID.Volume);
3132 // Clear out the extents
3135 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3136 AFS_TRACE_LEVEL_VERBOSE,
3137 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3138 &pFcb->NPFcb->Specific.File.ExtentsResource,
3139 PsGetCurrentThread());
3141 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3144 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3146 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3150 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3151 AFS_TRACE_LEVEL_VERBOSE,
3152 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3153 &pFcb->NPFcb->Specific.File.ExtentsResource,
3154 PsGetCurrentThread());
3156 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3159 // And get rid of them (note this involves waiting
3160 // for any writes or reads to the cache to complete)
3163 (VOID) AFSTearDownFcbExtents( pFcb,
3167 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3170 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3172 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3177 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3185 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3188 NTSTATUS ntStatus = STATUS_SUCCESS;
3193 if( AFSGlobalRoot == NULL)
3196 try_return( ntStatus);
3199 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3203 // Set the network state according to the information
3206 if( NetworkStatus->Online)
3209 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3214 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3217 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3228 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3232 NTSTATUS ntStatus = STATUS_SUCCESS;
3233 BOOLEAN bAcquiredLock = FALSE;
3234 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3235 AFSFcb *pFcb = NULL;
3240 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3241 AFS_TRACE_LEVEL_VERBOSE,
3242 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3243 ObjectInfo->FileId.Cell,
3244 ObjectInfo->FileId.Volume,
3245 ObjectInfo->FileId.Vnode,
3246 ObjectInfo->FileId.Unique);
3248 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3251 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3252 AFS_TRACE_LEVEL_VERBOSE,
3253 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3254 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3255 PsGetCurrentThread());
3257 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3260 bAcquiredLock = TRUE;
3264 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3267 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3268 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3271 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3272 AFS_TRACE_LEVEL_ERROR,
3273 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
3274 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3275 ObjectInfo->FileId.Cell,
3276 ObjectInfo->FileId.Volume,
3277 ObjectInfo->FileId.Vnode,
3278 ObjectInfo->FileId.Unique);
3282 // Reset the directory list information by clearing all valid entries
3285 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3287 while( pCurrentDirEntry != NULL)
3290 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3292 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3296 // If this entry has been deleted then process it here
3299 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3300 pCurrentDirEntry->OpenReferenceCount == 0)
3303 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3304 AFS_TRACE_LEVEL_VERBOSE,
3305 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3307 &pCurrentDirEntry->NameInformation.FileName);
3309 AFSDeleteDirEntry( ObjectInfo,
3315 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3317 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3318 AFS_TRACE_LEVEL_VERBOSE,
3319 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3321 pCurrentDirEntry->OpenReferenceCount);
3324 // We pull the short name from the parent tree since it could change below
3327 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3330 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3331 AFS_TRACE_LEVEL_VERBOSE,
3332 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3334 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3335 &pCurrentDirEntry->NameInformation.FileName);
3337 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3340 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3345 pCurrentDirEntry = pNextDirEntry;
3349 // Reget the directory contents
3352 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3355 if ( !NT_SUCCESS( ntStatus))
3357 try_return( ntStatus);
3361 // Now start again and tear down any entries not valid
3364 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3366 while( pCurrentDirEntry != NULL)
3369 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3371 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3374 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3375 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3378 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3381 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3383 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3384 AFS_TRACE_LEVEL_VERBOSE,
3385 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3387 &pCurrentDirEntry->NameInformation.FileName);
3389 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3394 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3397 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3398 AFS_TRACE_LEVEL_VERBOSE,
3399 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3401 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3402 &pCurrentDirEntry->NameInformation.FileName);
3406 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3408 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3409 AFS_TRACE_LEVEL_VERBOSE,
3410 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3412 &pCurrentDirEntry->NameInformation.FileName);
3417 pCurrentDirEntry = pNextDirEntry;
3422 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3423 AFS_TRACE_LEVEL_VERBOSE,
3424 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3426 pCurrentDirEntry->OpenReferenceCount);
3428 if( pCurrentDirEntry->OpenReferenceCount == 0)
3431 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3432 AFS_TRACE_LEVEL_VERBOSE,
3433 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3434 &pCurrentDirEntry->NameInformation.FileName,
3435 ObjectInfo->FileId.Cell,
3436 ObjectInfo->FileId.Volume,
3437 ObjectInfo->FileId.Vnode,
3438 ObjectInfo->FileId.Unique);
3440 AFSDeleteDirEntry( ObjectInfo,
3446 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3447 AFS_TRACE_LEVEL_VERBOSE,
3448 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3450 &pCurrentDirEntry->NameInformation.FileName,
3451 ObjectInfo->FileId.Cell,
3452 ObjectInfo->FileId.Volume,
3453 ObjectInfo->FileId.Vnode,
3454 ObjectInfo->FileId.Unique);
3456 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3458 AFSRemoveNameEntry( ObjectInfo,
3462 pCurrentDirEntry = pNextDirEntry;
3466 if( !AFSValidateDirList( ObjectInfo))
3469 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3478 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3486 AFSIsVolumeFID( IN AFSFileID *FileID)
3489 BOOLEAN bIsVolume = FALSE;
3491 if( FileID->Vnode == 1 &&
3492 FileID->Unique == 1)
3502 AFSIsFinalNode( IN AFSFcb *Fcb)
3505 BOOLEAN bIsFinalNode = FALSE;
3507 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3508 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3509 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3510 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3511 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3514 bIsFinalNode = TRUE;
3519 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3520 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3523 return bIsFinalNode;
3527 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3528 IN AFSDirEnumEntry *DirEnumEntry)
3531 NTSTATUS ntStatus = STATUS_SUCCESS;
3532 UNICODE_STRING uniTargetName;
3533 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3538 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3540 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3542 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3544 pObjectInfo->FileType = DirEnumEntry->FileType;
3546 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3548 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3550 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3552 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3554 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3556 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3558 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3560 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3563 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3566 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3567 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3570 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3573 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3575 pObjectInfo->Links = DirEnumEntry->Links;
3577 if( DirEnumEntry->TargetNameLength > 0)
3581 // Update the target name information if needed
3584 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3586 uniTargetName.MaximumLength = uniTargetName.Length;
3588 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3590 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3593 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3594 RtlCompareUnicodeString( &uniTargetName,
3595 &DirEntry->NameInformation.TargetName,
3600 // Update the target name
3603 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3605 uniTargetName.Buffer,
3606 uniTargetName.Length);
3608 if( !NT_SUCCESS( ntStatus))
3611 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3613 try_return( ntStatus);
3617 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3619 else if( DirEntry->NameInformation.TargetName.Length > 0)
3622 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3625 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3626 DirEntry->NameInformation.TargetName.Buffer != NULL)
3628 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
3631 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3633 DirEntry->NameInformation.TargetName.Length = 0;
3634 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3635 DirEntry->NameInformation.TargetName.Buffer = NULL;
3637 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3649 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3651 IN BOOLEAN PurgeContent,
3652 IN BOOLEAN FastCall)
3655 NTSTATUS ntStatus = STATUS_SUCCESS;
3656 LARGE_INTEGER liSystemTime;
3657 AFSDirEnumEntry *pDirEnumEntry = NULL;
3658 AFSFcb *pCurrentFcb = NULL;
3659 BOOLEAN bReleaseFcb = FALSE;
3660 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3666 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3670 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3671 AFS_TRACE_LEVEL_VERBOSE_2,
3672 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3673 &DirEntry->NameInformation.FileName,
3674 pObjectInfo->FileId.Cell,
3675 pObjectInfo->FileId.Volume,
3676 pObjectInfo->FileId.Vnode,
3677 pObjectInfo->FileId.Unique);
3680 // If this is a fake node then bail since the service knows nothing about it
3683 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3686 try_return( ntStatus);
3690 pObjectInfo->Fcb != NULL)
3693 pCurrentFcb = pObjectInfo->Fcb;
3695 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3698 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3699 AFS_TRACE_LEVEL_VERBOSE,
3700 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3701 &pCurrentFcb->NPFcb->Resource,
3702 PsGetCurrentThread());
3704 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3712 // This routine ensures that the current entry is valid by:
3714 // 1) Checking that the expiration time is non-zero and after where we
3718 KeQuerySystemTime( &liSystemTime);
3720 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3721 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3722 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3723 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3726 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3727 AFS_TRACE_LEVEL_VERBOSE_2,
3728 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3729 &DirEntry->NameInformation.FileName,
3730 pObjectInfo->FileId.Cell,
3731 pObjectInfo->FileId.Volume,
3732 pObjectInfo->FileId.Vnode,
3733 pObjectInfo->FileId.Unique);
3735 try_return( ntStatus);
3739 // This node requires updating
3742 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3747 if( !NT_SUCCESS( ntStatus))
3750 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3751 AFS_TRACE_LEVEL_ERROR,
3752 "AFSValidateEntry Failed to evaluate entry %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3753 &DirEntry->NameInformation.FileName,
3754 pObjectInfo->FileId.Cell,
3755 pObjectInfo->FileId.Volume,
3756 pObjectInfo->FileId.Vnode,
3757 pObjectInfo->FileId.Unique,
3761 // Failed validation of node so return access-denied
3764 try_return( ntStatus);
3767 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3768 AFS_TRACE_LEVEL_VERBOSE,
3769 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3770 &DirEntry->NameInformation.FileName,
3771 pObjectInfo->FileId.Cell,
3772 pObjectInfo->FileId.Volume,
3773 pObjectInfo->FileId.Vnode,
3774 pObjectInfo->FileId.Unique,
3775 pObjectInfo->DataVersion.QuadPart,
3776 pDirEnumEntry->DataVersion.QuadPart,
3777 pDirEnumEntry->FileType);
3781 // Based on the file type, process the node
3784 switch( pDirEnumEntry->FileType)
3787 case AFS_FILE_TYPE_MOUNTPOINT:
3791 // Update the metadata for the entry
3794 ntStatus = AFSUpdateMetaData( DirEntry,
3797 if( NT_SUCCESS( ntStatus))
3800 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3806 case AFS_FILE_TYPE_SYMLINK:
3807 case AFS_FILE_TYPE_DFSLINK:
3811 // Update the metadata for the entry
3814 ntStatus = AFSUpdateMetaData( DirEntry,
3817 if( NT_SUCCESS( ntStatus))
3820 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3826 case AFS_FILE_TYPE_FILE:
3830 // For a file where the data version has become invalid we need to
3831 // fail any current extent requests and purge the cache for the file
3832 // Can't hold the Fcb resource while doing this
3835 if( pCurrentFcb != NULL &&
3836 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3837 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3840 IO_STATUS_BLOCK stIoStatus;
3841 BOOLEAN bPurgeExtents = FALSE;
3843 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3844 AFS_TRACE_LEVEL_VERBOSE_2,
3845 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3846 &DirEntry->NameInformation.FileName,
3847 pObjectInfo->FileId.Cell,
3848 pObjectInfo->FileId.Volume,
3849 pObjectInfo->FileId.Vnode,
3850 pObjectInfo->FileId.Unique);
3852 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3854 bPurgeExtents = TRUE;
3856 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3857 AFS_TRACE_LEVEL_VERBOSE,
3858 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3859 &DirEntry->NameInformation.FileName,
3860 pObjectInfo->FileId.Cell,
3861 pObjectInfo->FileId.Volume,
3862 pObjectInfo->FileId.Vnode,
3863 pObjectInfo->FileId.Unique);
3865 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3871 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
3876 if( !NT_SUCCESS( stIoStatus.Status))
3879 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3880 AFS_TRACE_LEVEL_ERROR,
3881 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3882 &DirEntry->NameInformation.FileName,
3883 pObjectInfo->FileId.Cell,
3884 pObjectInfo->FileId.Volume,
3885 pObjectInfo->FileId.Vnode,
3886 pObjectInfo->FileId.Unique,
3888 stIoStatus.Information);
3890 ntStatus = stIoStatus.Status;
3896 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3902 __except( EXCEPTION_EXECUTE_HANDLER)
3904 ntStatus = GetExceptionCode();
3906 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3907 AFS_TRACE_LEVEL_ERROR,
3908 "AFSValidateEntry CcFlushCache or CcPurgeCacheSection exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3909 &DirEntry->NameInformation.FileName,
3910 pObjectInfo->FileId.Cell,
3911 pObjectInfo->FileId.Volume,
3912 pObjectInfo->FileId.Vnode,
3913 pObjectInfo->FileId.Unique,
3918 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3922 AFSFlushExtents( pCurrentFcb,
3927 // Reacquire the Fcb to purge the cache
3930 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3931 AFS_TRACE_LEVEL_VERBOSE,
3932 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3933 &pCurrentFcb->NPFcb->Resource,
3934 PsGetCurrentThread());
3936 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3941 // Update the metadata for the entry
3944 ntStatus = AFSUpdateMetaData( DirEntry,
3947 if( !NT_SUCCESS( ntStatus))
3950 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3951 AFS_TRACE_LEVEL_ERROR,
3952 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3953 &DirEntry->NameInformation.FileName,
3954 pObjectInfo->FileId.Cell,
3955 pObjectInfo->FileId.Volume,
3956 pObjectInfo->FileId.Vnode,
3957 pObjectInfo->FileId.Unique,
3963 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3966 // Update file sizes
3969 if( pObjectInfo->Fcb != NULL)
3971 FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3973 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3974 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3975 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3977 if ( pCCFileObject != NULL)
3979 CcSetFileSizes( pCCFileObject,
3980 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3987 case AFS_FILE_TYPE_DIRECTORY:
3990 AFSDirectoryCB *pCurrentDirEntry = NULL;
3992 if( pCurrentFcb != NULL &&
3993 pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3997 // For a directory or root entry flush the content of
3998 // the directory enumeration.
4001 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4002 AFS_TRACE_LEVEL_VERBOSE,
4003 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4004 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4005 PsGetCurrentThread());
4007 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4010 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4011 AFS_TRACE_LEVEL_VERBOSE_2,
4012 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4013 &DirEntry->NameInformation.FileName,
4014 pObjectInfo->FileId.Cell,
4015 pObjectInfo->FileId.Volume,
4016 pObjectInfo->FileId.Vnode,
4017 pObjectInfo->FileId.Unique);
4019 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4022 AFSValidateDirectoryCache( pCurrentFcb->ObjectInformation,
4025 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4028 if( !NT_SUCCESS( ntStatus))
4031 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4032 AFS_TRACE_LEVEL_ERROR,
4033 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4034 &DirEntry->NameInformation.FileName,
4035 pObjectInfo->FileId.Cell,
4036 pObjectInfo->FileId.Volume,
4037 pObjectInfo->FileId.Vnode,
4038 pObjectInfo->FileId.Unique,
4046 // Update the metadata for the entry
4049 ntStatus = AFSUpdateMetaData( DirEntry,
4052 if( NT_SUCCESS( ntStatus))
4055 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4063 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4064 AFS_TRACE_LEVEL_WARNING,
4065 "AFSValidateEntry Attempt to verify node of type %d\n",
4066 pObjectInfo->FileType);
4076 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4079 if( pDirEnumEntry != NULL)
4082 AFSExFreePool( pDirEnumEntry);
4090 AFSInitializeSpecialShareNameList()
4093 NTSTATUS ntStatus = STATUS_SUCCESS;
4094 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4095 AFSObjectInfoCB *pObjectInfoCB = NULL;
4096 UNICODE_STRING uniShareName;
4097 ULONG ulEntryLength = 0;
4098 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4103 RtlInitUnicodeString( &uniShareName,
4106 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4109 if( pObjectInfoCB == NULL)
4112 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4115 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4116 AFS_TRACE_LEVEL_VERBOSE,
4117 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
4120 pObjectInfoCB->ObjectReferenceCount = 1;
4122 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4124 ulEntryLength = sizeof( AFSDirectoryCB) +
4125 uniShareName.Length;
4127 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4131 if( pDirNode == NULL)
4134 AFSDeleteObjectInfo( pObjectInfoCB);
4136 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4139 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4140 sizeof( AFSNonPagedDirectoryCB),
4141 AFS_DIR_ENTRY_NP_TAG);
4143 if( pNonPagedDirEntry == NULL)
4146 ExFreePool( pDirNode);
4148 AFSDeleteObjectInfo( pObjectInfoCB);
4150 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4153 RtlZeroMemory( pDirNode,
4156 RtlZeroMemory( pNonPagedDirEntry,
4157 sizeof( AFSNonPagedDirectoryCB));
4159 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4161 pDirNode->NonPaged = pNonPagedDirEntry;
4163 pDirNode->ObjectInformation = pObjectInfoCB;
4169 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
4171 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4173 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4175 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4177 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4178 uniShareName.Buffer,
4179 pDirNode->NameInformation.FileName.Length);
4181 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4184 AFSSpecialShareNames = pDirNode;
4186 pLastDirNode = pDirNode;
4188 RtlInitUnicodeString( &uniShareName,
4191 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4194 if( pObjectInfoCB == NULL)
4197 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4200 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4201 AFS_TRACE_LEVEL_VERBOSE,
4202 "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
4205 pObjectInfoCB->ObjectReferenceCount = 1;
4207 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4209 ulEntryLength = sizeof( AFSDirectoryCB) +
4210 uniShareName.Length;
4212 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4216 if( pDirNode == NULL)
4219 AFSDeleteObjectInfo( pObjectInfoCB);
4221 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4224 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4225 sizeof( AFSNonPagedDirectoryCB),
4226 AFS_DIR_ENTRY_NP_TAG);
4228 if( pNonPagedDirEntry == NULL)
4231 ExFreePool( pDirNode);
4233 AFSDeleteObjectInfo( pObjectInfoCB);
4235 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4238 RtlZeroMemory( pDirNode,
4241 RtlZeroMemory( pNonPagedDirEntry,
4242 sizeof( AFSNonPagedDirectoryCB));
4244 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4246 pDirNode->NonPaged = pNonPagedDirEntry;
4248 pDirNode->ObjectInformation = pObjectInfoCB;
4254 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
4256 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4258 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4260 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4262 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4263 uniShareName.Buffer,
4264 pDirNode->NameInformation.FileName.Length);
4266 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4269 pLastDirNode->ListEntry.fLink = pDirNode;
4271 pDirNode->ListEntry.bLink = pLastDirNode;
4273 pLastDirNode = pDirNode;
4275 RtlInitUnicodeString( &uniShareName,
4278 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4281 if( pObjectInfoCB == NULL)
4284 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4287 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4288 AFS_TRACE_LEVEL_VERBOSE,
4289 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4292 pObjectInfoCB->ObjectReferenceCount = 1;
4294 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4296 ulEntryLength = sizeof( AFSDirectoryCB) +
4297 uniShareName.Length;
4299 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4303 if( pDirNode == NULL)
4306 AFSDeleteObjectInfo( pObjectInfoCB);
4308 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4311 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4312 sizeof( AFSNonPagedDirectoryCB),
4313 AFS_DIR_ENTRY_NP_TAG);
4315 if( pNonPagedDirEntry == NULL)
4318 ExFreePool( pDirNode);
4320 AFSDeleteObjectInfo( pObjectInfoCB);
4322 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4325 RtlZeroMemory( pDirNode,
4328 RtlZeroMemory( pNonPagedDirEntry,
4329 sizeof( AFSNonPagedDirectoryCB));
4331 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4333 pDirNode->NonPaged = pNonPagedDirEntry;
4335 pDirNode->ObjectInformation = pObjectInfoCB;
4341 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4343 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4345 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4347 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4349 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4350 uniShareName.Buffer,
4351 pDirNode->NameInformation.FileName.Length);
4353 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4356 pLastDirNode->ListEntry.fLink = pDirNode;
4358 pDirNode->ListEntry.bLink = pLastDirNode;
4362 if( !NT_SUCCESS( ntStatus))
4365 if( AFSSpecialShareNames != NULL)
4368 pDirNode = AFSSpecialShareNames;
4370 while( pDirNode != NULL)
4373 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4375 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4377 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4379 ExFreePool( pDirNode->NonPaged);
4381 ExFreePool( pDirNode);
4383 pDirNode = pLastDirNode;
4386 AFSSpecialShareNames = NULL;
4395 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4396 IN UNICODE_STRING *SecondaryName)
4399 AFSDirectoryCB *pDirectoryCB = NULL;
4400 ULONGLONG ullHash = 0;
4401 UNICODE_STRING uniFullShareName;
4407 // Build up the entire name here. We are guaranteed that if there is a
4408 // secondary name, it is pointing to a portion of the share name buffer
4411 if( SecondaryName->Length > 0 &&
4412 SecondaryName->Buffer != NULL)
4415 uniFullShareName = *SecondaryName;
4418 // The calling routine strips off the leading slash so add it back in
4421 uniFullShareName.Buffer--;
4422 uniFullShareName.Length += sizeof( WCHAR);
4423 uniFullShareName.MaximumLength += sizeof( WCHAR);
4426 // And the share name
4429 uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
4430 uniFullShareName.Length += ShareName->Length;
4431 uniFullShareName.MaximumLength += ShareName->Length;
4436 uniFullShareName = *ShareName;
4440 // Generate our hash value
4443 ullHash = AFSGenerateCRC( &uniFullShareName,
4447 // Loop through our special share names to see if this is one of them
4450 pDirectoryCB = AFSSpecialShareNames;
4452 while( pDirectoryCB != NULL)
4455 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4461 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4465 return pDirectoryCB;
4469 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4473 // Block on the queue flush event
4476 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4486 AFSWaitOnQueuedReleases()
4489 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4492 // Block on the queue flush event
4495 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4505 AFSIsEqualFID( IN AFSFileID *FileId1,
4506 IN AFSFileID *FileId2)
4509 BOOLEAN bIsEqual = FALSE;
4511 if( FileId1->Unique == FileId2->Unique &&
4512 FileId1->Vnode == FileId2->Vnode &&
4513 FileId1->Volume == FileId2->Volume &&
4514 FileId1->Cell == FileId2->Cell)
4524 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4527 NTSTATUS ntStatus = STATUS_SUCCESS;
4528 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4533 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4536 // Reset the directory list information
4539 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4541 while( pCurrentDirEntry != NULL)
4544 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4546 if( pCurrentDirEntry->OpenReferenceCount == 0)
4549 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4550 AFS_TRACE_LEVEL_VERBOSE,
4551 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4553 &pCurrentDirEntry->NameInformation.FileName);
4555 AFSDeleteDirEntry( ObjectInfoCB,
4561 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4562 AFS_TRACE_LEVEL_VERBOSE,
4563 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4565 &pCurrentDirEntry->NameInformation.FileName);
4567 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4569 AFSRemoveNameEntry( ObjectInfoCB,
4573 pCurrentDirEntry = pNextDirEntry;
4576 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4578 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4580 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4582 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4584 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4586 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4588 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4589 AFS_TRACE_LEVEL_VERBOSE,
4590 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4591 ObjectInfoCB->FileId.Cell,
4592 ObjectInfoCB->FileId.Volume,
4593 ObjectInfoCB->FileId.Vnode,
4594 ObjectInfoCB->FileId.Unique);
4601 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4604 NTSTATUS ntStatus = STATUS_SUCCESS;
4605 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4606 UNICODE_STRING uniFullName;
4611 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4612 AFS_TRACE_LEVEL_VERBOSE,
4613 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4614 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4615 PsGetCurrentThread());
4617 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4620 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4623 try_return( ntStatus);
4627 // Initialize the root information
4630 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4633 // Enumerate the shares in the volume
4636 ntStatus = AFSEnumerateDirectory( AuthGroup,
4637 &AFSGlobalRoot->ObjectInformation,
4640 if( !NT_SUCCESS( ntStatus))
4643 try_return( ntStatus);
4646 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4649 // Indicate the node is initialized
4652 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4654 uniFullName.MaximumLength = PAGE_SIZE;
4655 uniFullName.Length = 0;
4657 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4658 uniFullName.MaximumLength,
4659 AFS_GENERIC_MEMORY_12_TAG);
4661 if( uniFullName.Buffer == NULL)
4665 // Reset the directory content
4668 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4670 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4672 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4676 // Populate our list of entries in the NP enumeration list
4679 while( pDirGlobalDirNode != NULL)
4682 uniFullName.Buffer[ 0] = L'\\';
4683 uniFullName.Buffer[ 1] = L'\\';
4685 uniFullName.Length = 2 * sizeof( WCHAR);
4687 RtlCopyMemory( &uniFullName.Buffer[ 2],
4688 AFSServerName.Buffer,
4689 AFSServerName.Length);
4691 uniFullName.Length += AFSServerName.Length;
4693 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4695 uniFullName.Length += sizeof( WCHAR);
4697 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4698 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4699 pDirGlobalDirNode->NameInformation.FileName.Length);
4701 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4703 AFSAddConnectionEx( &uniFullName,
4704 RESOURCEDISPLAYTYPE_SHARE,
4707 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4710 AFSExFreePool( uniFullName.Buffer);
4714 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4721 AFSIsRelativeName( IN UNICODE_STRING *Name)
4724 BOOLEAN bIsRelative = FALSE;
4726 if( Name->Buffer[ 0] != L'\\')
4736 AFSUpdateName( IN UNICODE_STRING *Name)
4741 while( usIndex < Name->Length/sizeof( WCHAR))
4744 if( Name->Buffer[ usIndex] == L'/')
4747 Name->Buffer[ usIndex] = L'\\';
4757 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4758 IN OUT ULONG *Flags,
4759 IN WCHAR *NameBuffer,
4760 IN USHORT NameLength)
4763 NTSTATUS ntStatus = STATUS_SUCCESS;
4764 WCHAR *pTmpBuffer = NULL;
4770 // If we have enough space then just move in the name otherwise
4771 // allocate a new buffer
4774 if( TargetName->Length < NameLength)
4777 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4779 AFS_NAME_BUFFER_FIVE_TAG);
4781 if( pTmpBuffer == NULL)
4784 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4787 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4790 AFSExFreePool( TargetName->Buffer);
4793 TargetName->MaximumLength = NameLength;
4795 TargetName->Buffer = pTmpBuffer;
4797 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4800 TargetName->Length = NameLength;
4802 RtlCopyMemory( TargetName->Buffer,
4804 TargetName->Length);
4807 // Update the name in the buffer
4810 AFSUpdateName( TargetName);
4821 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4822 IN ULONG InitialElementCount)
4825 AFSNameArrayHdr *pNameArray = NULL;
4826 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4831 if( InitialElementCount == 0)
4834 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
4837 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
4838 sizeof( AFSNameArrayHdr) +
4839 (InitialElementCount * sizeof( AFSNameArrayCB)),
4840 AFS_NAME_ARRAY_TAG);
4842 if( pNameArray == NULL)
4845 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4846 AFS_TRACE_LEVEL_ERROR,
4847 "AFSInitNameArray Failed to allocate name array\n");
4849 try_return( pNameArray);
4852 RtlZeroMemory( pNameArray,
4853 sizeof( AFSNameArrayHdr) +
4854 (InitialElementCount * sizeof( AFSNameArrayCB)));
4856 pNameArray->MaxElementCount = InitialElementCount;
4858 if( DirectoryCB != NULL)
4861 pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
4863 InterlockedIncrement( &pNameArray->Count);
4865 InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
4867 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4868 AFS_TRACE_LEVEL_VERBOSE,
4869 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
4870 &DirectoryCB->NameInformation.FileName,
4872 DirectoryCB->OpenReferenceCount);
4874 pNameArray->CurrentEntry->DirectoryCB = DirectoryCB;
4876 pNameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
4878 pNameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
4890 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
4891 IN UNICODE_STRING *Path,
4892 IN AFSDirectoryCB *DirectoryCB)
4895 NTSTATUS ntStatus = STATUS_SUCCESS;
4896 AFSNameArrayCB *pCurrentElement = NULL;
4897 UNICODE_STRING uniComponentName, uniRemainingPath;
4898 AFSObjectInfoCB *pCurrentObject = NULL;
4899 ULONG ulTotalCount = 0;
4901 USHORT usLength = 0;
4907 // Init some info in the header
4910 pCurrentElement = &NameArray->ElementArray[ 0];
4912 NameArray->CurrentEntry = pCurrentElement;
4915 // The first entry points at the root
4918 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
4920 InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4922 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4923 AFS_TRACE_LEVEL_VERBOSE,
4924 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
4925 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4926 pCurrentElement->DirectoryCB,
4927 pCurrentElement->DirectoryCB->OpenReferenceCount);
4929 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
4931 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
4933 NameArray->Count = 1;
4935 NameArray->LinkCount = 0;
4938 // If the root is the parent then we are done ...
4941 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
4943 try_return( ntStatus);
4955 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
4956 IN AFSNameArrayHdr *RelatedNameArray,
4957 IN AFSDirectoryCB *DirectoryCB)
4960 NTSTATUS ntStatus = STATUS_SUCCESS;
4961 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
4962 UNICODE_STRING uniComponentName, uniRemainingPath;
4963 AFSObjectInfoCB *pObjectInfo = NULL;
4964 ULONG ulTotalCount = 0;
4966 USHORT usLength = 0;
4972 // Init some info in the header
4975 pCurrentElement = &NameArray->ElementArray[ 0];
4977 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
4979 NameArray->Count = 0;
4981 NameArray->LinkCount = RelatedNameArray->LinkCount;
4984 // Populate the name array with the data from the related array
4990 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
4992 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
4994 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
4996 InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4998 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4999 AFS_TRACE_LEVEL_VERBOSE,
5000 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
5001 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5002 pCurrentElement->DirectoryCB,
5003 pCurrentElement->DirectoryCB->OpenReferenceCount);
5005 InterlockedIncrement( &NameArray->Count);
5007 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5008 NameArray->Count == RelatedNameArray->Count)
5020 pCurrentRelatedElement++;
5023 if( NameArray->Count > 0)
5025 NameArray->CurrentEntry = pCurrentElement;
5033 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5036 NTSTATUS ntStatus = STATUS_SUCCESS;
5037 AFSNameArrayCB *pCurrentElement = NULL;
5042 pCurrentElement = &NameArray->ElementArray[ 0];
5047 if( pCurrentElement->DirectoryCB == NULL)
5053 InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5055 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5056 AFS_TRACE_LEVEL_VERBOSE,
5057 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
5058 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5059 pCurrentElement->DirectoryCB,
5060 pCurrentElement->DirectoryCB->OpenReferenceCount);
5065 AFSExFreePool( NameArray);
5072 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5073 IN AFSDirectoryCB *DirEntry)
5076 NTSTATUS ntStatus = STATUS_SUCCESS;
5077 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5082 if( NameArray->Count == NameArray->MaxElementCount)
5085 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5088 if( NameArray->CurrentEntry != NULL &&
5089 NameArray->CurrentEntry->DirectoryCB == DirEntry)
5092 try_return( ntStatus);
5095 if( NameArray->Count > 0)
5098 NameArray->CurrentEntry++;
5102 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5105 InterlockedIncrement( &NameArray->Count);
5107 InterlockedIncrement( &DirEntry->OpenReferenceCount);
5109 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5110 AFS_TRACE_LEVEL_VERBOSE,
5111 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
5112 &DirEntry->NameInformation.FileName,
5114 DirEntry->OpenReferenceCount);
5116 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5118 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5120 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5131 AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
5132 IN AFSDirectoryCB *DirectoryCB)
5135 ASSERT( NameArray->CurrentEntry != NULL);
5137 InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5139 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5140 AFS_TRACE_LEVEL_VERBOSE,
5141 "AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
5142 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5143 NameArray->CurrentEntry->DirectoryCB,
5144 NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5146 InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5148 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5149 AFS_TRACE_LEVEL_VERBOSE,
5150 "AFSReplaceCurrentElement Increment count on %wZ DE %p Cnt %d\n",
5151 &DirectoryCB->NameInformation.FileName,
5153 DirectoryCB->OpenReferenceCount);
5155 NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
5157 NameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
5159 NameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
5161 if( DirectoryCB->ObjectInformation->ParentObjectInformation == NULL)
5164 SetFlag( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5171 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5174 AFSDirectoryCB *pCurrentDirEntry = NULL;
5179 if( NameArray->Count == 0)
5181 try_return( pCurrentDirEntry);
5184 InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5186 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5187 AFS_TRACE_LEVEL_VERBOSE,
5188 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5189 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5190 NameArray->CurrentEntry->DirectoryCB,
5191 NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5193 NameArray->CurrentEntry->DirectoryCB = NULL;
5195 if( InterlockedDecrement( &NameArray->Count) == 0)
5197 NameArray->CurrentEntry = NULL;
5201 NameArray->CurrentEntry--;
5202 pCurrentDirEntry = NameArray->CurrentEntry->DirectoryCB;
5210 return pCurrentDirEntry;
5214 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5217 AFSDirectoryCB *pDirEntry = NULL;
5218 AFSNameArrayCB *pElement = NULL;
5223 if( NameArray->Count == 0 ||
5224 NameArray->Count == 1)
5227 try_return( pDirEntry = NULL);
5230 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5232 pDirEntry = pElement->DirectoryCB;
5243 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5244 IN AFSDirectoryCB *DirEntry)
5247 AFSNameArrayCB *pCurrentElement = NULL;
5248 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5253 pCurrentElement = &NameArray->ElementArray[ 0];
5258 if( pCurrentElement->DirectoryCB == NULL)
5264 InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5266 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5267 AFS_TRACE_LEVEL_VERBOSE,
5268 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5269 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5270 pCurrentElement->DirectoryCB,
5271 pCurrentElement->DirectoryCB->OpenReferenceCount);
5276 RtlZeroMemory( NameArray,
5277 sizeof( AFSNameArrayHdr) +
5278 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5280 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5282 if( DirEntry != NULL)
5285 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5287 InterlockedIncrement( &NameArray->Count);
5289 InterlockedIncrement( &DirEntry->OpenReferenceCount);
5291 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5292 AFS_TRACE_LEVEL_VERBOSE,
5293 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5294 &DirEntry->NameInformation.FileName,
5296 DirEntry->OpenReferenceCount);
5298 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5300 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5302 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5310 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5313 AFSNameArrayCB *pCurrentElement = NULL;
5315 pCurrentElement = &NameArray->ElementArray[ 0];
5317 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5319 while( pCurrentElement->DirectoryCB != NULL)
5322 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5323 pCurrentElement->FileId.Cell,
5324 pCurrentElement->FileId.Volume,
5325 pCurrentElement->FileId.Vnode,
5326 pCurrentElement->FileId.Unique,
5327 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5332 AFSPrint("AFSDumpNameArray End\n\n");
5338 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5342 // Depending on the type of node, set the event
5345 switch( Fcb->Header.NodeTypeCode)
5348 case AFS_DIRECTORY_FCB:
5351 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5355 InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5364 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5368 InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5378 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5382 // Depending on the type of node, set the event
5385 switch( Fcb->Header.NodeTypeCode)
5388 case AFS_DIRECTORY_FCB:
5391 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5393 if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
5396 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5406 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5408 if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
5411 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5422 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5425 BOOLEAN bIsInProcess = FALSE;
5430 if( ObjectInfo->Fcb == NULL)
5433 try_return( bIsInProcess);
5437 // Depending on the type of node, set the event
5440 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5443 case AFS_DIRECTORY_FCB:
5446 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5449 bIsInProcess = TRUE;
5459 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5462 bIsInProcess = TRUE;
5474 return bIsInProcess;
5478 AFSVerifyVolume( IN ULONGLONG ProcessId,
5479 IN AFSVolumeCB *VolumeCB)
5482 NTSTATUS ntStatus = STATUS_SUCCESS;
5489 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5492 NTSTATUS ntStatus = STATUS_SUCCESS;
5493 AFSObjectInfoCB *pObjectInfoCB = NULL;
5494 AFSDirectoryCB *pDirNode = NULL;
5495 ULONG ulEntryLength = 0;
5496 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5501 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5504 if( pObjectInfoCB == NULL)
5507 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5510 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5511 AFS_TRACE_LEVEL_VERBOSE,
5512 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5515 pObjectInfoCB->ObjectReferenceCount = 1;
5517 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5519 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5521 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5523 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5527 if( pDirNode == NULL)
5530 AFSDeleteObjectInfo( pObjectInfoCB);
5532 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5535 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5536 sizeof( AFSNonPagedDirectoryCB),
5537 AFS_DIR_ENTRY_NP_TAG);
5539 if( pNonPagedDirEntry == NULL)
5542 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5545 RtlZeroMemory( pDirNode,
5548 RtlZeroMemory( pNonPagedDirEntry,
5549 sizeof( AFSNonPagedDirectoryCB));
5551 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5553 pDirNode->NonPaged = pNonPagedDirEntry;
5555 pDirNode->ObjectInformation = pObjectInfoCB;
5557 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5563 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5565 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5567 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5569 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5571 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5572 AFSPIOCtlName.Buffer,
5573 pDirNode->NameInformation.FileName.Length);
5575 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5578 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB = pDirNode;
5582 if ( !NT_SUCCESS( ntStatus))
5585 if ( pDirNode != NULL)
5588 AFSExFreePool( pDirNode);
5591 if ( pObjectInfoCB != NULL)
5594 AFSDeleteObjectInfo( pObjectInfoCB);
5603 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5604 IN AFSDirectoryCB *DirectoryCB,
5605 IN UNICODE_STRING *ParentPathName,
5606 IN AFSNameArrayHdr *RelatedNameArray,
5608 OUT AFSFileInfoCB *FileInfo)
5611 NTSTATUS ntStatus = STATUS_SUCCESS;
5612 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
5613 UNICODE_STRING uniFullPathName;
5614 AFSNameArrayHdr *pNameArray = NULL;
5615 AFSVolumeCB *pVolumeCB = NULL;
5616 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5617 WCHAR *pwchBuffer = NULL;
5618 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5619 ULONG ulNameDifference = 0;
5625 // Retrieve a target name for the entry
5628 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5631 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5634 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5636 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5641 if( !NT_SUCCESS( ntStatus) ||
5642 pDirEntry->TargetNameLength == 0)
5645 if( pDirEntry != NULL)
5648 ntStatus = STATUS_ACCESS_DENIED;
5651 try_return( ntStatus);
5654 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5657 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5661 // Update the target name
5664 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5665 &DirectoryCB->Flags,
5666 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5667 (USHORT)pDirEntry->TargetNameLength);
5669 if( !NT_SUCCESS( ntStatus))
5672 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5674 try_return( ntStatus);
5678 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5682 // Need to pass the full path in for parsing.
5685 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5688 uniFullPathName.Length = 0;
5689 uniFullPathName.MaximumLength = ParentPathName->Length +
5691 DirectoryCB->NameInformation.TargetName.Length;
5693 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5694 uniFullPathName.MaximumLength,
5695 AFS_NAME_BUFFER_SIX_TAG);
5697 if( uniFullPathName.Buffer == NULL)
5700 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5702 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5705 pwchBuffer = uniFullPathName.Buffer;
5707 RtlZeroMemory( uniFullPathName.Buffer,
5708 uniFullPathName.MaximumLength);
5710 RtlCopyMemory( uniFullPathName.Buffer,
5711 ParentPathName->Buffer,
5712 ParentPathName->Length);
5714 uniFullPathName.Length = ParentPathName->Length;
5716 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5717 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5720 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5722 uniFullPathName.Length += sizeof( WCHAR);
5725 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5726 DirectoryCB->NameInformation.TargetName.Buffer,
5727 DirectoryCB->NameInformation.TargetName.Length);
5729 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5731 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5732 uniParsedName.MaximumLength = uniParsedName.Length;
5734 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5736 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5739 // We populate up to the current parent
5742 if( RelatedNameArray != NULL)
5745 pNameArray = AFSInitNameArray( NULL,
5746 RelatedNameArray->MaxElementCount);
5748 if( pNameArray == NULL)
5751 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5754 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5761 pNameArray = AFSInitNameArray( NULL,
5764 if( pNameArray == NULL)
5767 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5770 ntStatus = AFSPopulateNameArray( pNameArray,
5775 if( !NT_SUCCESS( ntStatus))
5778 try_return( ntStatus);
5781 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5783 AFSAcquireShared( pVolumeCB->VolumeLock,
5786 pParentDirEntry = ParentDirectoryCB;
5791 uniFullPathName.Length = 0;
5792 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5794 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5795 uniFullPathName.MaximumLength,
5796 AFS_NAME_BUFFER_SEVEN_TAG);
5798 if( uniFullPathName.Buffer == NULL)
5801 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5803 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5806 pwchBuffer = uniFullPathName.Buffer;
5808 RtlZeroMemory( uniFullPathName.Buffer,
5809 uniFullPathName.MaximumLength);
5811 RtlCopyMemory( uniFullPathName.Buffer,
5812 DirectoryCB->NameInformation.TargetName.Buffer,
5813 DirectoryCB->NameInformation.TargetName.Length);
5815 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5818 // This name should begin with the \afs server so parse it off and check it
5821 FsRtlDissectName( uniFullPathName,
5825 if( RtlCompareUnicodeString( &uniComponentName,
5830 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5832 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5833 AFS_TRACE_LEVEL_ERROR,
5834 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5837 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5840 uniFullPathName = uniRemainingPath;
5842 uniParsedName = uniFullPathName;
5844 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5846 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5852 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5855 if( pNameArray == NULL)
5858 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5861 pVolumeCB = AFSGlobalRoot;
5863 AFSAcquireShared( pVolumeCB->VolumeLock,
5866 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5870 // Increment the ref count on the volume and dir entry for correct processing below
5873 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
5875 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5876 AFS_TRACE_LEVEL_VERBOSE,
5877 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
5879 pVolumeCB->VolumeReferenceCount);
5881 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
5883 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5884 AFS_TRACE_LEVEL_VERBOSE,
5885 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5886 &pParentDirEntry->NameInformation.FileName,
5889 pParentDirEntry->OpenReferenceCount);
5891 ntStatus = AFSLocateNameEntry( NULL,
5896 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5902 if( !NT_SUCCESS( ntStatus))
5906 // The volume lock was released on failure above
5907 // Except for STATUS_OBJECT_NAME_NOT_FOUND
5910 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
5913 if( pVolumeCB != NULL)
5916 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5918 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5919 AFS_TRACE_LEVEL_VERBOSE,
5920 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
5922 pVolumeCB->VolumeReferenceCount);
5924 AFSReleaseResource( pVolumeCB->VolumeLock);
5927 if( pDirectoryEntry != NULL)
5930 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5932 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5933 AFS_TRACE_LEVEL_VERBOSE,
5934 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5935 &pDirectoryEntry->NameInformation.FileName,
5938 pDirectoryEntry->OpenReferenceCount);
5943 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
5945 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5946 AFS_TRACE_LEVEL_VERBOSE,
5947 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5948 &pParentDirEntry->NameInformation.FileName,
5951 pParentDirEntry->OpenReferenceCount);
5957 try_return( ntStatus);
5961 // Store off the information
5964 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5967 // Check for the mount point being returned
5970 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
5973 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5975 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
5976 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5979 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
5982 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
5987 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5991 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5993 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5995 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5997 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5999 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6001 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6004 // Remove the reference made above
6007 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6009 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6010 AFS_TRACE_LEVEL_VERBOSE,
6011 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
6012 &pDirectoryEntry->NameInformation.FileName,
6015 pDirectoryEntry->OpenReferenceCount);
6019 if( pDirEntry != NULL)
6022 AFSExFreePool( pDirEntry);
6025 if( pVolumeCB != NULL)
6028 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6030 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6031 AFS_TRACE_LEVEL_VERBOSE,
6032 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
6034 pVolumeCB->VolumeReferenceCount);
6036 AFSReleaseResource( pVolumeCB->VolumeLock);
6039 if( pNameArray != NULL)
6042 AFSFreeNameArray( pNameArray);
6045 if( pwchBuffer != NULL)
6049 // Always free the buffer that we allocated as AFSLocateNameEntry
6050 // will not free it. If uniFullPathName.Buffer was allocated by
6051 // AFSLocateNameEntry, then we must free that as well.
6052 // Check that the uniFullPathName.Buffer in the string is not the same
6053 // offset by the length of the server name
6056 if( uniFullPathName.Length > 0 &&
6057 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6060 AFSExFreePool( uniFullPathName.Buffer);
6063 AFSExFreePool( pwchBuffer);
6071 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6072 IN ULONGLONG HashIndex)
6075 NTSTATUS ntStatus = STATUS_SUCCESS;
6076 AFSObjectInfoCB *pObjectInfo = NULL;
6081 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6082 sizeof( AFSObjectInfoCB),
6083 AFS_OBJECT_INFO_TAG);
6085 if( pObjectInfo == NULL)
6088 try_return( pObjectInfo);
6091 RtlZeroMemory( pObjectInfo,
6092 sizeof( AFSObjectInfoCB));
6094 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6095 sizeof( AFSNonPagedObjectInfoCB),
6096 AFS_NP_OBJECT_INFO_TAG);
6098 if( pObjectInfo->NonPagedInfo == NULL)
6101 AFSExFreePool( pObjectInfo);
6103 try_return( pObjectInfo = NULL);
6106 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6108 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6110 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6112 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6114 if( ParentObjectInfo != NULL)
6116 InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
6120 // Initialize the access time
6123 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6129 // Insert the entry into the object tree and list
6132 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6134 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6137 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6142 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6143 &pObjectInfo->TreeEntry);
6145 ASSERT( NT_SUCCESS( ntStatus));
6149 // And the object list in the volume
6152 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6155 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6160 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6162 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6165 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6168 // Indicate the object is in the hash tree and linked list in the volume
6171 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6183 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6186 BOOLEAN bAcquiredTreeLock = FALSE;
6188 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6191 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6193 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6196 bAcquiredTreeLock = TRUE;
6200 // Remove it from the tree and list if it was inserted
6203 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6206 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6207 &ObjectInfo->TreeEntry);
6210 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6213 if( ObjectInfo->ListEntry.fLink == NULL)
6216 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6218 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6221 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6227 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6230 if( ObjectInfo->ListEntry.bLink == NULL)
6233 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6235 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6238 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6244 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6248 if( ObjectInfo->ParentObjectInformation != NULL)
6250 InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
6253 if( bAcquiredTreeLock)
6256 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6260 // Release the fid in the service
6263 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6266 AFSReleaseFid( &ObjectInfo->FileId);
6269 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6271 AFSExFreePool( ObjectInfo->NonPagedInfo);
6273 AFSExFreePool( ObjectInfo);
6279 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6280 OUT AFSDirectoryCB **TargetDirEntry)
6283 NTSTATUS ntStatus = STATUS_SUCCESS;
6284 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6285 UNICODE_STRING uniFullPathName;
6286 AFSNameArrayHdr *pNameArray = NULL;
6287 AFSVolumeCB *pVolumeCB = NULL;
6288 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6289 WCHAR *pwchBuffer = NULL;
6290 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6291 ULONG ulNameDifference = 0;
6297 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6298 DirectoryCB->ObjectInformation,
6302 if( !NT_SUCCESS( ntStatus))
6304 try_return( ntStatus);
6308 // Retrieve a target name for the entry
6311 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6314 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6317 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6319 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6324 if( !NT_SUCCESS( ntStatus) ||
6325 pDirEntry->TargetNameLength == 0)
6328 if( pDirEntry != NULL)
6331 ntStatus = STATUS_ACCESS_DENIED;
6334 try_return( ntStatus);
6337 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6340 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6344 // Update the target name
6347 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6348 &DirectoryCB->Flags,
6349 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6350 (USHORT)pDirEntry->TargetNameLength);
6352 if( !NT_SUCCESS( ntStatus))
6355 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6357 try_return( ntStatus);
6361 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6365 // Need to pass the full path in for parsing.
6368 uniFullPathName.Length = 0;
6369 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6371 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6372 uniFullPathName.MaximumLength,
6373 AFS_NAME_BUFFER_EIGHT_TAG);
6375 if( uniFullPathName.Buffer == NULL)
6378 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6380 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6383 pwchBuffer = uniFullPathName.Buffer;
6385 RtlZeroMemory( uniFullPathName.Buffer,
6386 uniFullPathName.MaximumLength);
6388 RtlCopyMemory( uniFullPathName.Buffer,
6389 DirectoryCB->NameInformation.TargetName.Buffer,
6390 DirectoryCB->NameInformation.TargetName.Length);
6392 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6395 // This name should begin with the \afs server so parse it off and chech it
6398 FsRtlDissectName( uniFullPathName,
6402 if( RtlCompareUnicodeString( &uniComponentName,
6408 // Try evaluating the full path
6411 uniFullPathName.Buffer = pwchBuffer;
6413 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6415 uniFullPathName.MaximumLength = uniFullPathName.Length;
6420 uniFullPathName = uniRemainingPath;
6423 uniParsedName = uniFullPathName;
6425 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6427 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6433 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6436 if( pNameArray == NULL)
6439 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6442 pVolumeCB = AFSGlobalRoot;
6444 AFSAcquireShared( pVolumeCB->VolumeLock,
6447 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6449 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6451 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6452 AFS_TRACE_LEVEL_VERBOSE,
6453 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6455 pVolumeCB->VolumeReferenceCount);
6457 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6459 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6460 AFS_TRACE_LEVEL_VERBOSE,
6461 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6462 &pParentDirEntry->NameInformation.FileName,
6465 pParentDirEntry->OpenReferenceCount);
6467 ntStatus = AFSLocateNameEntry( NULL,
6478 if( !NT_SUCCESS( ntStatus))
6482 // The volume lock was released on failure above
6483 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6486 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6489 if( pVolumeCB != NULL)
6492 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6494 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6495 AFS_TRACE_LEVEL_VERBOSE,
6496 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
6498 pVolumeCB->VolumeReferenceCount);
6500 AFSReleaseResource( pVolumeCB->VolumeLock);
6503 if( pDirectoryEntry != NULL)
6506 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6508 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6509 AFS_TRACE_LEVEL_VERBOSE,
6510 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6511 &pDirectoryEntry->NameInformation.FileName,
6514 pDirectoryEntry->OpenReferenceCount);
6519 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6521 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6522 AFS_TRACE_LEVEL_VERBOSE,
6523 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6524 &pParentDirEntry->NameInformation.FileName,
6527 pParentDirEntry->OpenReferenceCount);
6533 try_return( ntStatus);
6537 // Pass back the target dir entry for this request
6540 *TargetDirEntry = pDirectoryEntry;
6544 if( pDirEntry != NULL)
6547 AFSExFreePool( pDirEntry);
6550 if( pVolumeCB != NULL)
6553 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6555 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6556 AFS_TRACE_LEVEL_VERBOSE,
6557 "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
6559 pVolumeCB->VolumeReferenceCount);
6561 AFSReleaseResource( pVolumeCB->VolumeLock);
6564 if( pNameArray != NULL)
6567 AFSFreeNameArray( pNameArray);
6570 if( pwchBuffer != NULL)
6574 // Always free the buffer that we allocated as AFSLocateNameEntry
6575 // will not free it. If uniFullPathName.Buffer was allocated by
6576 // AFSLocateNameEntry, then we must free that as well.
6577 // Check that the uniFullPathName.Buffer in the string is not the same
6578 // offset by the length of the server name
6581 if( uniFullPathName.Length > 0 &&
6582 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6585 AFSExFreePool( uniFullPathName.Buffer);
6588 AFSExFreePool( pwchBuffer);
6596 AFSCleanupFcb( IN AFSFcb *Fcb,
6597 IN BOOLEAN ForceFlush)
6600 NTSTATUS ntStatus = STATUS_SUCCESS;
6601 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6602 LARGE_INTEGER liTime;
6603 IO_STATUS_BLOCK stIoStatus;
6608 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6610 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6612 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6615 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6616 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6619 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6622 if( Fcb->OpenReferenceCount > 0)
6628 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6633 if( !NT_SUCCESS( stIoStatus.Status))
6636 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6637 AFS_TRACE_LEVEL_ERROR,
6638 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6639 Fcb->ObjectInformation->FileId.Cell,
6640 Fcb->ObjectInformation->FileId.Volume,
6641 Fcb->ObjectInformation->FileId.Vnode,
6642 Fcb->ObjectInformation->FileId.Unique,
6644 stIoStatus.Information);
6646 ntStatus = stIoStatus.Status;
6649 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6654 __except( EXCEPTION_EXECUTE_HANDLER)
6656 ntStatus = GetExceptionCode();
6660 AFSReleaseResource( &Fcb->NPFcb->Resource);
6663 // Wait for any currently running flush or release requests to complete
6666 AFSWaitOnQueuedFlushes( Fcb);
6669 // Now perform another flush on the file
6672 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6676 AFSReleaseExtentsWithFlush( Fcb,
6681 if( Fcb->OpenReferenceCount == 0 ||
6682 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6683 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6686 AFSTearDownFcbExtents( Fcb,
6690 try_return( ntStatus);
6693 KeQueryTickCount( &liTime);
6696 // First up are there dirty extents in the cache to flush?
6700 ( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6701 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
6702 ( Fcb->Specific.File.ExtentsDirtyCount ||
6703 Fcb->Specific.File.ExtentCount) &&
6704 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6705 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6707 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6709 Fcb->OpenReferenceCount == 0)
6712 AFSReleaseExtentsWithFlush( Fcb,
6716 else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6717 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6721 // The file has been marked as invalid. Dump it
6724 AFSTearDownFcbExtents( Fcb,
6729 // If there are extents and they haven't been used recently *and*
6730 // are not being used
6734 ( 0 != Fcb->Specific.File.ExtentCount &&
6735 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6736 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6737 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
6738 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6745 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6750 if( !NT_SUCCESS( stIoStatus.Status))
6753 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6754 AFS_TRACE_LEVEL_ERROR,
6755 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6756 Fcb->ObjectInformation->FileId.Cell,
6757 Fcb->ObjectInformation->FileId.Volume,
6758 Fcb->ObjectInformation->FileId.Vnode,
6759 Fcb->ObjectInformation->FileId.Unique,
6761 stIoStatus.Information);
6763 ntStatus = stIoStatus.Status;
6769 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6775 __except( EXCEPTION_EXECUTE_HANDLER)
6777 ntStatus = GetExceptionCode();
6780 AFSReleaseResource( &Fcb->NPFcb->Resource);
6782 if( Fcb->OpenReferenceCount == 0)
6786 // Tear em down we'll not be needing them again
6789 AFSTearDownFcbExtents( Fcb,
6803 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
6804 IN UNICODE_STRING *NewFileName)
6807 NTSTATUS ntStatus = STATUS_SUCCESS;
6808 WCHAR *pTmpBuffer = NULL;
6813 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
6816 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
6819 AFSExFreePool( DirectoryCB->NameInformation.FileName.Buffer);
6821 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6823 DirectoryCB->NameInformation.FileName.Buffer = NULL;
6827 // OK, we need to allocate a new name buffer
6830 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6831 NewFileName->Length,
6832 AFS_NAME_BUFFER_NINE_TAG);
6834 if( pTmpBuffer == NULL)
6837 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6840 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
6842 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
6844 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6847 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
6849 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
6850 NewFileName->Buffer,
6851 NewFileName->Length);
6862 AFSReadCacheFile( IN void *ReadBuffer,
6863 IN LARGE_INTEGER *ReadOffset,
6864 IN ULONG RequestedDataLength,
6865 IN OUT PULONG BytesRead)
6868 NTSTATUS ntStatus = STATUS_SUCCESS;
6871 PIO_STACK_LOCATION pIoStackLocation = NULL;
6872 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6873 DEVICE_OBJECT *pTargetDeviceObject = NULL;
6874 FILE_OBJECT *pCacheFileObject = NULL;
6879 pCacheFileObject = AFSReferenceCacheFileObject();
6881 if( pCacheFileObject == NULL)
6883 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
6886 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
6889 // Initialize the event
6892 KeInitializeEvent( &kEvent,
6893 SynchronizationEvent,
6897 // Allocate an irp for this request. This could also come from a
6898 // private pool, for instance.
6901 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
6907 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6911 // Build the IRP's main body
6914 pIrp->UserBuffer = ReadBuffer;
6916 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
6917 pIrp->RequestorMode = KernelMode;
6918 pIrp->Flags |= IRP_READ_OPERATION;
6921 // Set up the I/O stack location.
6924 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
6925 pIoStackLocation->MajorFunction = IRP_MJ_READ;
6926 pIoStackLocation->DeviceObject = pTargetDeviceObject;
6927 pIoStackLocation->FileObject = pCacheFileObject;
6928 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
6930 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
6933 // Set the completion routine.
6936 IoSetCompletionRoutine( pIrp,
6944 // Send it to the FSD
6947 ntStatus = IoCallDriver( pTargetDeviceObject,
6950 if( NT_SUCCESS( ntStatus))
6957 ntStatus = KeWaitForSingleObject( &kEvent,
6963 if( NT_SUCCESS( ntStatus))
6966 ntStatus = pIrp->IoStatus.Status;
6968 *BytesRead = (ULONG)pIrp->IoStatus.Information;
6974 if( pCacheFileObject != NULL)
6976 AFSReleaseCacheFileObject( pCacheFileObject);
6982 if( pIrp->MdlAddress != NULL)
6985 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
6988 MmUnlockPages( pIrp->MdlAddress);
6991 IoFreeMdl( pIrp->MdlAddress);
6994 pIrp->MdlAddress = NULL;
7008 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7013 KEVENT *pEvent = (KEVENT *)Context;
7019 return STATUS_MORE_PROCESSING_REQUIRED;
7023 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7026 BOOLEAN bIsEmpty = FALSE;
7027 AFSDirectoryCB *pDirEntry = NULL;
7032 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7037 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7040 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7042 while( pDirEntry != NULL)
7045 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7046 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7054 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7059 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7066 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7067 IN AFSDirectoryCB *DirEntry)
7070 NTSTATUS ntStatus = STATUS_SUCCESS;
7075 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7078 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7079 AFS_TRACE_LEVEL_VERBOSE,
7080 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7082 &DirEntry->NameInformation.FileName);
7084 try_return( ntStatus);
7087 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7090 // Remove the entry from the parent tree
7093 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7094 AFS_TRACE_LEVEL_VERBOSE,
7095 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7097 &DirEntry->NameInformation.FileName);
7099 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7102 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7103 AFS_TRACE_LEVEL_VERBOSE,
7104 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7106 &DirEntry->NameInformation.FileName);
7108 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7111 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7115 // From the short name tree
7118 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7119 AFS_TRACE_LEVEL_VERBOSE,
7120 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7122 &DirEntry->NameInformation.FileName);
7124 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7127 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7130 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7131 AFS_TRACE_LEVEL_VERBOSE,
7132 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7134 &DirEntry->NameInformation.FileName);
7136 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7138 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7149 AFSGetAuthenticationId()
7152 LARGE_INTEGER liAuthId = {0,0};
7153 NTSTATUS ntStatus = STATUS_SUCCESS;
7154 PACCESS_TOKEN hToken = NULL;
7155 PTOKEN_STATISTICS pTokenInfo = NULL;
7156 BOOLEAN bCopyOnOpen = FALSE;
7157 BOOLEAN bEffectiveOnly = FALSE;
7158 BOOLEAN bPrimaryToken = FALSE;
7159 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7164 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7167 &stImpersonationLevel);
7172 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7177 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7178 AFS_TRACE_LEVEL_ERROR,
7179 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7181 try_return( ntStatus);
7184 bPrimaryToken = TRUE;
7187 ntStatus = SeQueryInformationToken( hToken,
7189 (PVOID *)&pTokenInfo);
7191 if( !NT_SUCCESS( ntStatus))
7194 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7195 AFS_TRACE_LEVEL_ERROR,
7196 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7198 try_return( ntStatus);
7201 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7202 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7204 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7205 AFS_TRACE_LEVEL_VERBOSE,
7206 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7217 PsDereferenceImpersonationToken( hToken);
7222 PsDereferencePrimaryToken( hToken);
7226 if( pTokenInfo != NULL)
7229 AFSExFreePool( pTokenInfo);
7237 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7241 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7243 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7246 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7248 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7251 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7253 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7256 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7258 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7261 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7263 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7270 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7273 BOOLEAN bIsValid = TRUE;
7275 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7277 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7279 while( pCurrentDirEntry != NULL)
7282 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7286 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7291 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7292 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7295 if( pDirEntry == NULL)
7302 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7305 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7308 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7310 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7312 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7321 AFSReferenceCacheFileObject()
7324 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7325 FILE_OBJECT *pCacheFileObject = NULL;
7327 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7330 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7332 if( pCacheFileObject != NULL)
7334 ObReferenceObject( pCacheFileObject);
7337 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7339 return pCacheFileObject;
7343 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7346 ASSERT( CacheFileObject != NULL);
7348 ObDereferenceObject( CacheFileObject);
7354 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7357 NTSTATUS ntStatus = STATUS_SUCCESS;
7358 AFSDeviceExt *pControlDevExt = NULL;
7359 ULONG ulTimeIncrement = 0;
7364 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7366 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7368 AFSServerName = LibraryInit->AFSServerName;
7370 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7373 // Callbacks in the framework
7376 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7378 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7380 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7382 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7384 AFSExFreePool = LibraryInit->AFSExFreePool;
7386 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7388 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7390 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7392 if( LibraryInit->AFSCacheBaseAddress != NULL)
7395 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7397 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7399 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7403 // Initialize some flush parameters
7406 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7408 ulTimeIncrement = KeQueryTimeIncrement();
7410 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7411 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_ONE_SECOND;
7412 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart *= AFS_SERVER_PURGE_DELAY;
7413 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7414 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)(AFS_ONE_SECOND * AFS_SERVER_FLUSH_DELAY) / (ULONGLONG)ulTimeIncrement);
7415 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7418 // Initialize the global root entry
7421 ntStatus = AFSInitVolume( NULL,
7422 &LibraryInit->GlobalRootFid,
7425 if( !NT_SUCCESS( ntStatus))
7428 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7429 AFS_TRACE_LEVEL_ERROR,
7430 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7433 try_return( ntStatus);
7436 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7439 if( !NT_SUCCESS( ntStatus))
7442 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7443 AFS_TRACE_LEVEL_ERROR,
7444 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7447 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7449 try_return( ntStatus);
7453 // Update the node type code to AFS_ROOT_ALL
7456 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7458 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7461 // Drop the locks acquired above
7464 AFSInitVolumeWorker( AFSGlobalRoot);
7466 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7468 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7482 NTSTATUS ntStatus = STATUS_SUCCESS;
7483 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7488 if( AFSGlobalDotDirEntry != NULL)
7491 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
7493 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7495 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7497 ExFreePool( AFSGlobalDotDirEntry);
7499 AFSGlobalDotDirEntry = NULL;
7502 if( AFSGlobalDotDotDirEntry != NULL)
7505 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
7507 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7509 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7511 ExFreePool( AFSGlobalDotDotDirEntry);
7513 AFSGlobalDotDotDirEntry = NULL;
7516 if( AFSSpecialShareNames != NULL)
7519 pDirNode = AFSSpecialShareNames;
7521 while( pDirNode != NULL)
7524 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7526 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
7528 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7530 ExFreePool( pDirNode->NonPaged);
7532 ExFreePool( pDirNode);
7534 pDirNode = pLastDirNode;
7537 AFSSpecialShareNames = NULL;
7545 AFSDefaultLogMsg( IN ULONG Subsystem,
7551 NTSTATUS ntStatus = STATUS_SUCCESS;
7553 char chDebugBuffer[ 256];
7558 va_start( va_args, Format);
7560 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7565 if( NT_SUCCESS( ntStatus))
7567 DbgPrint( chDebugBuffer);
7577 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7578 IN ULONG InputBufferLength,
7579 IN AFSStatusInfoCB *StatusInfo,
7580 OUT ULONG *ReturnLength)
7583 NTSTATUS ntStatus = STATUS_SUCCESS;
7584 AFSFcb *pFcb = NULL;
7585 AFSVolumeCB *pVolumeCB = NULL;
7586 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7587 AFSObjectInfoCB *pObjectInfo = NULL;
7588 ULONGLONG ullIndex = 0;
7589 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7590 AFSNameArrayHdr *pNameArray = NULL;
7591 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7597 // If we are given a FID then look up the entry by that, otherwise
7601 if( GetStatusInfo->FileID.Cell != 0 &&
7602 GetStatusInfo->FileID.Volume != 0 &&
7603 GetStatusInfo->FileID.Vnode != 0 &&
7604 GetStatusInfo->FileID.Unique != 0)
7607 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7610 // Locate the volume node
7613 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7615 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7617 (AFSBTreeEntry **)&pVolumeCB);
7619 if( pVolumeCB != NULL)
7622 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7624 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7625 AFS_TRACE_LEVEL_VERBOSE,
7626 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7628 pVolumeCB->VolumeReferenceCount);
7631 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7633 if( !NT_SUCCESS( ntStatus) ||
7636 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7639 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
7642 pObjectInfo = &pVolumeCB->ObjectInformation;
7644 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7646 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7651 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
7654 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7656 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7657 AFS_TRACE_LEVEL_VERBOSE,
7658 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7660 pVolumeCB->VolumeReferenceCount);
7662 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
7664 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
7666 (AFSBTreeEntry **)&pObjectInfo);
7668 if( pObjectInfo != NULL)
7672 // Reference the node so it won't be torn down
7675 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7677 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7678 AFS_TRACE_LEVEL_VERBOSE,
7679 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
7681 pObjectInfo->ObjectReferenceCount);
7684 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
7686 if( !NT_SUCCESS( ntStatus) ||
7687 pObjectInfo == NULL)
7689 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7696 if( GetStatusInfo->FileNameLength == 0 ||
7697 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
7699 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7702 uniFullPathName.Length = GetStatusInfo->FileNameLength;
7703 uniFullPathName.MaximumLength = uniFullPathName.Length;
7705 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
7708 // This name should begin with the \afs server so parse it off and check it
7711 FsRtlDissectName( uniFullPathName,
7715 if( RtlCompareUnicodeString( &uniComponentName,
7719 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7720 AFS_TRACE_LEVEL_ERROR,
7721 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
7724 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
7727 uniFullPathName = uniRemainingPath;
7729 uniParsedName = uniFullPathName;
7735 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7738 if( pNameArray == NULL)
7740 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7743 pVolumeCB = AFSGlobalRoot;
7745 AFSAcquireShared( pVolumeCB->VolumeLock,
7748 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7751 // Increment the ref count on the volume and dir entry for correct processing below
7754 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7756 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7757 AFS_TRACE_LEVEL_VERBOSE,
7758 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7760 pVolumeCB->VolumeReferenceCount);
7762 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
7764 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7765 AFS_TRACE_LEVEL_VERBOSE,
7766 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7767 &pParentDirEntry->NameInformation.FileName,
7770 pParentDirEntry->OpenReferenceCount);
7772 ntStatus = AFSLocateNameEntry( NULL,
7777 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
7778 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
7784 if( !NT_SUCCESS( ntStatus))
7788 // The volume lock was released on failure above
7789 // Except for STATUS_OBJECT_NAME_NOT_FOUND
7792 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
7795 if( pVolumeCB != NULL)
7798 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7800 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7801 AFS_TRACE_LEVEL_VERBOSE,
7802 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7804 pVolumeCB->VolumeReferenceCount);
7806 AFSReleaseResource( pVolumeCB->VolumeLock);
7809 if( pDirectoryEntry != NULL)
7812 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7814 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7815 AFS_TRACE_LEVEL_VERBOSE,
7816 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7817 &pDirectoryEntry->NameInformation.FileName,
7820 pDirectoryEntry->OpenReferenceCount);
7825 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
7827 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7828 AFS_TRACE_LEVEL_VERBOSE,
7829 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7830 &pParentDirEntry->NameInformation.FileName,
7833 pParentDirEntry->OpenReferenceCount);
7839 try_return( ntStatus);
7843 // Remove the reference made above
7846 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7848 pObjectInfo = pDirectoryEntry->ObjectInformation;
7850 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7852 if( pVolumeCB != NULL)
7855 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7857 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7858 AFS_TRACE_LEVEL_VERBOSE,
7859 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
7861 pVolumeCB->VolumeReferenceCount);
7863 AFSReleaseResource( pVolumeCB->VolumeLock);
7868 // At this point we have an object info block, return the information
7871 StatusInfo->FileId = pObjectInfo->FileId;
7873 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
7875 StatusInfo->Expiration = pObjectInfo->Expiration;
7877 StatusInfo->DataVersion = pObjectInfo->DataVersion;
7879 StatusInfo->FileType = pObjectInfo->FileType;
7881 StatusInfo->ObjectFlags = pObjectInfo->Flags;
7883 StatusInfo->CreationTime = pObjectInfo->CreationTime;
7885 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
7887 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
7889 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
7891 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
7893 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
7895 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
7897 StatusInfo->EaSize = pObjectInfo->EaSize;
7899 StatusInfo->Links = pObjectInfo->Links;
7902 // Return the information length
7905 *ReturnLength = sizeof( AFSStatusInfoCB);
7909 if( pObjectInfo != NULL)
7912 InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
7915 if( pNameArray != NULL)
7918 AFSFreeNameArray( pNameArray);
7926 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
7927 IN UNICODE_STRING *ComponentName)
7930 NTSTATUS ntStatus = STATUS_SUCCESS;
7931 AFSDirectoryCB *pDirEntry = NULL;
7938 // Search for the entry in the parent
7941 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7942 AFS_TRACE_LEVEL_VERBOSE_2,
7943 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
7946 ulCRC = AFSGenerateCRC( ComponentName,
7949 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7952 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7956 if( pDirEntry == NULL)
7960 // Missed so perform a case insensitive lookup
7963 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7964 AFS_TRACE_LEVEL_VERBOSE_2,
7965 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
7968 ulCRC = AFSGenerateCRC( ComponentName,
7971 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7975 if( pDirEntry == NULL)
7979 // OK, if this component is a valid short name then try
7980 // a lookup in the short name tree
7983 if( RtlIsNameLegalDOS8Dot3( ComponentName,
7988 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7989 AFS_TRACE_LEVEL_VERBOSE_2,
7990 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
7993 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8000 if( pDirEntry != NULL)
8002 InterlockedIncrement( &pDirEntry->OpenReferenceCount);
8005 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8007 if( pDirEntry == NULL)
8010 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8011 AFS_TRACE_LEVEL_VERBOSE_2,
8012 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
8015 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8019 // We have the symlink object but previously failed to process it so return access
8023 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8024 AFS_TRACE_LEVEL_VERBOSE_2,
8025 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ ACCESS_DENIED\n",
8028 ntStatus = STATUS_ACCESS_DENIED;
8030 InterlockedDecrement( &pDirEntry->OpenReferenceCount);
8041 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8042 OUT UNICODE_STRING *ComponentName)
8045 NTSTATUS ntStatus = STATUS_SUCCESS;
8046 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8048 uniFullPathName = *FullPathName;
8053 FsRtlDissectName( uniFullPathName,
8057 if( uniRemainingPath.Length == 0)
8062 uniFullPathName = uniRemainingPath;
8065 if( uniComponentName.Length > 0)
8067 *ComponentName = uniComponentName;
8074 AFSDumpTraceFiles_Default()
8080 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8083 BOOLEAN bIsValidName = TRUE;
8089 while( usIndex < FileName->Length/sizeof( WCHAR))
8092 if( FileName->Buffer[ usIndex] == L':' ||
8093 FileName->Buffer[ usIndex] == L'*' ||
8094 FileName->Buffer[ usIndex] == L'?' ||
8095 FileName->Buffer[ usIndex] == L'"' ||
8096 FileName->Buffer[ usIndex] == L'<' ||
8097 FileName->Buffer[ usIndex] == L'>')
8099 bIsValidName = FALSE;
8107 return bIsValidName;
8111 AFSCreateDefaultSecurityDescriptor()
8114 NTSTATUS ntStatus = STATUS_SUCCESS;
8116 ULONG ulSACLSize = 0;
8117 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8118 ULONG ulACESize = 0;
8119 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8120 ULONG ulSDLength = 0;
8121 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8122 PSID pWorldSID = NULL;
8123 ULONG *pulSubAuthority = NULL;
8124 ULONG ulWorldSIDLEngth = 0;
8129 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8131 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8133 AFS_GENERIC_MEMORY_29_TAG);
8135 if( pWorldSID == NULL)
8137 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8138 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8141 RtlZeroMemory( pWorldSID,
8144 RtlInitializeSid( pWorldSID,
8145 &SeWorldSidAuthority,
8148 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8149 *pulSubAuthority = SECURITY_WORLD_RID;
8151 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8154 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8159 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8161 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8163 AFS_GENERIC_MEMORY_29_TAG);
8168 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8170 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8173 RtlZeroMemory( pACE,
8176 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8177 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8178 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8179 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8181 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8183 SeExports->SeLowMandatorySid);
8185 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8186 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8188 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8190 AFS_GENERIC_MEMORY_29_TAG);
8195 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8197 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8200 ntStatus = RtlCreateAcl( pSACL,
8204 if( !NT_SUCCESS( ntStatus))
8207 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8210 try_return( ntStatus);
8213 ntStatus = RtlAddAce( pSACL,
8217 pACE->Header.AceSize);
8219 if( !NT_SUCCESS( ntStatus))
8222 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8225 try_return( ntStatus);
8229 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8230 sizeof( SECURITY_DESCRIPTOR),
8231 AFS_GENERIC_MEMORY_27_TAG);
8233 if( pSecurityDescr == NULL)
8236 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8238 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8241 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8242 SECURITY_DESCRIPTOR_REVISION);
8244 if( !NT_SUCCESS( ntStatus))
8247 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8250 try_return( ntStatus);
8253 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8255 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8260 if( !NT_SUCCESS( ntStatus))
8263 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8266 try_return( ntStatus);
8271 // Add in the group and owner to the SD
8274 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8276 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8280 if( !NT_SUCCESS( ntStatus))
8283 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8286 try_return( ntStatus);
8290 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8294 if( !NT_SUCCESS( ntStatus))
8297 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8300 try_return( ntStatus);
8303 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8306 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8308 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8311 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8313 AFS_GENERIC_MEMORY_27_TAG);
8315 if( pRelativeSecurityDescr == NULL)
8318 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8320 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8323 ulSDLength = PAGE_SIZE;
8325 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8326 pRelativeSecurityDescr,
8329 if( !NT_SUCCESS( ntStatus))
8332 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8335 try_return( ntStatus);
8338 AFSDefaultSD = pRelativeSecurityDescr;
8342 if( !NT_SUCCESS( ntStatus))
8345 if( pRelativeSecurityDescr != NULL)
8347 ExFreePool( pRelativeSecurityDescr);
8351 if( pSecurityDescr != NULL)
8353 ExFreePool( pSecurityDescr);
8366 if( pWorldSID != NULL)
8368 ExFreePool( pWorldSID);
8376 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8377 OUT UNICODE_STRING *ParentPath)
8382 *ParentPath = *FullFileName;
8385 // If the final character is a \, jump over it
8388 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8390 ParentPath->Length -= sizeof( WCHAR);
8393 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8395 ParentPath->Length -= sizeof( WCHAR);
8399 // And the separator
8402 ParentPath->Length -= sizeof( WCHAR);
8408 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8409 IN AFSObjectInfoCB *ObjectInfo,
8410 IN BOOLEAN WriteAccess,
8411 OUT GUID *AuthGroup)
8414 NTSTATUS ntStatus = STATUS_SUCCESS;
8415 GUID stAuthGroup, stZeroAuthGroup;
8416 BOOLEAN bFoundAuthGroup = FALSE;
8417 AFSCcb *pCcb = NULL;
8423 RtlZeroMemory( &stAuthGroup,
8426 RtlZeroMemory( &stZeroAuthGroup,
8432 if( ObjectInfo != NULL &&
8433 ObjectInfo->Fcb != NULL)
8435 pFcb = ObjectInfo->Fcb;
8442 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8445 pCcb = Fcb->CcbListHead;
8447 while( pCcb != NULL)
8451 pCcb->GrantedAccess & FILE_WRITE_DATA)
8453 RtlCopyMemory( &stAuthGroup,
8457 bFoundAuthGroup = TRUE;
8461 else if( pCcb->GrantedAccess != 0)
8464 // At least get the read-only access
8467 RtlCopyMemory( &stAuthGroup,
8471 bFoundAuthGroup = TRUE;
8474 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
8477 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
8480 if( !bFoundAuthGroup)
8483 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
8484 (ULONGLONG)PsGetCurrentThreadId(),
8487 if( RtlCompareMemory( &stZeroAuthGroup,
8489 sizeof( GUID)) == sizeof( GUID))
8492 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
8494 try_return( ntStatus = STATUS_ACCESS_DENIED);
8498 RtlCopyMemory( AuthGroup,