2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSGeneric.cpp
39 #include "AFSCommon.h"
42 // Function: AFSExceptionFilter
46 // This function is the exception handler
50 // A status is returned for the function
54 AFSExceptionFilter( IN ULONG Code,
55 IN PEXCEPTION_POINTERS ExceptPtrs)
58 PEXCEPTION_RECORD ExceptRec;
64 ExceptRec = ExceptPtrs->ExceptionRecord;
66 Context = ExceptPtrs->ContextRecord;
70 "AFSExceptionFilter (Library) - EXR %p CXR %p Code %08lX Address %p Routine %p\n",
73 ExceptRec->ExceptionCode,
74 ExceptRec->ExceptionAddress,
75 (void *)AFSExceptionFilter);
77 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
79 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
80 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
82 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
84 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
87 KeBugCheck( (ULONG)-2);
95 __except( EXCEPTION_EXECUTE_HANDLER)
101 return EXCEPTION_EXECUTE_HANDLER;
105 // Function: AFSLibExAllocatePoolWithTag()
107 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
108 // is configured on, then bugcheck the system if
109 // a memory allocation fails. The routine should be
110 // used for all memory allocations that are to be freed
111 // when the library is unloaded. Memory allocations that
112 // are to survive library unload and reload should be
113 // performed using AFSExAllocatePoolWithTag() which is
114 // provided by the AFS Framework.
117 // POOL_TYPE PoolType - Paged or NonPaged
118 // SIZE_T NumberOfBytes - requested allocation size
119 // ULONG Tag - Pool Allocation Tag to be applied for tracking
122 // void * - the memory allocation
126 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
127 IN SIZE_T NumberOfBytes,
131 void *pBuffer = NULL;
133 pBuffer = ExAllocatePoolWithTag( PoolType,
140 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
143 KeBugCheck( (ULONG)-2);
150 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
154 PsGetCurrentThread());
164 // Function: AFSAcquireExcl()
166 // Purpose: Called to acquire a resource exclusive with optional wait
169 // PERESOURCE Resource - Resource to acquire
170 // BOOLEAN Wait - Whether to block
173 // BOOLEAN - Whether the mask was acquired
177 AFSAcquireExcl( IN PERESOURCE Resource,
181 BOOLEAN bStatus = FALSE;
184 // Normal kernel APCs must be disabled before calling
185 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
188 KeEnterCriticalRegion();
190 bStatus = ExAcquireResourceExclusiveLite( Resource,
196 KeLeaveCriticalRegion();
203 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
207 BOOLEAN bStatus = FALSE;
209 KeEnterCriticalRegion();
211 bStatus = ExAcquireSharedStarveExclusive( Resource,
217 KeLeaveCriticalRegion();
224 // Function: AFSAcquireShared()
226 // Purpose: Called to acquire a resource shared with optional wait
229 // PERESOURCE Resource - Resource to acquire
230 // BOOLEAN Wait - Whether to block
233 // BOOLEAN - Whether the mask was acquired
237 AFSAcquireShared( IN PERESOURCE Resource,
241 BOOLEAN bStatus = FALSE;
243 KeEnterCriticalRegion();
245 bStatus = ExAcquireResourceSharedLite( Resource,
251 KeLeaveCriticalRegion();
258 // Function: AFSReleaseResource()
260 // Purpose: Called to release a resource
263 // PERESOURCE Resource - Resource to release
270 AFSReleaseResource( IN PERESOURCE Resource)
273 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
274 AFS_TRACE_LEVEL_VERBOSE,
275 "AFSReleaseResource Releasing lock %08lX Thread %08lX\n",
277 PsGetCurrentThread());
279 ExReleaseResourceLite( Resource);
281 KeLeaveCriticalRegion();
287 AFSConvertToShared( IN PERESOURCE Resource)
290 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
291 AFS_TRACE_LEVEL_VERBOSE,
292 "AFSConvertToShared Converting lock %08lX Thread %08lX\n",
294 PsGetCurrentThread());
296 ExConvertExclusiveToSharedLite( Resource);
302 // Function: AFSCompleteRequest
306 // This function completes irps
310 // A status is returned for the function
314 AFSCompleteRequest( IN PIRP Irp,
318 Irp->IoStatus.Status = Status;
320 IoCompleteRequest( Irp,
327 // Function: AFSGenerateCRC
331 // Given a device and filename this function generates a CRC
335 // A status is returned for the function
339 AFSGenerateCRC( IN PUNICODE_STRING FileName,
340 IN BOOLEAN UpperCaseName)
344 NTSTATUS ntStatus = STATUS_SUCCESS;
346 ntStatus = RtlHashUnicodeString( FileName,
348 HASH_STRING_ALGORITHM_DEFAULT,
351 if( !NT_SUCCESS( ntStatus))
360 AFSLockSystemBuffer( IN PIRP Irp,
364 NTSTATUS Status = STATUS_SUCCESS;
365 void *pAddress = NULL;
367 if( Irp->MdlAddress != NULL)
370 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
373 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
376 pAddress = Irp->AssociatedIrp.SystemBuffer;
378 else if( Irp->UserBuffer != NULL)
381 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
387 if( Irp->MdlAddress != NULL)
391 // Lock the new Mdl in memory.
396 PIO_STACK_LOCATION pIoStack;
397 pIoStack = IoGetCurrentIrpStackLocation( Irp);
400 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
401 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
403 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
406 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
409 IoFreeMdl( Irp->MdlAddress );
410 Irp->MdlAddress = NULL;
420 AFSLockUserBuffer( IN void *UserBuffer,
421 IN ULONG BufferLength,
425 NTSTATUS ntStatus = STATUS_SUCCESS;
426 void *pAddress = NULL;
432 pMdl = IoAllocateMdl( UserBuffer,
441 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
445 // Lock the new Mdl in memory.
451 MmProbeAndLockPages( pMdl,
455 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
458 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
481 AFSMapToService( IN PIRP Irp,
485 NTSTATUS ntStatus = STATUS_SUCCESS;
486 void *pMappedBuffer = NULL;
487 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
493 if( pDevExt->Specific.Control.ServiceProcess == NULL)
496 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
499 if( Irp->MdlAddress == NULL)
502 if( AFSLockSystemBuffer( Irp,
506 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
511 // Attach to the service process for mapping
514 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
515 (PRKAPC_STATE)&stApcState);
517 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
524 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
531 return pMappedBuffer;
535 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
539 NTSTATUS ntStatus = STATUS_SUCCESS;
540 void *pMappedBuffer = NULL;
541 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
547 if( pDevExt->Specific.Control.ServiceProcess == NULL)
550 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
557 // Attach to the service process for mapping
560 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
561 (PRKAPC_STATE)&stApcState);
563 MmUnmapLockedPages( MappedBuffer,
566 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
578 AFSInitializeLibraryDevice()
581 NTSTATUS ntStatus = STATUS_SUCCESS;
582 AFSDeviceExt *pDeviceExt = NULL;
587 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
590 // The PIOCtl file name
593 RtlInitUnicodeString( &AFSPIOCtlName,
594 AFS_PIOCTL_FILE_INTERFACE_NAME);
597 // And the global root share name
600 RtlInitUnicodeString( &AFSGlobalRootName,
601 AFS_GLOBAL_ROOT_SHARE_NAME);
609 AFSRemoveLibraryDevice()
612 NTSTATUS ntStatus = STATUS_SUCCESS;
623 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
627 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
628 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
630 AFSCompleteRequest( Irp,
637 AFSInitializeGlobalDirectoryEntries()
640 NTSTATUS ntStatus = STATUS_SUCCESS;
641 AFSDirectoryCB *pDirNode = NULL;
642 ULONG ulEntryLength = 0;
643 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
644 AFSObjectInfoCB *pObjectInfoCB = NULL;
645 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
652 // Initialize the global . entry
655 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
658 if( pObjectInfoCB == NULL)
661 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
662 AFS_TRACE_LEVEL_ERROR,
663 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
666 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
669 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
671 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
672 AFS_TRACE_LEVEL_VERBOSE,
673 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
677 ntStatus = STATUS_SUCCESS;
679 ulEntryLength = sizeof( AFSDirectoryCB) +
682 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
686 if( pDirNode == NULL)
689 AFSDeleteObjectInfo( pObjectInfoCB);
691 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
692 AFS_TRACE_LEVEL_ERROR,
693 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
695 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
698 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
699 sizeof( AFSNonPagedDirectoryCB),
700 AFS_DIR_ENTRY_NP_TAG);
702 if( pNonPagedDirEntry == NULL)
705 ExFreePool( pDirNode);
707 AFSDeleteObjectInfo( pObjectInfoCB);
709 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
710 AFS_TRACE_LEVEL_ERROR,
711 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
713 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
716 RtlZeroMemory( pDirNode,
719 RtlZeroMemory( pNonPagedDirEntry,
720 sizeof( AFSNonPagedDirectoryCB));
722 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
724 pDirNode->NonPaged = pNonPagedDirEntry;
726 pDirNode->ObjectInformation = pObjectInfoCB;
732 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
734 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
737 // Setup the names in the entry
740 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
742 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
744 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
746 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
749 // Populate the rest of the data
752 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
754 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
756 AFSGlobalDotDirEntry = pDirNode;
762 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
765 if( pObjectInfoCB == NULL)
768 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
769 AFS_TRACE_LEVEL_ERROR,
770 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
773 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
776 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
778 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
779 AFS_TRACE_LEVEL_VERBOSE,
780 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
784 ntStatus = STATUS_SUCCESS;
786 ulEntryLength = sizeof( AFSDirectoryCB) +
787 ( 2 * sizeof( WCHAR));
789 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
793 if( pDirNode == NULL)
796 AFSDeleteObjectInfo( pObjectInfoCB);
798 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
801 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
802 sizeof( AFSNonPagedDirectoryCB),
803 AFS_DIR_ENTRY_NP_TAG);
805 if( pNonPagedDirEntry == NULL)
808 ExFreePool( pDirNode);
810 AFSDeleteObjectInfo( pObjectInfoCB);
812 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
815 RtlZeroMemory( pDirNode,
818 RtlZeroMemory( pNonPagedDirEntry,
819 sizeof( AFSNonPagedDirectoryCB));
821 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
823 pDirNode->NonPaged = pNonPagedDirEntry;
825 pDirNode->ObjectInformation = pObjectInfoCB;
831 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
833 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
836 // Setup the names in the entry
839 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
841 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
843 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
845 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
847 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
850 // Populate the rest of the data
853 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
855 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
857 AFSGlobalDotDotDirEntry = pDirNode;
861 if( !NT_SUCCESS( ntStatus))
864 if( AFSGlobalDotDirEntry != NULL)
867 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
869 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
871 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
873 ExFreePool( AFSGlobalDotDirEntry);
875 AFSGlobalDotDirEntry = NULL;
878 if( AFSGlobalDotDotDirEntry != NULL)
881 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
883 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
885 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
887 ExFreePool( AFSGlobalDotDotDirEntry);
889 AFSGlobalDotDotDirEntry = NULL;
898 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
899 IN PUNICODE_STRING FileName,
900 IN PUNICODE_STRING TargetName,
901 IN AFSDirEnumEntry *DirEnumEntry,
905 AFSDirectoryCB *pDirNode = NULL;
906 NTSTATUS ntStatus = STATUS_SUCCESS;
907 ULONG ulEntryLength = 0;
908 AFSDirEnumEntry *pDirEnumCB = NULL;
909 AFSFileID stTargetFileID;
911 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
912 AFSObjectInfoCB *pObjectInfoCB = NULL;
913 BOOLEAN bAllocatedObjectCB = FALSE;
914 ULONGLONG ullIndex = 0;
915 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
921 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
922 AFS_TRACE_LEVEL_VERBOSE,
923 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
925 ParentObjectInfo->FileId.Cell,
926 ParentObjectInfo->FileId.Volume,
927 ParentObjectInfo->FileId.Vnode,
928 ParentObjectInfo->FileId.Unique);
931 // First thing is to locate/create our object information block
935 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
938 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
940 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
942 (AFSBTreeEntry **)&pObjectInfoCB);
944 if( !NT_SUCCESS( ntStatus) ||
945 pObjectInfoCB == NULL)
949 // Allocate our object info cb
952 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
955 if( pObjectInfoCB == NULL)
958 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
960 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
963 bAllocatedObjectCB = TRUE;
965 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
966 AFS_TRACE_LEVEL_VERBOSE,
967 "AFSInitDirEntry initialized object %08lX Parent Object %08lX for %wZ\n",
973 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
975 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
976 AFS_TRACE_LEVEL_VERBOSE,
977 "AFSInitDirEntry Increment count on object %08lX Cnt %d\n",
981 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
983 ntStatus = STATUS_SUCCESS;
985 ulEntryLength = sizeof( AFSDirectoryCB) +
988 if( TargetName != NULL)
991 ulEntryLength += TargetName->Length;
994 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
998 if( pDirNode == NULL)
1001 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1004 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1005 sizeof( AFSNonPagedDirectoryCB),
1006 AFS_DIR_ENTRY_NP_TAG);
1008 if( pNonPagedDirEntry == NULL)
1011 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1014 RtlZeroMemory( pDirNode,
1017 RtlZeroMemory( pNonPagedDirEntry,
1018 sizeof( AFSNonPagedDirectoryCB));
1020 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1022 pDirNode->NonPaged = pNonPagedDirEntry;
1024 pDirNode->ObjectInformation = pObjectInfoCB;
1027 // Set valid entry and NOT_IN_PARENT flag
1030 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1032 pDirNode->FileIndex = FileIndex;
1035 // Setup the names in the entry
1038 if( FileName->Length > 0)
1041 pDirNode->NameInformation.FileName.Length = FileName->Length;
1043 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1045 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1047 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1049 pDirNode->NameInformation.FileName.Length);
1052 // Create a CRC for the file
1055 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1058 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1062 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1063 AFS_TRACE_LEVEL_VERBOSE,
1064 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1067 ParentObjectInfo->FileId.Cell,
1068 ParentObjectInfo->FileId.Volume,
1069 ParentObjectInfo->FileId.Vnode,
1070 ParentObjectInfo->FileId.Unique);
1072 if( TargetName != NULL &&
1073 TargetName->Length > 0)
1076 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1078 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1080 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1081 sizeof( AFSDirectoryCB) +
1082 pDirNode->NameInformation.FileName.Length);
1084 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1086 pDirNode->NameInformation.TargetName.Length);
1090 // If we allocated the object information cb then update the information
1093 if( bAllocatedObjectCB)
1097 // Populate the rest of the data
1100 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1102 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1104 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1106 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1108 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1110 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1112 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1114 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1116 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1118 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1120 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1123 pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1126 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1127 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1130 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1133 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1136 // Object specific information
1139 pObjectInfoCB->Links = DirEnumEntry->Links;
1141 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1143 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1146 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1147 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1151 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1152 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1153 pObjectInfoCB->TargetFileId.Unique == 0 &&
1154 pDirNode->NameInformation.TargetName.Length == 0)
1158 // This will ensure we perform a validation on the node
1161 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1164 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1167 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1173 if( !NT_SUCCESS( ntStatus))
1176 if( pNonPagedDirEntry != NULL)
1179 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1181 AFSExFreePool( pNonPagedDirEntry);
1184 if( pDirNode != NULL)
1187 AFSExFreePool( pDirNode);
1193 // Dereference our object info block if we have one
1196 if( pObjectInfoCB != NULL)
1199 lCount = InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
1201 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1202 AFS_TRACE_LEVEL_VERBOSE,
1203 "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
1207 if( bAllocatedObjectCB)
1210 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1212 AFSDeleteObjectInfo( pObjectInfoCB);
1222 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1223 IN BOOLEAN DirectoryEntry)
1226 BOOLEAN bReturn = TRUE;
1227 ACCESS_MASK stAccessMask = 0;
1230 // Get rid of anything we don't know about
1233 DesiredAccess = (DesiredAccess &
1239 ACCESS_SYSTEM_SECURITY |
1243 FILE_READ_ATTRIBUTES |
1244 FILE_WRITE_ATTRIBUTES |
1245 FILE_LIST_DIRECTORY |
1251 // Our 'read only' access mask. These are the accesses we will
1252 // allow for a read only file
1255 stAccessMask = DELETE |
1260 ACCESS_SYSTEM_SECURITY |
1264 FILE_READ_ATTRIBUTES |
1265 FILE_WRITE_ATTRIBUTES |
1267 FILE_LIST_DIRECTORY |
1271 // For a directory, add in the directory specific accesses
1277 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1282 if( FlagOn( DesiredAccess, ~stAccessMask))
1286 // A write access is set ...
1296 AFSEvaluateNode( IN GUID *AuthGroup,
1297 IN AFSDirectoryCB *DirEntry)
1300 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1301 NTSTATUS ntStatus = STATUS_SUCCESS;
1302 AFSDirEnumEntry *pDirEntry = NULL;
1303 UNICODE_STRING uniTargetName;
1308 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1313 if( !NT_SUCCESS( ntStatus))
1316 try_return( ntStatus);
1319 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1321 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1323 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1325 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1327 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1329 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1331 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1333 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1335 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1337 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1339 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1341 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1344 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1347 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1348 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1351 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1354 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1356 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1359 // If we have a target name then see if it needs updating ...
1362 if( pDirEntry->TargetNameLength > 0)
1366 // Update the target name information if needed
1369 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1371 uniTargetName.MaximumLength = uniTargetName.Length;
1373 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1375 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1378 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1379 RtlCompareUnicodeString( &uniTargetName,
1380 &DirEntry->NameInformation.TargetName,
1385 // Update the target name
1388 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1390 uniTargetName.Buffer,
1391 uniTargetName.Length);
1393 if( !NT_SUCCESS( ntStatus))
1396 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1398 try_return( ntStatus);
1402 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1407 if( pDirEntry != NULL)
1410 AFSExFreePool( pDirEntry);
1418 AFSValidateSymLink( IN GUID *AuthGroup,
1419 IN AFSDirectoryCB *DirEntry)
1422 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1423 NTSTATUS ntStatus = STATUS_SUCCESS;
1424 AFSDirEnumEntry *pDirEntry = NULL;
1425 UNICODE_STRING uniTargetName;
1430 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1435 if( !NT_SUCCESS( ntStatus))
1438 try_return( ntStatus);
1441 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1442 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1445 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1448 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1450 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1452 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1455 // Update the target name information if needed
1458 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1460 uniTargetName.MaximumLength = uniTargetName.Length;
1462 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1464 if( uniTargetName.Length > 0)
1467 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1470 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1471 RtlCompareUnicodeString( &uniTargetName,
1472 &DirEntry->NameInformation.TargetName,
1477 // Update the target name
1480 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1482 uniTargetName.Buffer,
1483 uniTargetName.Length);
1485 if( !NT_SUCCESS( ntStatus))
1488 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1490 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1494 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1498 // If the FileType is the same then nothing to do since it IS
1502 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1505 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1507 try_return( ntStatus = STATUS_SUCCESS);
1510 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1512 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1514 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1516 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1518 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1520 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1522 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1524 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1526 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1529 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1532 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1533 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1536 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1539 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1541 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1545 if( pDirEntry != NULL)
1548 AFSExFreePool( pDirEntry);
1556 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1559 NTSTATUS ntStatus = STATUS_SUCCESS;
1560 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1561 AFSVolumeCB *pVolumeCB = NULL;
1562 AFSFcb *pTargetDcb = NULL;
1563 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1564 AFSDirectoryCB *pCurrentDirEntry = NULL;
1565 BOOLEAN bIsChild = FALSE;
1566 ULONGLONG ullIndex = 0;
1567 AFSObjectInfoCB *pObjectInfo = NULL;
1568 IO_STATUS_BLOCK stIoStatus;
1576 // Need to locate the Fcb for the directory to purge
1579 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1580 AFS_TRACE_LEVEL_VERBOSE,
1581 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1582 &pDevExt->Specific.RDR.VolumeTreeLock,
1583 PsGetCurrentThread());
1586 // Starve any exclusive waiters on this paticular call
1589 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1592 // Locate the volume node
1595 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1597 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1599 (AFSBTreeEntry **)&pVolumeCB);
1601 if( pVolumeCB != NULL)
1604 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1606 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1607 AFS_TRACE_LEVEL_VERBOSE,
1608 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1613 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1615 if( !NT_SUCCESS( ntStatus) ||
1618 try_return( ntStatus = STATUS_SUCCESS);
1622 // If this is a whole volume invalidation then go do it now
1625 if( InvalidateCB->WholeVolume ||
1626 AFSIsVolumeFID( &InvalidateCB->FileID))
1629 ntStatus = AFSInvalidateVolume( pVolumeCB,
1630 InvalidateCB->Reason);
1632 AFSFsRtlNotifyFullReportChange( &pVolumeCB->ObjectInformation,
1634 FILE_NOTIFY_CHANGE_FILE_NAME |
1635 FILE_NOTIFY_CHANGE_DIR_NAME |
1636 FILE_NOTIFY_CHANGE_NAME |
1637 FILE_NOTIFY_CHANGE_ATTRIBUTES |
1638 FILE_NOTIFY_CHANGE_SIZE,
1639 FILE_ACTION_MODIFIED);
1641 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1643 try_return( ntStatus);
1646 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1649 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1651 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1652 AFS_TRACE_LEVEL_VERBOSE,
1653 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
1655 pVolumeCB->VolumeReferenceCount);
1657 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
1659 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
1661 (AFSBTreeEntry **)&pObjectInfo);
1663 if( pObjectInfo != NULL)
1667 // Reference the node so it won't be torn down
1670 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
1672 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1673 AFS_TRACE_LEVEL_VERBOSE,
1674 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
1679 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1681 if( !NT_SUCCESS( ntStatus) ||
1682 pObjectInfo == NULL)
1684 try_return( ntStatus = STATUS_SUCCESS);
1687 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
1688 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK ||
1689 pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1692 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1693 AFS_TRACE_LEVEL_VERBOSE,
1694 "AFSInvalidateCache Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1695 pObjectInfo->FileType,
1696 pObjectInfo->FileId.Cell,
1697 pObjectInfo->FileId.Volume,
1698 pObjectInfo->FileId.Vnode,
1699 pObjectInfo->FileId.Unique,
1700 InvalidateCB->Reason);
1703 // We only act on the mount point itself, not the target. If the
1704 // node has been deleted then mark it as such otherwise indicate
1705 // it requires verification
1708 if( InvalidateCB->Reason == AFS_INVALIDATE_DELETED)
1710 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1715 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED)
1718 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1720 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1723 pObjectInfo->Expiration.QuadPart = 0;
1725 pObjectInfo->TargetFileId.Vnode = 0;
1727 pObjectInfo->TargetFileId.Unique = 0;
1729 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1730 AFS_TRACE_LEVEL_VERBOSE,
1731 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1732 pObjectInfo->FileId.Cell,
1733 pObjectInfo->FileId.Volume,
1734 pObjectInfo->FileId.Vnode,
1735 pObjectInfo->FileId.Unique);
1737 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1740 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1742 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1744 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1747 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION ||
1748 InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED)
1750 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1754 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1757 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1759 FILE_NOTIFY_CHANGE_FILE_NAME |
1760 FILE_NOTIFY_CHANGE_ATTRIBUTES,
1761 FILE_ACTION_MODIFIED);
1763 try_return( ntStatus);
1767 // Depending on the reason for invalidation then perform work on the node
1770 switch( InvalidateCB->Reason)
1773 case AFS_INVALIDATE_DELETED:
1777 // Mark this node as invalid
1780 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
1782 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1783 AFS_TRACE_LEVEL_VERBOSE,
1784 "AFSInvalidateCache Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1785 pObjectInfo->FileId.Cell,
1786 pObjectInfo->FileId.Volume,
1787 pObjectInfo->FileId.Vnode,
1788 pObjectInfo->FileId.Unique);
1790 if( pObjectInfo->ParentObjectInformation != NULL)
1793 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1794 AFS_TRACE_LEVEL_VERBOSE,
1795 "AFSInvalidateCache Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1796 pObjectInfo->ParentObjectInformation->FileId.Cell,
1797 pObjectInfo->ParentObjectInformation->FileId.Volume,
1798 pObjectInfo->ParentObjectInformation->FileId.Vnode,
1799 pObjectInfo->ParentObjectInformation->FileId.Unique);
1801 SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1803 pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1805 pObjectInfo->ParentObjectInformation->Expiration.QuadPart = 0;
1808 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1810 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1814 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1817 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1820 FILE_ACTION_REMOVED);
1822 if( NT_SUCCESS( AFSQueueInvalidateObject( pObjectInfo,
1823 InvalidateCB->Reason)))
1825 pObjectInfo = NULL; // We'll dec the count in the worker item
1831 case AFS_INVALIDATE_FLUSHED:
1834 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
1835 pObjectInfo->Fcb != NULL)
1838 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1839 AFS_TRACE_LEVEL_VERBOSE,
1840 "AFSInvalidateCache Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1841 pObjectInfo->FileId.Cell,
1842 pObjectInfo->FileId.Volume,
1843 pObjectInfo->FileId.Vnode,
1844 pObjectInfo->FileId.Unique);
1846 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
1852 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1857 if( !NT_SUCCESS( stIoStatus.Status))
1860 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1861 AFS_TRACE_LEVEL_ERROR,
1862 "AFSInvalidateCache CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1863 pObjectInfo->FileId.Cell,
1864 pObjectInfo->FileId.Volume,
1865 pObjectInfo->FileId.Vnode,
1866 pObjectInfo->FileId.Unique,
1868 stIoStatus.Information);
1870 ntStatus = stIoStatus.Status;
1873 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1878 __except( EXCEPTION_EXECUTE_HANDLER)
1881 ntStatus = GetExceptionCode();
1884 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
1887 // Clear out the extents
1888 // Get rid of them (note this involves waiting
1889 // for any writes or reads to the cache to complete)
1892 (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb,
1896 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1899 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
1902 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1903 AFS_TRACE_LEVEL_VERBOSE,
1904 "AFSInvalidateCache Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1905 pObjectInfo->FileId.Cell,
1906 pObjectInfo->FileId.Volume,
1907 pObjectInfo->FileId.Vnode,
1908 pObjectInfo->FileId.Unique);
1910 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1913 // Fall through to the default processing
1919 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1921 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1925 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1928 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1930 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1933 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1935 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1939 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1942 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1945 FILE_ACTION_MODIFIED);
1948 // Indicate this node requires re-evaluation for the remaining reasons
1951 pObjectInfo->Expiration.QuadPart = 0;
1953 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1954 AFS_TRACE_LEVEL_VERBOSE,
1955 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1956 pObjectInfo->FileId.Cell,
1957 pObjectInfo->FileId.Volume,
1958 pObjectInfo->FileId.Vnode,
1959 pObjectInfo->FileId.Unique);
1961 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1963 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION &&
1964 NT_SUCCESS( AFSQueueInvalidateObject( pObjectInfo,
1965 InvalidateCB->Reason)))
1967 pObjectInfo = NULL; // We'll dec the count in the worker item
1976 if( pObjectInfo != NULL)
1979 lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
1981 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1982 AFS_TRACE_LEVEL_VERBOSE,
1983 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
1993 AFSIsChildOfParent( IN AFSFcb *Dcb,
1997 BOOLEAN bIsChild = FALSE;
1998 AFSFcb *pCurrentFcb = Fcb;
2000 while( pCurrentFcb != NULL)
2003 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2011 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2019 AFSCreateHighIndex( IN AFSFileID *FileID)
2022 ULONGLONG ullIndex = 0;
2024 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2031 AFSCreateLowIndex( IN AFSFileID *FileID)
2034 ULONGLONG ullIndex = 0;
2036 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2042 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2043 IN ACCESS_MASK GrantedAccess,
2044 IN BOOLEAN DirectoryEntry)
2047 BOOLEAN bAccessGranted = TRUE;
2050 // Check if we are asking for read/write and granted only read only
2051 // NOTE: There will be more checks here
2054 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2056 AFSCheckForReadOnlyAccess( GrantedAccess,
2060 bAccessGranted = FALSE;
2063 return bAccessGranted;
2067 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2070 NTSTATUS ntStatus = STATUS_SUCCESS;
2071 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2077 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2079 if( AFSGlobalRoot == NULL)
2086 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2089 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2096 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2103 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2104 IN UNICODE_STRING *SubstituteName,
2105 IN ULONG StringIndex)
2108 NTSTATUS ntStatus = STATUS_SUCCESS;
2109 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2110 AFSSysNameCB *pSysName = NULL;
2111 ERESOURCE *pSysNameLock = NULL;
2114 UNICODE_STRING uniSysName;
2121 if( IoIs32bitProcess( NULL))
2124 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2126 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2131 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2133 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2137 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2139 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2143 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2144 AFS_TRACE_LEVEL_VERBOSE,
2145 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2147 PsGetCurrentThread());
2149 AFSAcquireShared( pSysNameLock,
2153 // Find where we are in the list
2156 while( pSysName != NULL &&
2157 ulIndex < StringIndex)
2160 pSysName = pSysName->fLink;
2165 if( pSysName == NULL)
2168 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2171 RtlInitUnicodeString( &uniSysName,
2174 // If it is a full component of @SYS then just substitue the
2178 if( RtlCompareUnicodeString( &uniSysName,
2183 SubstituteName->Length = pSysName->SysName.Length;
2184 SubstituteName->MaximumLength = SubstituteName->Length;
2186 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2187 SubstituteName->Length,
2188 AFS_SUBST_BUFFER_TAG);
2190 if( SubstituteName->Buffer == NULL)
2193 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2196 RtlCopyMemory( SubstituteName->Buffer,
2197 pSysName->SysName.Buffer,
2198 pSysName->SysName.Length);
2205 while( ComponentName->Buffer[ usIndex] != L'@')
2211 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2212 SubstituteName->MaximumLength = SubstituteName->Length;
2214 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2215 SubstituteName->Length,
2216 AFS_SUBST_BUFFER_TAG);
2218 if( SubstituteName->Buffer == NULL)
2221 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2224 RtlCopyMemory( SubstituteName->Buffer,
2225 ComponentName->Buffer,
2226 usIndex * sizeof( WCHAR));
2228 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2229 pSysName->SysName.Buffer,
2230 pSysName->SysName.Length);
2235 AFSReleaseResource( pSysNameLock);
2242 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2243 IN OUT UNICODE_STRING *ComponentName,
2244 IN UNICODE_STRING *SubstituteName,
2245 IN OUT UNICODE_STRING *RemainingPath,
2246 IN BOOLEAN FreePathName)
2249 NTSTATUS ntStatus = STATUS_SUCCESS;
2250 UNICODE_STRING uniPathName;
2251 USHORT usPrefixNameLen = 0;
2252 SHORT sNameLenDelta = 0;
2258 // If the passed in name can handle the additional length
2259 // then just moves things around
2262 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2264 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2266 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2269 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2272 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2273 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2274 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2277 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2278 SubstituteName->Buffer,
2279 SubstituteName->Length);
2281 FullPathName->Length += sNameLenDelta;
2283 ComponentName->Length += sNameLenDelta;
2285 ComponentName->MaximumLength = ComponentName->Length;
2287 if ( RemainingPath->Buffer)
2290 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2293 try_return( ntStatus);
2297 // Need to re-allocate the buffer
2300 uniPathName.Length = FullPathName->Length -
2301 ComponentName->Length +
2302 SubstituteName->Length;
2304 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2306 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2307 uniPathName.MaximumLength,
2308 AFS_NAME_BUFFER_FOUR_TAG);
2310 if( uniPathName.Buffer == NULL)
2313 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2316 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2318 usPrefixNameLen *= sizeof( WCHAR);
2320 RtlZeroMemory( uniPathName.Buffer,
2321 uniPathName.MaximumLength);
2323 RtlCopyMemory( uniPathName.Buffer,
2324 FullPathName->Buffer,
2327 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2328 SubstituteName->Buffer,
2329 SubstituteName->Length);
2331 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2334 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2335 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2336 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2339 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2341 ComponentName->Length += sNameLenDelta;
2343 ComponentName->MaximumLength = ComponentName->Length;
2345 if ( RemainingPath->Buffer)
2348 RemainingPath->Buffer = uniPathName.Buffer
2349 + (RemainingPath->Buffer - FullPathName->Buffer)
2350 + sNameLenDelta/sizeof( WCHAR);
2355 AFSExFreePool( FullPathName->Buffer);
2358 *FullPathName = uniPathName;
2369 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2373 NTSTATUS ntStatus = STATUS_SUCCESS;
2374 AFSFcb *pFcb = NULL;
2375 AFSObjectInfoCB *pCurrentObject = NULL;
2381 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2382 AFS_TRACE_LEVEL_VERBOSE,
2383 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2384 VolumeCB->ObjectInformation.FileId.Cell,
2385 VolumeCB->ObjectInformation.FileId.Volume,
2386 VolumeCB->ObjectInformation.FileId.Vnode,
2387 VolumeCB->ObjectInformation.FileId.Unique,
2391 // Depending on the reason for invalidation then perform work on the node
2397 case AFS_INVALIDATE_DELETED:
2401 // Mark this volume as invalid
2404 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2406 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2408 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2410 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2412 FILE_NOTIFY_CHANGE_DIR_NAME,
2413 FILE_ACTION_REMOVED);
2415 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2418 pCurrentObject = VolumeCB->ObjectInfoListHead;
2420 while( pCurrentObject != NULL)
2423 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2425 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2429 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2432 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2435 FILE_ACTION_REMOVED);
2437 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2439 pFcb = pCurrentObject->Fcb;
2442 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2447 // Clear out the extents
2448 // And get rid of them (note this involves waiting
2449 // for any writes or reads to the cache to complete)
2452 (VOID) AFSTearDownFcbExtents( pFcb,
2456 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2459 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2468 // Indicate this node requires re-evaluation for the remaining reasons
2471 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2473 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2474 AFS_TRACE_LEVEL_VERBOSE,
2475 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2476 VolumeCB->ObjectInformation.FileId.Cell,
2477 VolumeCB->ObjectInformation.FileId.Volume,
2478 VolumeCB->ObjectInformation.FileId.Vnode,
2479 VolumeCB->ObjectInformation.FileId.Unique);
2481 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY);
2483 if( Reason == AFS_INVALIDATE_FLUSHED)
2486 VolumeCB->ObjectInformation.DataVersion.QuadPart = (ULONGLONG)-1;
2490 // Notify anyone that cares
2493 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2495 if( Reason == AFS_INVALIDATE_CREDS)
2497 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2500 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2501 Reason == AFS_INVALIDATE_FLUSHED)
2503 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2507 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2510 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2513 FILE_ACTION_MODIFIED);
2516 // Volume invalidations require all objects in the volume be re-verified
2519 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2522 pCurrentObject = VolumeCB->ObjectInfoListHead;
2524 while( pCurrentObject != NULL)
2527 pCurrentObject->Expiration.QuadPart = 0;
2529 pCurrentObject->TargetFileId.Vnode = 0;
2531 pCurrentObject->TargetFileId.Unique = 0;
2533 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2534 AFS_TRACE_LEVEL_VERBOSE,
2535 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2536 pCurrentObject->FileId.Cell,
2537 pCurrentObject->FileId.Volume,
2538 pCurrentObject->FileId.Vnode,
2539 pCurrentObject->FileId.Unique);
2541 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
2543 if( Reason == AFS_INVALIDATE_FLUSHED)
2546 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
2549 if( Reason == AFS_INVALIDATE_FLUSHED &&
2550 pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
2553 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2554 AFS_TRACE_LEVEL_VERBOSE,
2555 "AFSInvalidateVolume Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
2556 pCurrentObject->FileId.Cell,
2557 pCurrentObject->FileId.Volume,
2558 pCurrentObject->FileId.Vnode,
2559 pCurrentObject->FileId.Unique);
2561 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2564 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2566 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2570 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2573 if( Reason == AFS_INVALIDATE_CREDS)
2575 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2578 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2579 Reason == AFS_INVALIDATE_FLUSHED)
2581 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2585 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2588 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2591 FILE_ACTION_MODIFIED);
2593 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2596 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2607 AFSVerifyEntry( IN GUID *AuthGroup,
2608 IN AFSDirectoryCB *DirEntry)
2611 NTSTATUS ntStatus = STATUS_SUCCESS;
2612 AFSDirEnumEntry *pDirEnumEntry = NULL;
2613 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2614 IO_STATUS_BLOCK stIoStatus;
2619 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2620 AFS_TRACE_LEVEL_VERBOSE_2,
2621 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2622 &DirEntry->NameInformation.FileName,
2623 pObjectInfo->FileId.Cell,
2624 pObjectInfo->FileId.Volume,
2625 pObjectInfo->FileId.Vnode,
2626 pObjectInfo->FileId.Unique);
2628 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2633 if( !NT_SUCCESS( ntStatus))
2636 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2637 AFS_TRACE_LEVEL_ERROR,
2638 "AFSValidateEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2639 &DirEntry->NameInformation.FileName,
2640 pObjectInfo->FileId.Cell,
2641 pObjectInfo->FileId.Volume,
2642 pObjectInfo->FileId.Vnode,
2643 pObjectInfo->FileId.Unique,
2646 try_return( ntStatus);
2650 // Check the data version of the file
2653 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2654 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2657 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2658 AFS_TRACE_LEVEL_VERBOSE,
2659 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2660 pObjectInfo->DataVersion.QuadPart,
2661 &DirEntry->NameInformation.FileName,
2662 pObjectInfo->FileId.Cell,
2663 pObjectInfo->FileId.Volume,
2664 pObjectInfo->FileId.Vnode,
2665 pObjectInfo->FileId.Unique);
2668 // We are ok, just get out
2671 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2673 try_return( ntStatus = STATUS_SUCCESS);
2677 // New data version so we will need to process the node based on the type
2680 switch( pDirEnumEntry->FileType)
2683 case AFS_FILE_TYPE_MOUNTPOINT:
2687 // For a mount point we need to ensure the target is the same
2690 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2691 &pDirEnumEntry->TargetFileId))
2697 // Update the metadata for the entry
2700 ntStatus = AFSUpdateMetaData( DirEntry,
2703 if( NT_SUCCESS( ntStatus))
2706 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2712 case AFS_FILE_TYPE_SYMLINK:
2715 ASSERT( pDirEnumEntry->TargetNameLength > 0);
2718 // Update the metadata for the entry
2721 ntStatus = AFSUpdateMetaData( DirEntry,
2724 if( NT_SUCCESS( ntStatus))
2727 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2733 case AFS_FILE_TYPE_FILE:
2735 FILE_OBJECT * pCCFileObject = NULL;
2736 BOOLEAN bPurgeExtents = FALSE;
2738 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2740 bPurgeExtents = TRUE;
2742 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2743 AFS_TRACE_LEVEL_VERBOSE,
2744 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2745 &DirEntry->NameInformation.FileName,
2746 pObjectInfo->FileId.Cell,
2747 pObjectInfo->FileId.Volume,
2748 pObjectInfo->FileId.Vnode,
2749 pObjectInfo->FileId.Unique);
2751 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2755 // Update the metadata for the entry
2758 ntStatus = AFSUpdateMetaData( DirEntry,
2761 if( !NT_SUCCESS( ntStatus))
2764 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2765 AFS_TRACE_LEVEL_ERROR,
2766 "AFSInvalidateCache Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2767 &DirEntry->NameInformation.FileName,
2768 pObjectInfo->FileId.Cell,
2769 pObjectInfo->FileId.Volume,
2770 pObjectInfo->FileId.Vnode,
2771 pObjectInfo->FileId.Unique,
2777 if( pObjectInfo->Fcb != NULL)
2780 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2781 AFS_TRACE_LEVEL_VERBOSE,
2782 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2783 &DirEntry->NameInformation.FileName,
2784 pObjectInfo->FileId.Cell,
2785 pObjectInfo->FileId.Volume,
2786 pObjectInfo->FileId.Vnode,
2787 pObjectInfo->FileId.Unique);
2789 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2795 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2800 if( !NT_SUCCESS( stIoStatus.Status))
2803 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2804 AFS_TRACE_LEVEL_ERROR,
2805 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2806 &DirEntry->NameInformation.FileName,
2807 pObjectInfo->FileId.Cell,
2808 pObjectInfo->FileId.Volume,
2809 pObjectInfo->FileId.Vnode,
2810 pObjectInfo->FileId.Unique,
2812 stIoStatus.Information);
2814 ntStatus = stIoStatus.Status;
2820 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2826 __except( EXCEPTION_EXECUTE_HANDLER)
2828 ntStatus = GetExceptionCode();
2830 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2831 AFS_TRACE_LEVEL_ERROR,
2832 "AFSVerifyEntry CcFlushCache or CcPurgeCacheSection Exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2833 &DirEntry->NameInformation.FileName,
2834 pObjectInfo->FileId.Cell,
2835 pObjectInfo->FileId.Volume,
2836 pObjectInfo->FileId.Vnode,
2837 pObjectInfo->FileId.Unique,
2841 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2845 AFSFlushExtents( pObjectInfo->Fcb,
2850 // Reacquire the Fcb to purge the cache
2853 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2854 AFS_TRACE_LEVEL_VERBOSE,
2855 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2856 &pObjectInfo->Fcb->NPFcb->Resource,
2857 PsGetCurrentThread());
2859 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2863 // Update file sizes
2866 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2867 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2868 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2870 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2872 if ( pCCFileObject != NULL)
2874 CcSetFileSizes( pCCFileObject,
2875 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
2878 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2882 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2883 AFS_TRACE_LEVEL_WARNING,
2884 "AFSValidateEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2885 &DirEntry->NameInformation.FileName,
2886 pObjectInfo->FileId.Cell,
2887 pObjectInfo->FileId.Volume,
2888 pObjectInfo->FileId.Vnode,
2889 pObjectInfo->FileId.Unique);
2892 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2897 case AFS_FILE_TYPE_DIRECTORY:
2900 AFSFcb *pCurrentFcb = NULL;
2901 AFSDirectoryCB *pCurrentDirEntry = NULL;
2904 // For a directory or root entry flush the content of
2905 // the directory enumeration.
2908 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2911 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2912 AFS_TRACE_LEVEL_VERBOSE_2,
2913 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2914 &DirEntry->NameInformation.FileName,
2915 pObjectInfo->FileId.Cell,
2916 pObjectInfo->FileId.Volume,
2917 pObjectInfo->FileId.Vnode,
2918 pObjectInfo->FileId.Unique);
2920 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2923 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
2926 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2928 if ( !NT_SUCCESS( ntStatus))
2931 try_return( ntStatus);
2936 // Update the metadata for the entry
2939 ntStatus = AFSUpdateMetaData( DirEntry,
2942 if( NT_SUCCESS( ntStatus))
2945 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2951 case AFS_FILE_TYPE_DFSLINK:
2954 UNICODE_STRING uniTargetName;
2957 // For a DFS link need to check the target name has not changed
2960 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
2962 uniTargetName.MaximumLength = uniTargetName.Length;
2964 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
2966 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
2969 if( DirEntry->NameInformation.TargetName.Length == 0 ||
2970 RtlCompareUnicodeString( &uniTargetName,
2971 &DirEntry->NameInformation.TargetName,
2976 // Update the target name
2979 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
2981 uniTargetName.Buffer,
2982 uniTargetName.Length);
2984 if( !NT_SUCCESS( ntStatus))
2987 AFSReleaseResource( &DirEntry->NonPaged->Lock);
2993 AFSReleaseResource( &DirEntry->NonPaged->Lock);
2996 // Update the metadata for the entry
2999 ntStatus = AFSUpdateMetaData( DirEntry,
3002 if( NT_SUCCESS( ntStatus))
3005 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3013 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3014 AFS_TRACE_LEVEL_WARNING,
3015 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3016 pObjectInfo->FileType,
3017 &DirEntry->NameInformation.FileName,
3018 pObjectInfo->FileId.Cell,
3019 pObjectInfo->FileId.Volume,
3020 pObjectInfo->FileId.Vnode,
3021 pObjectInfo->FileId.Unique);
3028 if( pDirEnumEntry != NULL)
3031 AFSExFreePool( pDirEnumEntry);
3039 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3042 NTSTATUS ntStatus = STATUS_SUCCESS;
3043 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3044 ULONGLONG ullIndex = 0;
3045 AFSVolumeCB *pVolumeCB = NULL;
3046 AFSFcb *pFcb = NULL;
3047 AFSObjectInfoCB *pCurrentObject = NULL;
3053 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3054 AFS_TRACE_LEVEL_VERBOSE,
3055 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3056 VolumeStatus->Online,
3057 VolumeStatus->FileID.Cell,
3058 VolumeStatus->FileID.Volume);
3061 // Need to locate the Fcb for the directory to purge
3064 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3065 AFS_TRACE_LEVEL_VERBOSE,
3066 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3067 &pDevExt->Specific.RDR.VolumeTreeLock,
3068 PsGetCurrentThread());
3070 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3073 // Locate the volume node
3076 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3078 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3080 (AFSBTreeEntry **)&pVolumeCB);
3082 if( pVolumeCB != NULL)
3085 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3087 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3090 // Set the volume state accordingly
3093 if( VolumeStatus->Online)
3096 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3101 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3104 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3107 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3109 while( pCurrentObject != NULL)
3112 if( VolumeStatus->Online)
3115 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3117 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3119 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3124 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3127 pFcb = pCurrentObject->Fcb;
3130 !(VolumeStatus->Online) &&
3131 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3134 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3135 AFS_TRACE_LEVEL_ERROR,
3136 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3137 VolumeStatus->FileID.Cell,
3138 VolumeStatus->FileID.Volume);
3141 // Clear out the extents
3144 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3145 AFS_TRACE_LEVEL_VERBOSE,
3146 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3147 &pFcb->NPFcb->Specific.File.ExtentsResource,
3148 PsGetCurrentThread());
3150 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3153 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3155 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3159 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3160 AFS_TRACE_LEVEL_VERBOSE,
3161 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3162 &pFcb->NPFcb->Specific.File.ExtentsResource,
3163 PsGetCurrentThread());
3165 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3168 // And get rid of them (note this involves waiting
3169 // for any writes or reads to the cache to complete)
3172 (VOID) AFSTearDownFcbExtents( pFcb,
3176 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3179 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3181 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3186 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3194 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3197 NTSTATUS ntStatus = STATUS_SUCCESS;
3202 if( AFSGlobalRoot == NULL)
3205 try_return( ntStatus);
3208 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3212 // Set the network state according to the information
3215 if( NetworkStatus->Online)
3218 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3223 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3226 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3237 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3241 NTSTATUS ntStatus = STATUS_SUCCESS;
3242 BOOLEAN bAcquiredLock = FALSE;
3243 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3244 AFSFcb *pFcb = NULL;
3249 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3250 AFS_TRACE_LEVEL_VERBOSE,
3251 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3252 ObjectInfo->FileId.Cell,
3253 ObjectInfo->FileId.Volume,
3254 ObjectInfo->FileId.Vnode,
3255 ObjectInfo->FileId.Unique);
3257 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3260 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3261 AFS_TRACE_LEVEL_VERBOSE,
3262 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3263 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3264 PsGetCurrentThread());
3266 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3269 bAcquiredLock = TRUE;
3273 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3276 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3277 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3280 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3281 AFS_TRACE_LEVEL_ERROR,
3282 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
3283 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3284 ObjectInfo->FileId.Cell,
3285 ObjectInfo->FileId.Volume,
3286 ObjectInfo->FileId.Vnode,
3287 ObjectInfo->FileId.Unique);
3291 // Reset the directory list information by clearing all valid entries
3294 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3296 while( pCurrentDirEntry != NULL)
3299 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3301 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3305 // If this entry has been deleted then process it here
3308 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3309 pCurrentDirEntry->OpenReferenceCount == 0)
3312 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3313 AFS_TRACE_LEVEL_VERBOSE,
3314 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3316 &pCurrentDirEntry->NameInformation.FileName);
3318 AFSDeleteDirEntry( ObjectInfo,
3324 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3326 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3327 AFS_TRACE_LEVEL_VERBOSE,
3328 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3330 pCurrentDirEntry->OpenReferenceCount);
3333 // We pull the short name from the parent tree since it could change below
3336 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3339 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3340 AFS_TRACE_LEVEL_VERBOSE,
3341 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3343 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3344 &pCurrentDirEntry->NameInformation.FileName);
3346 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3349 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3354 pCurrentDirEntry = pNextDirEntry;
3358 // Reget the directory contents
3361 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3364 if ( !NT_SUCCESS( ntStatus))
3366 try_return( ntStatus);
3370 // Now start again and tear down any entries not valid
3373 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3375 while( pCurrentDirEntry != NULL)
3378 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3380 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3383 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3384 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3387 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3390 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3392 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3393 AFS_TRACE_LEVEL_VERBOSE,
3394 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3396 &pCurrentDirEntry->NameInformation.FileName);
3398 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3403 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3406 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3407 AFS_TRACE_LEVEL_VERBOSE,
3408 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3410 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3411 &pCurrentDirEntry->NameInformation.FileName);
3415 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3417 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3418 AFS_TRACE_LEVEL_VERBOSE,
3419 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3421 &pCurrentDirEntry->NameInformation.FileName);
3426 pCurrentDirEntry = pNextDirEntry;
3431 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3432 AFS_TRACE_LEVEL_VERBOSE,
3433 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3435 pCurrentDirEntry->OpenReferenceCount);
3437 if( pCurrentDirEntry->OpenReferenceCount == 0)
3440 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3441 AFS_TRACE_LEVEL_VERBOSE,
3442 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3443 &pCurrentDirEntry->NameInformation.FileName,
3444 ObjectInfo->FileId.Cell,
3445 ObjectInfo->FileId.Volume,
3446 ObjectInfo->FileId.Vnode,
3447 ObjectInfo->FileId.Unique);
3449 AFSDeleteDirEntry( ObjectInfo,
3455 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3456 AFS_TRACE_LEVEL_VERBOSE,
3457 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3459 &pCurrentDirEntry->NameInformation.FileName,
3460 ObjectInfo->FileId.Cell,
3461 ObjectInfo->FileId.Volume,
3462 ObjectInfo->FileId.Vnode,
3463 ObjectInfo->FileId.Unique);
3465 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3467 AFSRemoveNameEntry( ObjectInfo,
3471 pCurrentDirEntry = pNextDirEntry;
3475 if( !AFSValidateDirList( ObjectInfo))
3478 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3487 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3495 AFSIsVolumeFID( IN AFSFileID *FileID)
3498 BOOLEAN bIsVolume = FALSE;
3500 if( FileID->Vnode == 1 &&
3501 FileID->Unique == 1)
3511 AFSIsFinalNode( IN AFSFcb *Fcb)
3514 BOOLEAN bIsFinalNode = FALSE;
3516 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3517 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3518 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3519 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3520 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3523 bIsFinalNode = TRUE;
3528 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3529 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3532 return bIsFinalNode;
3536 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3537 IN AFSDirEnumEntry *DirEnumEntry)
3540 NTSTATUS ntStatus = STATUS_SUCCESS;
3541 UNICODE_STRING uniTargetName;
3542 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3547 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3549 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3551 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3553 pObjectInfo->FileType = DirEnumEntry->FileType;
3555 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3557 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3559 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3561 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3563 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3565 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3567 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3569 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3572 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3575 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3576 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3579 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3582 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3584 pObjectInfo->Links = DirEnumEntry->Links;
3586 if( DirEnumEntry->TargetNameLength > 0)
3590 // Update the target name information if needed
3593 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3595 uniTargetName.MaximumLength = uniTargetName.Length;
3597 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3599 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3602 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3603 RtlCompareUnicodeString( &uniTargetName,
3604 &DirEntry->NameInformation.TargetName,
3609 // Update the target name
3612 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3614 uniTargetName.Buffer,
3615 uniTargetName.Length);
3617 if( !NT_SUCCESS( ntStatus))
3620 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3622 try_return( ntStatus);
3626 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3628 else if( DirEntry->NameInformation.TargetName.Length > 0)
3631 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3634 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3635 DirEntry->NameInformation.TargetName.Buffer != NULL)
3637 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
3640 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3642 DirEntry->NameInformation.TargetName.Length = 0;
3643 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3644 DirEntry->NameInformation.TargetName.Buffer = NULL;
3646 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3658 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3660 IN BOOLEAN PurgeContent,
3661 IN BOOLEAN FastCall)
3664 NTSTATUS ntStatus = STATUS_SUCCESS;
3665 LARGE_INTEGER liSystemTime;
3666 AFSDirEnumEntry *pDirEnumEntry = NULL;
3667 AFSFcb *pCurrentFcb = NULL;
3668 BOOLEAN bReleaseFcb = FALSE;
3669 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3675 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3679 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3680 AFS_TRACE_LEVEL_VERBOSE_2,
3681 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3682 &DirEntry->NameInformation.FileName,
3683 pObjectInfo->FileId.Cell,
3684 pObjectInfo->FileId.Volume,
3685 pObjectInfo->FileId.Vnode,
3686 pObjectInfo->FileId.Unique);
3689 // If this is a fake node then bail since the service knows nothing about it
3692 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3695 try_return( ntStatus);
3699 pObjectInfo->Fcb != NULL)
3702 pCurrentFcb = pObjectInfo->Fcb;
3704 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3707 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3708 AFS_TRACE_LEVEL_VERBOSE,
3709 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3710 &pCurrentFcb->NPFcb->Resource,
3711 PsGetCurrentThread());
3713 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3721 // This routine ensures that the current entry is valid by:
3723 // 1) Checking that the expiration time is non-zero and after where we
3727 KeQuerySystemTime( &liSystemTime);
3729 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3730 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3731 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3732 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3735 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3736 AFS_TRACE_LEVEL_VERBOSE_2,
3737 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3738 &DirEntry->NameInformation.FileName,
3739 pObjectInfo->FileId.Cell,
3740 pObjectInfo->FileId.Volume,
3741 pObjectInfo->FileId.Vnode,
3742 pObjectInfo->FileId.Unique);
3744 try_return( ntStatus);
3748 // This node requires updating
3751 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3756 if( !NT_SUCCESS( ntStatus))
3759 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3760 AFS_TRACE_LEVEL_ERROR,
3761 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3763 &DirEntry->NameInformation.FileName,
3764 pObjectInfo->FileId.Cell,
3765 pObjectInfo->FileId.Volume,
3766 pObjectInfo->FileId.Vnode,
3767 pObjectInfo->FileId.Unique,
3771 // Failed validation of node so return access-denied
3774 try_return( ntStatus);
3777 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3778 AFS_TRACE_LEVEL_VERBOSE,
3779 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3781 &DirEntry->NameInformation.FileName,
3782 pObjectInfo->FileId.Cell,
3783 pObjectInfo->FileId.Volume,
3784 pObjectInfo->FileId.Vnode,
3785 pObjectInfo->FileId.Unique,
3786 pObjectInfo->DataVersion.QuadPart,
3787 pDirEnumEntry->DataVersion.QuadPart,
3788 pDirEnumEntry->FileType);
3792 // Based on the file type, process the node
3795 switch( pDirEnumEntry->FileType)
3798 case AFS_FILE_TYPE_MOUNTPOINT:
3802 // Update the metadata for the entry
3805 ntStatus = AFSUpdateMetaData( DirEntry,
3808 if( NT_SUCCESS( ntStatus))
3811 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3817 case AFS_FILE_TYPE_SYMLINK:
3818 case AFS_FILE_TYPE_DFSLINK:
3822 // Update the metadata for the entry
3825 ntStatus = AFSUpdateMetaData( DirEntry,
3828 if( NT_SUCCESS( ntStatus))
3831 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3837 case AFS_FILE_TYPE_FILE:
3841 // For a file where the data version has become invalid we need to
3842 // fail any current extent requests and purge the cache for the file
3843 // Can't hold the Fcb resource while doing this
3846 if( pCurrentFcb != NULL &&
3847 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3848 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3851 IO_STATUS_BLOCK stIoStatus;
3852 BOOLEAN bPurgeExtents = FALSE;
3854 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3855 AFS_TRACE_LEVEL_VERBOSE_2,
3856 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3857 &DirEntry->NameInformation.FileName,
3858 pObjectInfo->FileId.Cell,
3859 pObjectInfo->FileId.Volume,
3860 pObjectInfo->FileId.Vnode,
3861 pObjectInfo->FileId.Unique);
3863 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3865 bPurgeExtents = TRUE;
3867 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3868 AFS_TRACE_LEVEL_VERBOSE,
3869 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3870 &DirEntry->NameInformation.FileName,
3871 pObjectInfo->FileId.Cell,
3872 pObjectInfo->FileId.Volume,
3873 pObjectInfo->FileId.Vnode,
3874 pObjectInfo->FileId.Unique);
3876 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3882 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
3887 if( !NT_SUCCESS( stIoStatus.Status))
3890 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3891 AFS_TRACE_LEVEL_ERROR,
3892 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3893 &DirEntry->NameInformation.FileName,
3894 pObjectInfo->FileId.Cell,
3895 pObjectInfo->FileId.Volume,
3896 pObjectInfo->FileId.Vnode,
3897 pObjectInfo->FileId.Unique,
3899 stIoStatus.Information);
3901 ntStatus = stIoStatus.Status;
3907 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3913 __except( EXCEPTION_EXECUTE_HANDLER)
3915 ntStatus = GetExceptionCode();
3917 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3918 AFS_TRACE_LEVEL_ERROR,
3919 "AFSValidateEntry CcFlushCache or CcPurgeCacheSection exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3920 &DirEntry->NameInformation.FileName,
3921 pObjectInfo->FileId.Cell,
3922 pObjectInfo->FileId.Volume,
3923 pObjectInfo->FileId.Vnode,
3924 pObjectInfo->FileId.Unique,
3929 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3933 AFSFlushExtents( pCurrentFcb,
3938 // Reacquire the Fcb to purge the cache
3941 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3942 AFS_TRACE_LEVEL_VERBOSE,
3943 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3944 &pCurrentFcb->NPFcb->Resource,
3945 PsGetCurrentThread());
3947 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3952 // Update the metadata for the entry
3955 ntStatus = AFSUpdateMetaData( DirEntry,
3958 if( !NT_SUCCESS( ntStatus))
3961 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3962 AFS_TRACE_LEVEL_ERROR,
3963 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3964 &DirEntry->NameInformation.FileName,
3965 pObjectInfo->FileId.Cell,
3966 pObjectInfo->FileId.Volume,
3967 pObjectInfo->FileId.Vnode,
3968 pObjectInfo->FileId.Unique,
3974 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3977 // Update file sizes
3980 if( pObjectInfo->Fcb != NULL)
3982 FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3984 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3985 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3986 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3988 if ( pCCFileObject != NULL)
3990 CcSetFileSizes( pCCFileObject,
3991 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3998 case AFS_FILE_TYPE_DIRECTORY:
4001 AFSDirectoryCB *pCurrentDirEntry = NULL;
4003 if( pCurrentFcb != NULL &&
4004 pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4008 // For a directory or root entry flush the content of
4009 // the directory enumeration.
4012 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4013 AFS_TRACE_LEVEL_VERBOSE,
4014 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4015 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4016 PsGetCurrentThread());
4018 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4021 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4022 AFS_TRACE_LEVEL_VERBOSE_2,
4023 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4024 &DirEntry->NameInformation.FileName,
4025 pObjectInfo->FileId.Cell,
4026 pObjectInfo->FileId.Volume,
4027 pObjectInfo->FileId.Vnode,
4028 pObjectInfo->FileId.Unique);
4030 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4033 AFSValidateDirectoryCache( pCurrentFcb->ObjectInformation,
4036 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4039 if( !NT_SUCCESS( ntStatus))
4042 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4043 AFS_TRACE_LEVEL_ERROR,
4044 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4045 &DirEntry->NameInformation.FileName,
4046 pObjectInfo->FileId.Cell,
4047 pObjectInfo->FileId.Volume,
4048 pObjectInfo->FileId.Vnode,
4049 pObjectInfo->FileId.Unique,
4057 // Update the metadata for the entry
4060 ntStatus = AFSUpdateMetaData( DirEntry,
4063 if( NT_SUCCESS( ntStatus))
4066 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4074 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4075 AFS_TRACE_LEVEL_WARNING,
4076 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4077 pObjectInfo->FileType,
4079 &DirEntry->NameInformation.FileName,
4080 pObjectInfo->FileId.Cell,
4081 pObjectInfo->FileId.Volume,
4082 pObjectInfo->FileId.Vnode,
4083 pObjectInfo->FileId.Unique);
4093 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4096 if( pDirEnumEntry != NULL)
4099 AFSExFreePool( pDirEnumEntry);
4107 AFSInitializeSpecialShareNameList()
4110 NTSTATUS ntStatus = STATUS_SUCCESS;
4111 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4112 AFSObjectInfoCB *pObjectInfoCB = NULL;
4113 UNICODE_STRING uniShareName;
4114 ULONG ulEntryLength = 0;
4115 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4120 RtlInitUnicodeString( &uniShareName,
4123 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4126 if( pObjectInfoCB == NULL)
4129 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4132 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4133 AFS_TRACE_LEVEL_VERBOSE,
4134 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
4137 pObjectInfoCB->ObjectReferenceCount = 1;
4139 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4141 ulEntryLength = sizeof( AFSDirectoryCB) +
4142 uniShareName.Length;
4144 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4148 if( pDirNode == NULL)
4151 AFSDeleteObjectInfo( pObjectInfoCB);
4153 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4156 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4157 sizeof( AFSNonPagedDirectoryCB),
4158 AFS_DIR_ENTRY_NP_TAG);
4160 if( pNonPagedDirEntry == NULL)
4163 ExFreePool( pDirNode);
4165 AFSDeleteObjectInfo( pObjectInfoCB);
4167 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4170 RtlZeroMemory( pDirNode,
4173 RtlZeroMemory( pNonPagedDirEntry,
4174 sizeof( AFSNonPagedDirectoryCB));
4176 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4178 pDirNode->NonPaged = pNonPagedDirEntry;
4180 pDirNode->ObjectInformation = pObjectInfoCB;
4186 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
4188 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4190 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4192 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4194 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4195 uniShareName.Buffer,
4196 pDirNode->NameInformation.FileName.Length);
4198 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4201 AFSSpecialShareNames = pDirNode;
4203 pLastDirNode = pDirNode;
4205 RtlInitUnicodeString( &uniShareName,
4208 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4211 if( pObjectInfoCB == NULL)
4214 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4217 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4218 AFS_TRACE_LEVEL_VERBOSE,
4219 "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
4222 pObjectInfoCB->ObjectReferenceCount = 1;
4224 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4226 ulEntryLength = sizeof( AFSDirectoryCB) +
4227 uniShareName.Length;
4229 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4233 if( pDirNode == NULL)
4236 AFSDeleteObjectInfo( pObjectInfoCB);
4238 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4241 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4242 sizeof( AFSNonPagedDirectoryCB),
4243 AFS_DIR_ENTRY_NP_TAG);
4245 if( pNonPagedDirEntry == NULL)
4248 ExFreePool( pDirNode);
4250 AFSDeleteObjectInfo( pObjectInfoCB);
4252 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4255 RtlZeroMemory( pDirNode,
4258 RtlZeroMemory( pNonPagedDirEntry,
4259 sizeof( AFSNonPagedDirectoryCB));
4261 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4263 pDirNode->NonPaged = pNonPagedDirEntry;
4265 pDirNode->ObjectInformation = pObjectInfoCB;
4271 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
4273 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4275 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4277 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4279 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4280 uniShareName.Buffer,
4281 pDirNode->NameInformation.FileName.Length);
4283 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4286 pLastDirNode->ListEntry.fLink = pDirNode;
4288 pDirNode->ListEntry.bLink = pLastDirNode;
4290 pLastDirNode = pDirNode;
4292 RtlInitUnicodeString( &uniShareName,
4295 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4298 if( pObjectInfoCB == NULL)
4301 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4304 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4305 AFS_TRACE_LEVEL_VERBOSE,
4306 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4309 pObjectInfoCB->ObjectReferenceCount = 1;
4311 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4313 ulEntryLength = sizeof( AFSDirectoryCB) +
4314 uniShareName.Length;
4316 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4320 if( pDirNode == NULL)
4323 AFSDeleteObjectInfo( pObjectInfoCB);
4325 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4328 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4329 sizeof( AFSNonPagedDirectoryCB),
4330 AFS_DIR_ENTRY_NP_TAG);
4332 if( pNonPagedDirEntry == NULL)
4335 ExFreePool( pDirNode);
4337 AFSDeleteObjectInfo( pObjectInfoCB);
4339 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4342 RtlZeroMemory( pDirNode,
4345 RtlZeroMemory( pNonPagedDirEntry,
4346 sizeof( AFSNonPagedDirectoryCB));
4348 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4350 pDirNode->NonPaged = pNonPagedDirEntry;
4352 pDirNode->ObjectInformation = pObjectInfoCB;
4358 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4360 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4362 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4364 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4366 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4367 uniShareName.Buffer,
4368 pDirNode->NameInformation.FileName.Length);
4370 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4373 pLastDirNode->ListEntry.fLink = pDirNode;
4375 pDirNode->ListEntry.bLink = pLastDirNode;
4379 if( !NT_SUCCESS( ntStatus))
4382 if( AFSSpecialShareNames != NULL)
4385 pDirNode = AFSSpecialShareNames;
4387 while( pDirNode != NULL)
4390 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4392 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4394 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4396 ExFreePool( pDirNode->NonPaged);
4398 ExFreePool( pDirNode);
4400 pDirNode = pLastDirNode;
4403 AFSSpecialShareNames = NULL;
4412 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4413 IN UNICODE_STRING *SecondaryName)
4416 AFSDirectoryCB *pDirectoryCB = NULL;
4417 ULONGLONG ullHash = 0;
4418 UNICODE_STRING uniFullShareName;
4424 // Build up the entire name here. We are guaranteed that if there is a
4425 // secondary name, it is pointing to a portion of the share name buffer
4428 if( SecondaryName->Length > 0 &&
4429 SecondaryName->Buffer != NULL)
4432 uniFullShareName = *SecondaryName;
4435 // The calling routine strips off the leading slash so add it back in
4438 uniFullShareName.Buffer--;
4439 uniFullShareName.Length += sizeof( WCHAR);
4440 uniFullShareName.MaximumLength += sizeof( WCHAR);
4443 // And the share name
4446 uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
4447 uniFullShareName.Length += ShareName->Length;
4448 uniFullShareName.MaximumLength += ShareName->Length;
4453 uniFullShareName = *ShareName;
4457 // Generate our hash value
4460 ullHash = AFSGenerateCRC( &uniFullShareName,
4464 // Loop through our special share names to see if this is one of them
4467 pDirectoryCB = AFSSpecialShareNames;
4469 while( pDirectoryCB != NULL)
4472 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4478 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4482 return pDirectoryCB;
4486 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4490 // Block on the queue flush event
4493 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4503 AFSWaitOnQueuedReleases()
4506 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4509 // Block on the queue flush event
4512 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4522 AFSIsEqualFID( IN AFSFileID *FileId1,
4523 IN AFSFileID *FileId2)
4526 BOOLEAN bIsEqual = FALSE;
4528 if( FileId1->Unique == FileId2->Unique &&
4529 FileId1->Vnode == FileId2->Vnode &&
4530 FileId1->Volume == FileId2->Volume &&
4531 FileId1->Cell == FileId2->Cell)
4541 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4544 NTSTATUS ntStatus = STATUS_SUCCESS;
4545 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4550 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4553 // Reset the directory list information
4556 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4558 while( pCurrentDirEntry != NULL)
4561 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4563 if( pCurrentDirEntry->OpenReferenceCount == 0)
4566 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4567 AFS_TRACE_LEVEL_VERBOSE,
4568 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4570 &pCurrentDirEntry->NameInformation.FileName);
4572 AFSDeleteDirEntry( ObjectInfoCB,
4578 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4579 AFS_TRACE_LEVEL_VERBOSE,
4580 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4582 &pCurrentDirEntry->NameInformation.FileName);
4584 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4586 AFSRemoveNameEntry( ObjectInfoCB,
4590 pCurrentDirEntry = pNextDirEntry;
4593 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4595 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4597 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4599 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4601 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4603 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4605 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4606 AFS_TRACE_LEVEL_VERBOSE,
4607 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4608 ObjectInfoCB->FileId.Cell,
4609 ObjectInfoCB->FileId.Volume,
4610 ObjectInfoCB->FileId.Vnode,
4611 ObjectInfoCB->FileId.Unique);
4618 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4621 NTSTATUS ntStatus = STATUS_SUCCESS;
4622 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4623 UNICODE_STRING uniFullName;
4628 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4629 AFS_TRACE_LEVEL_VERBOSE,
4630 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4631 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4632 PsGetCurrentThread());
4634 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4637 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4640 try_return( ntStatus);
4644 // Initialize the root information
4647 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4650 // Enumerate the shares in the volume
4653 ntStatus = AFSEnumerateDirectory( AuthGroup,
4654 &AFSGlobalRoot->ObjectInformation,
4657 if( !NT_SUCCESS( ntStatus))
4660 try_return( ntStatus);
4663 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4666 // Indicate the node is initialized
4669 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4671 uniFullName.MaximumLength = PAGE_SIZE;
4672 uniFullName.Length = 0;
4674 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4675 uniFullName.MaximumLength,
4676 AFS_GENERIC_MEMORY_12_TAG);
4678 if( uniFullName.Buffer == NULL)
4682 // Reset the directory content
4685 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4687 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4689 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4693 // Populate our list of entries in the NP enumeration list
4696 while( pDirGlobalDirNode != NULL)
4699 uniFullName.Buffer[ 0] = L'\\';
4700 uniFullName.Buffer[ 1] = L'\\';
4702 uniFullName.Length = 2 * sizeof( WCHAR);
4704 RtlCopyMemory( &uniFullName.Buffer[ 2],
4705 AFSServerName.Buffer,
4706 AFSServerName.Length);
4708 uniFullName.Length += AFSServerName.Length;
4710 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4712 uniFullName.Length += sizeof( WCHAR);
4714 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4715 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4716 pDirGlobalDirNode->NameInformation.FileName.Length);
4718 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4720 AFSAddConnectionEx( &uniFullName,
4721 RESOURCEDISPLAYTYPE_SHARE,
4724 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4727 AFSExFreePool( uniFullName.Buffer);
4731 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4738 AFSIsRelativeName( IN UNICODE_STRING *Name)
4741 BOOLEAN bIsRelative = FALSE;
4743 if( Name->Buffer[ 0] != L'\\')
4753 AFSUpdateName( IN UNICODE_STRING *Name)
4758 while( usIndex < Name->Length/sizeof( WCHAR))
4761 if( Name->Buffer[ usIndex] == L'/')
4764 Name->Buffer[ usIndex] = L'\\';
4774 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4775 IN OUT ULONG *Flags,
4776 IN WCHAR *NameBuffer,
4777 IN USHORT NameLength)
4780 NTSTATUS ntStatus = STATUS_SUCCESS;
4781 WCHAR *pTmpBuffer = NULL;
4787 // If we have enough space then just move in the name otherwise
4788 // allocate a new buffer
4791 if( TargetName->Length < NameLength)
4794 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4796 AFS_NAME_BUFFER_FIVE_TAG);
4798 if( pTmpBuffer == NULL)
4801 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4804 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4807 AFSExFreePool( TargetName->Buffer);
4810 TargetName->MaximumLength = NameLength;
4812 TargetName->Buffer = pTmpBuffer;
4814 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4817 TargetName->Length = NameLength;
4819 RtlCopyMemory( TargetName->Buffer,
4821 TargetName->Length);
4824 // Update the name in the buffer
4827 AFSUpdateName( TargetName);
4838 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4839 IN ULONG InitialElementCount)
4842 AFSNameArrayHdr *pNameArray = NULL;
4843 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4849 if( InitialElementCount == 0)
4852 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
4855 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
4856 sizeof( AFSNameArrayHdr) +
4857 (InitialElementCount * sizeof( AFSNameArrayCB)),
4858 AFS_NAME_ARRAY_TAG);
4860 if( pNameArray == NULL)
4863 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4864 AFS_TRACE_LEVEL_ERROR,
4865 "AFSInitNameArray Failed to allocate name array\n");
4867 try_return( pNameArray);
4870 RtlZeroMemory( pNameArray,
4871 sizeof( AFSNameArrayHdr) +
4872 (InitialElementCount * sizeof( AFSNameArrayCB)));
4874 pNameArray->MaxElementCount = InitialElementCount;
4876 if( DirectoryCB != NULL)
4879 pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
4881 lCount = InterlockedIncrement( &pNameArray->Count);
4883 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
4885 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4886 AFS_TRACE_LEVEL_VERBOSE,
4887 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
4888 &DirectoryCB->NameInformation.FileName,
4892 pNameArray->CurrentEntry->DirectoryCB = DirectoryCB;
4894 pNameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
4896 pNameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
4908 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
4909 IN UNICODE_STRING *Path,
4910 IN AFSDirectoryCB *DirectoryCB)
4913 NTSTATUS ntStatus = STATUS_SUCCESS;
4914 AFSNameArrayCB *pCurrentElement = NULL;
4915 UNICODE_STRING uniComponentName, uniRemainingPath;
4916 AFSObjectInfoCB *pCurrentObject = NULL;
4917 ULONG ulTotalCount = 0;
4919 USHORT usLength = 0;
4926 // Init some info in the header
4929 pCurrentElement = &NameArray->ElementArray[ 0];
4931 NameArray->CurrentEntry = pCurrentElement;
4934 // The first entry points at the root
4937 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
4939 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4941 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4942 AFS_TRACE_LEVEL_VERBOSE,
4943 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
4944 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4945 pCurrentElement->DirectoryCB,
4948 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
4950 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
4952 NameArray->Count = 1;
4954 NameArray->LinkCount = 0;
4957 // If the root is the parent then we are done ...
4960 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
4962 try_return( ntStatus);
4974 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
4975 IN AFSNameArrayHdr *RelatedNameArray,
4976 IN AFSDirectoryCB *DirectoryCB)
4979 NTSTATUS ntStatus = STATUS_SUCCESS;
4980 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
4981 UNICODE_STRING uniComponentName, uniRemainingPath;
4982 AFSObjectInfoCB *pObjectInfo = NULL;
4983 ULONG ulTotalCount = 0;
4985 USHORT usLength = 0;
4992 // Init some info in the header
4995 pCurrentElement = &NameArray->ElementArray[ 0];
4997 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
4999 NameArray->Count = 0;
5001 NameArray->LinkCount = RelatedNameArray->LinkCount;
5004 // Populate the name array with the data from the related array
5010 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5012 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5014 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5016 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5018 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5019 AFS_TRACE_LEVEL_VERBOSE,
5020 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
5021 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5022 pCurrentElement->DirectoryCB,
5025 lCount = InterlockedIncrement( &NameArray->Count);
5027 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5028 NameArray->Count == RelatedNameArray->Count)
5040 pCurrentRelatedElement++;
5043 if( NameArray->Count > 0)
5045 NameArray->CurrentEntry = pCurrentElement;
5053 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5056 NTSTATUS ntStatus = STATUS_SUCCESS;
5057 AFSNameArrayCB *pCurrentElement = NULL;
5063 pCurrentElement = &NameArray->ElementArray[ 0];
5068 if( pCurrentElement->DirectoryCB == NULL)
5074 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5076 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5077 AFS_TRACE_LEVEL_VERBOSE,
5078 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
5079 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5080 pCurrentElement->DirectoryCB,
5086 AFSExFreePool( NameArray);
5093 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5094 IN AFSDirectoryCB *DirEntry)
5097 NTSTATUS ntStatus = STATUS_SUCCESS;
5098 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5104 if( NameArray->Count == NameArray->MaxElementCount)
5107 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5110 if( NameArray->CurrentEntry != NULL &&
5111 NameArray->CurrentEntry->DirectoryCB == DirEntry)
5114 try_return( ntStatus);
5117 if( NameArray->Count > 0)
5120 NameArray->CurrentEntry++;
5124 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5127 lCount = InterlockedIncrement( &NameArray->Count);
5129 lCount = InterlockedIncrement( &DirEntry->OpenReferenceCount);
5131 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5132 AFS_TRACE_LEVEL_VERBOSE,
5133 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
5134 &DirEntry->NameInformation.FileName,
5138 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5140 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5142 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5153 AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
5154 IN AFSDirectoryCB *DirectoryCB)
5158 ASSERT( NameArray->CurrentEntry != NULL);
5160 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5162 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5163 AFS_TRACE_LEVEL_VERBOSE,
5164 "AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
5165 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5166 NameArray->CurrentEntry->DirectoryCB,
5169 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5171 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5172 AFS_TRACE_LEVEL_VERBOSE,
5173 "AFSReplaceCurrentElement Increment count on %wZ DE %p Cnt %d\n",
5174 &DirectoryCB->NameInformation.FileName,
5178 NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
5180 NameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
5182 NameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
5184 if( DirectoryCB->ObjectInformation->ParentObjectInformation == NULL)
5187 SetFlag( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5194 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5197 AFSDirectoryCB *pCurrentDirEntry = NULL;
5203 if( NameArray->Count == 0)
5205 try_return( pCurrentDirEntry);
5208 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5210 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5211 AFS_TRACE_LEVEL_VERBOSE,
5212 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5213 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5214 NameArray->CurrentEntry->DirectoryCB,
5217 NameArray->CurrentEntry->DirectoryCB = NULL;
5219 lCount = InterlockedDecrement( &NameArray->Count);
5223 NameArray->CurrentEntry = NULL;
5227 NameArray->CurrentEntry--;
5228 pCurrentDirEntry = NameArray->CurrentEntry->DirectoryCB;
5236 return pCurrentDirEntry;
5240 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5243 AFSDirectoryCB *pDirEntry = NULL;
5244 AFSNameArrayCB *pElement = NULL;
5249 if( NameArray->Count == 0 ||
5250 NameArray->Count == 1)
5253 try_return( pDirEntry = NULL);
5256 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5258 pDirEntry = pElement->DirectoryCB;
5269 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5270 IN AFSDirectoryCB *DirEntry)
5273 AFSNameArrayCB *pCurrentElement = NULL;
5274 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5280 pCurrentElement = &NameArray->ElementArray[ 0];
5285 if( pCurrentElement->DirectoryCB == NULL)
5291 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5293 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5294 AFS_TRACE_LEVEL_VERBOSE,
5295 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5296 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5297 pCurrentElement->DirectoryCB,
5303 RtlZeroMemory( NameArray,
5304 sizeof( AFSNameArrayHdr) +
5305 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5307 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5309 if( DirEntry != NULL)
5312 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5314 lCount = InterlockedIncrement( &NameArray->Count);
5316 lCount = InterlockedIncrement( &DirEntry->OpenReferenceCount);
5318 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5319 AFS_TRACE_LEVEL_VERBOSE,
5320 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5321 &DirEntry->NameInformation.FileName,
5325 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5327 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5329 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5337 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5340 AFSNameArrayCB *pCurrentElement = NULL;
5342 pCurrentElement = &NameArray->ElementArray[ 0];
5344 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5346 while( pCurrentElement->DirectoryCB != NULL)
5349 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5350 pCurrentElement->FileId.Cell,
5351 pCurrentElement->FileId.Volume,
5352 pCurrentElement->FileId.Vnode,
5353 pCurrentElement->FileId.Unique,
5354 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5359 AFSPrint("AFSDumpNameArray End\n\n");
5365 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5370 // Depending on the type of node, set the event
5373 switch( Fcb->Header.NodeTypeCode)
5376 case AFS_DIRECTORY_FCB:
5379 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5383 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5392 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5396 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5406 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5412 // Depending on the type of node, set the event
5415 switch( Fcb->Header.NodeTypeCode)
5418 case AFS_DIRECTORY_FCB:
5421 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5423 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5428 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5438 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5440 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5445 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5456 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5459 BOOLEAN bIsInProcess = FALSE;
5464 if( ObjectInfo->Fcb == NULL)
5467 try_return( bIsInProcess);
5471 // Depending on the type of node, set the event
5474 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5477 case AFS_DIRECTORY_FCB:
5480 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5483 bIsInProcess = TRUE;
5493 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5496 bIsInProcess = TRUE;
5508 return bIsInProcess;
5512 AFSVerifyVolume( IN ULONGLONG ProcessId,
5513 IN AFSVolumeCB *VolumeCB)
5516 NTSTATUS ntStatus = STATUS_SUCCESS;
5523 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5526 NTSTATUS ntStatus = STATUS_SUCCESS;
5527 AFSObjectInfoCB *pObjectInfoCB = NULL;
5528 AFSDirectoryCB *pDirNode = NULL;
5529 ULONG ulEntryLength = 0;
5530 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5535 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5538 if( pObjectInfoCB == NULL)
5541 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5544 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5545 AFS_TRACE_LEVEL_VERBOSE,
5546 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5549 pObjectInfoCB->ObjectReferenceCount = 1;
5551 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5553 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5555 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5557 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5561 if( pDirNode == NULL)
5564 AFSDeleteObjectInfo( pObjectInfoCB);
5566 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5569 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5570 sizeof( AFSNonPagedDirectoryCB),
5571 AFS_DIR_ENTRY_NP_TAG);
5573 if( pNonPagedDirEntry == NULL)
5576 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5579 RtlZeroMemory( pDirNode,
5582 RtlZeroMemory( pNonPagedDirEntry,
5583 sizeof( AFSNonPagedDirectoryCB));
5585 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5587 pDirNode->NonPaged = pNonPagedDirEntry;
5589 pDirNode->ObjectInformation = pObjectInfoCB;
5591 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5597 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5599 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5601 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5603 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5605 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5606 AFSPIOCtlName.Buffer,
5607 pDirNode->NameInformation.FileName.Length);
5609 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5612 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB = pDirNode;
5616 if ( !NT_SUCCESS( ntStatus))
5619 if ( pDirNode != NULL)
5622 AFSExFreePool( pDirNode);
5625 if ( pObjectInfoCB != NULL)
5628 AFSDeleteObjectInfo( pObjectInfoCB);
5637 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5638 IN AFSDirectoryCB *DirectoryCB,
5639 IN UNICODE_STRING *ParentPathName,
5640 IN AFSNameArrayHdr *RelatedNameArray,
5642 OUT AFSFileInfoCB *FileInfo)
5645 NTSTATUS ntStatus = STATUS_SUCCESS;
5646 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
5647 UNICODE_STRING uniFullPathName;
5648 AFSNameArrayHdr *pNameArray = NULL;
5649 AFSVolumeCB *pVolumeCB = NULL;
5650 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5651 WCHAR *pwchBuffer = NULL;
5652 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5653 ULONG ulNameDifference = 0;
5660 // Retrieve a target name for the entry
5663 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5666 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5669 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5671 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5676 if( !NT_SUCCESS( ntStatus) ||
5677 pDirEntry->TargetNameLength == 0)
5680 if( pDirEntry != NULL)
5683 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5686 try_return( ntStatus);
5689 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5692 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5696 // Update the target name
5699 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5700 &DirectoryCB->Flags,
5701 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5702 (USHORT)pDirEntry->TargetNameLength);
5704 if( !NT_SUCCESS( ntStatus))
5707 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5709 try_return( ntStatus);
5713 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5717 // Need to pass the full path in for parsing.
5720 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5723 uniFullPathName.Length = 0;
5724 uniFullPathName.MaximumLength = ParentPathName->Length +
5726 DirectoryCB->NameInformation.TargetName.Length;
5728 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5729 uniFullPathName.MaximumLength,
5730 AFS_NAME_BUFFER_SIX_TAG);
5732 if( uniFullPathName.Buffer == NULL)
5735 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5737 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5740 pwchBuffer = uniFullPathName.Buffer;
5742 RtlZeroMemory( uniFullPathName.Buffer,
5743 uniFullPathName.MaximumLength);
5745 RtlCopyMemory( uniFullPathName.Buffer,
5746 ParentPathName->Buffer,
5747 ParentPathName->Length);
5749 uniFullPathName.Length = ParentPathName->Length;
5751 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5752 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5755 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5757 uniFullPathName.Length += sizeof( WCHAR);
5760 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5761 DirectoryCB->NameInformation.TargetName.Buffer,
5762 DirectoryCB->NameInformation.TargetName.Length);
5764 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5766 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5767 uniParsedName.MaximumLength = uniParsedName.Length;
5769 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5771 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5774 // We populate up to the current parent
5777 if( RelatedNameArray != NULL)
5780 pNameArray = AFSInitNameArray( NULL,
5781 RelatedNameArray->MaxElementCount);
5783 if( pNameArray == NULL)
5786 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5789 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5796 pNameArray = AFSInitNameArray( NULL,
5799 if( pNameArray == NULL)
5802 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5805 ntStatus = AFSPopulateNameArray( pNameArray,
5810 if( !NT_SUCCESS( ntStatus))
5813 try_return( ntStatus);
5816 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5818 pParentDirEntry = ParentDirectoryCB;
5823 uniFullPathName.Length = 0;
5824 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5826 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5827 uniFullPathName.MaximumLength,
5828 AFS_NAME_BUFFER_SEVEN_TAG);
5830 if( uniFullPathName.Buffer == NULL)
5833 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5835 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5838 pwchBuffer = uniFullPathName.Buffer;
5840 RtlZeroMemory( uniFullPathName.Buffer,
5841 uniFullPathName.MaximumLength);
5843 RtlCopyMemory( uniFullPathName.Buffer,
5844 DirectoryCB->NameInformation.TargetName.Buffer,
5845 DirectoryCB->NameInformation.TargetName.Length);
5847 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5850 // This name should begin with the \afs server so parse it off and check it
5853 FsRtlDissectName( uniFullPathName,
5857 if( RtlCompareUnicodeString( &uniComponentName,
5862 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5864 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5865 AFS_TRACE_LEVEL_ERROR,
5866 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5869 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5872 uniFullPathName = uniRemainingPath;
5874 uniParsedName = uniFullPathName;
5876 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5878 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5884 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5887 if( pNameArray == NULL)
5890 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5893 pVolumeCB = AFSGlobalRoot;
5895 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5899 // Increment the ref count on the volume and dir entry for correct processing below
5902 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
5904 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5905 AFS_TRACE_LEVEL_VERBOSE,
5906 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
5910 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
5912 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5913 AFS_TRACE_LEVEL_VERBOSE,
5914 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5915 &pParentDirEntry->NameInformation.FileName,
5920 ntStatus = AFSLocateNameEntry( NULL,
5925 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5931 if( !NT_SUCCESS( ntStatus))
5935 // The volume lock was released on failure above
5936 // Except for STATUS_OBJECT_NAME_NOT_FOUND
5939 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
5942 if( pVolumeCB != NULL)
5945 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5947 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5948 AFS_TRACE_LEVEL_VERBOSE,
5949 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
5954 if( pDirectoryEntry != NULL)
5957 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5959 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5960 AFS_TRACE_LEVEL_VERBOSE,
5961 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5962 &pDirectoryEntry->NameInformation.FileName,
5970 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
5972 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5973 AFS_TRACE_LEVEL_VERBOSE,
5974 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5975 &pParentDirEntry->NameInformation.FileName,
5984 try_return( ntStatus);
5988 // Store off the information
5991 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5994 // Check for the mount point being returned
5997 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
6000 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6002 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
6003 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6006 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6009 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6014 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6018 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6020 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6022 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6024 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6026 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6028 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6031 // Remove the reference made above
6034 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6036 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6037 AFS_TRACE_LEVEL_VERBOSE,
6038 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
6039 &pDirectoryEntry->NameInformation.FileName,
6046 if( pDirEntry != NULL)
6049 AFSExFreePool( pDirEntry);
6052 if( pVolumeCB != NULL)
6055 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6057 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6058 AFS_TRACE_LEVEL_VERBOSE,
6059 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
6064 if( pNameArray != NULL)
6067 AFSFreeNameArray( pNameArray);
6070 if( pwchBuffer != NULL)
6074 // Always free the buffer that we allocated as AFSLocateNameEntry
6075 // will not free it. If uniFullPathName.Buffer was allocated by
6076 // AFSLocateNameEntry, then we must free that as well.
6077 // Check that the uniFullPathName.Buffer in the string is not the same
6078 // offset by the length of the server name
6081 if( uniFullPathName.Length > 0 &&
6082 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6085 AFSExFreePool( uniFullPathName.Buffer);
6088 AFSExFreePool( pwchBuffer);
6096 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6097 IN ULONGLONG HashIndex)
6100 NTSTATUS ntStatus = STATUS_SUCCESS;
6101 AFSObjectInfoCB *pObjectInfo = NULL;
6107 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6108 sizeof( AFSObjectInfoCB),
6109 AFS_OBJECT_INFO_TAG);
6111 if( pObjectInfo == NULL)
6114 try_return( pObjectInfo);
6117 RtlZeroMemory( pObjectInfo,
6118 sizeof( AFSObjectInfoCB));
6120 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6121 sizeof( AFSNonPagedObjectInfoCB),
6122 AFS_NP_OBJECT_INFO_TAG);
6124 if( pObjectInfo->NonPagedInfo == NULL)
6127 AFSExFreePool( pObjectInfo);
6129 try_return( pObjectInfo = NULL);
6132 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6134 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6136 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6138 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6140 if( ParentObjectInfo != NULL)
6142 lCount = InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
6146 // Initialize the access time
6149 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6155 // Insert the entry into the object tree and list
6158 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6160 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6163 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6168 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6169 &pObjectInfo->TreeEntry);
6171 ASSERT( NT_SUCCESS( ntStatus));
6175 // And the object list in the volume
6178 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6181 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6186 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6188 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6191 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6194 // Indicate the object is in the hash tree and linked list in the volume
6197 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6209 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6212 BOOLEAN bAcquiredTreeLock = FALSE;
6215 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6218 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6220 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6223 bAcquiredTreeLock = TRUE;
6227 // Remove it from the tree and list if it was inserted
6230 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6233 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6234 &ObjectInfo->TreeEntry);
6237 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6240 if( ObjectInfo->ListEntry.fLink == NULL)
6243 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6245 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6248 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6254 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6257 if( ObjectInfo->ListEntry.bLink == NULL)
6260 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6262 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6265 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6271 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6275 if( ObjectInfo->ParentObjectInformation != NULL)
6278 lCount = InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
6281 if( bAcquiredTreeLock)
6284 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6288 // Release the fid in the service
6291 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6294 AFSReleaseFid( &ObjectInfo->FileId);
6297 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6299 AFSExFreePool( ObjectInfo->NonPagedInfo);
6301 AFSExFreePool( ObjectInfo);
6307 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6308 OUT AFSDirectoryCB **TargetDirEntry)
6311 NTSTATUS ntStatus = STATUS_SUCCESS;
6312 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6313 UNICODE_STRING uniFullPathName;
6314 AFSNameArrayHdr *pNameArray = NULL;
6315 AFSVolumeCB *pVolumeCB = NULL;
6316 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6317 WCHAR *pwchBuffer = NULL;
6318 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6319 ULONG ulNameDifference = 0;
6326 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6327 DirectoryCB->ObjectInformation,
6331 if( !NT_SUCCESS( ntStatus))
6333 try_return( ntStatus);
6337 // Retrieve a target name for the entry
6340 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6343 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6346 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6348 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6353 if( !NT_SUCCESS( ntStatus) ||
6354 pDirEntry->TargetNameLength == 0)
6357 if( pDirEntry != NULL)
6360 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6363 try_return( ntStatus);
6366 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6369 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6373 // Update the target name
6376 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6377 &DirectoryCB->Flags,
6378 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6379 (USHORT)pDirEntry->TargetNameLength);
6381 if( !NT_SUCCESS( ntStatus))
6384 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6386 try_return( ntStatus);
6390 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6394 // Need to pass the full path in for parsing.
6397 uniFullPathName.Length = 0;
6398 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6400 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6401 uniFullPathName.MaximumLength,
6402 AFS_NAME_BUFFER_EIGHT_TAG);
6404 if( uniFullPathName.Buffer == NULL)
6407 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6409 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6412 pwchBuffer = uniFullPathName.Buffer;
6414 RtlZeroMemory( uniFullPathName.Buffer,
6415 uniFullPathName.MaximumLength);
6417 RtlCopyMemory( uniFullPathName.Buffer,
6418 DirectoryCB->NameInformation.TargetName.Buffer,
6419 DirectoryCB->NameInformation.TargetName.Length);
6421 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6424 // This name should begin with the \afs server so parse it off and chech it
6427 FsRtlDissectName( uniFullPathName,
6431 if( RtlCompareUnicodeString( &uniComponentName,
6437 // Try evaluating the full path
6440 uniFullPathName.Buffer = pwchBuffer;
6442 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6444 uniFullPathName.MaximumLength = uniFullPathName.Length;
6449 uniFullPathName = uniRemainingPath;
6452 uniParsedName = uniFullPathName;
6454 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6456 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6462 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6465 if( pNameArray == NULL)
6468 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6471 pVolumeCB = AFSGlobalRoot;
6473 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6475 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6477 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6478 AFS_TRACE_LEVEL_VERBOSE,
6479 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6483 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6485 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6486 AFS_TRACE_LEVEL_VERBOSE,
6487 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6488 &pParentDirEntry->NameInformation.FileName,
6493 ntStatus = AFSLocateNameEntry( NULL,
6504 if( !NT_SUCCESS( ntStatus))
6508 // The volume lock was released on failure above
6509 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6512 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6515 if( pVolumeCB != NULL)
6518 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6520 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6521 AFS_TRACE_LEVEL_VERBOSE,
6522 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
6527 if( pDirectoryEntry != NULL)
6530 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6532 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6533 AFS_TRACE_LEVEL_VERBOSE,
6534 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6535 &pDirectoryEntry->NameInformation.FileName,
6543 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6545 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6546 AFS_TRACE_LEVEL_VERBOSE,
6547 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6548 &pParentDirEntry->NameInformation.FileName,
6557 try_return( ntStatus);
6561 // Pass back the target dir entry for this request
6564 *TargetDirEntry = pDirectoryEntry;
6568 if( pDirEntry != NULL)
6571 AFSExFreePool( pDirEntry);
6574 if( pVolumeCB != NULL)
6577 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6579 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6580 AFS_TRACE_LEVEL_VERBOSE,
6581 "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
6586 if( pNameArray != NULL)
6589 AFSFreeNameArray( pNameArray);
6592 if( pwchBuffer != NULL)
6596 // Always free the buffer that we allocated as AFSLocateNameEntry
6597 // will not free it. If uniFullPathName.Buffer was allocated by
6598 // AFSLocateNameEntry, then we must free that as well.
6599 // Check that the uniFullPathName.Buffer in the string is not the same
6600 // offset by the length of the server name
6603 if( uniFullPathName.Length > 0 &&
6604 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6607 AFSExFreePool( uniFullPathName.Buffer);
6610 AFSExFreePool( pwchBuffer);
6618 AFSCleanupFcb( IN AFSFcb *Fcb,
6619 IN BOOLEAN ForceFlush)
6622 NTSTATUS ntStatus = STATUS_SUCCESS;
6623 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6624 LARGE_INTEGER liTime;
6625 IO_STATUS_BLOCK stIoStatus;
6630 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6632 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6634 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6637 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6638 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6641 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6644 if( Fcb->OpenReferenceCount > 0)
6650 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6655 if( !NT_SUCCESS( stIoStatus.Status))
6658 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6659 AFS_TRACE_LEVEL_ERROR,
6660 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6661 Fcb->ObjectInformation->FileId.Cell,
6662 Fcb->ObjectInformation->FileId.Volume,
6663 Fcb->ObjectInformation->FileId.Vnode,
6664 Fcb->ObjectInformation->FileId.Unique,
6666 stIoStatus.Information);
6668 ntStatus = stIoStatus.Status;
6671 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6676 __except( EXCEPTION_EXECUTE_HANDLER)
6678 ntStatus = GetExceptionCode();
6682 AFSReleaseResource( &Fcb->NPFcb->Resource);
6685 // Wait for any currently running flush or release requests to complete
6688 AFSWaitOnQueuedFlushes( Fcb);
6691 // Now perform another flush on the file
6694 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6698 AFSReleaseExtentsWithFlush( Fcb,
6703 if( Fcb->OpenReferenceCount == 0 ||
6704 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6705 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6708 AFSTearDownFcbExtents( Fcb,
6712 try_return( ntStatus);
6715 KeQueryTickCount( &liTime);
6718 // First up are there dirty extents in the cache to flush?
6722 ( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6723 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
6724 ( Fcb->Specific.File.ExtentsDirtyCount ||
6725 Fcb->Specific.File.ExtentCount) &&
6726 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6727 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6729 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6731 Fcb->OpenReferenceCount == 0)
6734 AFSReleaseExtentsWithFlush( Fcb,
6738 else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6739 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6743 // The file has been marked as invalid. Dump it
6746 AFSTearDownFcbExtents( Fcb,
6751 // If there are extents and they haven't been used recently *and*
6752 // are not being used
6756 ( 0 != Fcb->Specific.File.ExtentCount &&
6757 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6758 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6759 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
6760 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6767 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6772 if( !NT_SUCCESS( stIoStatus.Status))
6775 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6776 AFS_TRACE_LEVEL_ERROR,
6777 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6778 Fcb->ObjectInformation->FileId.Cell,
6779 Fcb->ObjectInformation->FileId.Volume,
6780 Fcb->ObjectInformation->FileId.Vnode,
6781 Fcb->ObjectInformation->FileId.Unique,
6783 stIoStatus.Information);
6785 ntStatus = stIoStatus.Status;
6791 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6797 __except( EXCEPTION_EXECUTE_HANDLER)
6799 ntStatus = GetExceptionCode();
6802 AFSReleaseResource( &Fcb->NPFcb->Resource);
6804 if( Fcb->OpenReferenceCount == 0)
6808 // Tear em down we'll not be needing them again
6811 AFSTearDownFcbExtents( Fcb,
6825 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
6826 IN UNICODE_STRING *NewFileName)
6829 NTSTATUS ntStatus = STATUS_SUCCESS;
6830 WCHAR *pTmpBuffer = NULL;
6835 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
6838 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
6841 AFSExFreePool( DirectoryCB->NameInformation.FileName.Buffer);
6843 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6845 DirectoryCB->NameInformation.FileName.Buffer = NULL;
6849 // OK, we need to allocate a new name buffer
6852 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6853 NewFileName->Length,
6854 AFS_NAME_BUFFER_NINE_TAG);
6856 if( pTmpBuffer == NULL)
6859 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6862 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
6864 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
6866 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6869 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
6871 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
6872 NewFileName->Buffer,
6873 NewFileName->Length);
6884 AFSReadCacheFile( IN void *ReadBuffer,
6885 IN LARGE_INTEGER *ReadOffset,
6886 IN ULONG RequestedDataLength,
6887 IN OUT PULONG BytesRead)
6890 NTSTATUS ntStatus = STATUS_SUCCESS;
6893 PIO_STACK_LOCATION pIoStackLocation = NULL;
6894 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6895 DEVICE_OBJECT *pTargetDeviceObject = NULL;
6896 FILE_OBJECT *pCacheFileObject = NULL;
6901 pCacheFileObject = AFSReferenceCacheFileObject();
6903 if( pCacheFileObject == NULL)
6905 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
6908 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
6911 // Initialize the event
6914 KeInitializeEvent( &kEvent,
6915 SynchronizationEvent,
6919 // Allocate an irp for this request. This could also come from a
6920 // private pool, for instance.
6923 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
6929 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6933 // Build the IRP's main body
6936 pIrp->UserBuffer = ReadBuffer;
6938 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
6939 pIrp->RequestorMode = KernelMode;
6940 pIrp->Flags |= IRP_READ_OPERATION;
6943 // Set up the I/O stack location.
6946 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
6947 pIoStackLocation->MajorFunction = IRP_MJ_READ;
6948 pIoStackLocation->DeviceObject = pTargetDeviceObject;
6949 pIoStackLocation->FileObject = pCacheFileObject;
6950 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
6952 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
6955 // Set the completion routine.
6958 IoSetCompletionRoutine( pIrp,
6966 // Send it to the FSD
6969 ntStatus = IoCallDriver( pTargetDeviceObject,
6972 if( NT_SUCCESS( ntStatus))
6979 ntStatus = KeWaitForSingleObject( &kEvent,
6985 if( NT_SUCCESS( ntStatus))
6988 ntStatus = pIrp->IoStatus.Status;
6990 *BytesRead = (ULONG)pIrp->IoStatus.Information;
6996 if( pCacheFileObject != NULL)
6998 AFSReleaseCacheFileObject( pCacheFileObject);
7004 if( pIrp->MdlAddress != NULL)
7007 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7010 MmUnlockPages( pIrp->MdlAddress);
7013 IoFreeMdl( pIrp->MdlAddress);
7016 pIrp->MdlAddress = NULL;
7030 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7035 KEVENT *pEvent = (KEVENT *)Context;
7041 return STATUS_MORE_PROCESSING_REQUIRED;
7045 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7048 BOOLEAN bIsEmpty = FALSE;
7049 AFSDirectoryCB *pDirEntry = NULL;
7054 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7059 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7062 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7064 while( pDirEntry != NULL)
7067 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7068 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7076 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7081 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7088 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7089 IN AFSDirectoryCB *DirEntry)
7092 NTSTATUS ntStatus = STATUS_SUCCESS;
7097 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7100 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7101 AFS_TRACE_LEVEL_VERBOSE,
7102 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7104 &DirEntry->NameInformation.FileName);
7106 try_return( ntStatus);
7109 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7112 // Remove the entry from the parent tree
7115 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7116 AFS_TRACE_LEVEL_VERBOSE,
7117 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7119 &DirEntry->NameInformation.FileName);
7121 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7124 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7125 AFS_TRACE_LEVEL_VERBOSE,
7126 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7128 &DirEntry->NameInformation.FileName);
7130 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7133 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7137 // From the short name tree
7140 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7141 AFS_TRACE_LEVEL_VERBOSE,
7142 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7144 &DirEntry->NameInformation.FileName);
7146 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7149 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7152 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7153 AFS_TRACE_LEVEL_VERBOSE,
7154 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7156 &DirEntry->NameInformation.FileName);
7158 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7160 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7171 AFSGetAuthenticationId()
7174 LARGE_INTEGER liAuthId = {0,0};
7175 NTSTATUS ntStatus = STATUS_SUCCESS;
7176 PACCESS_TOKEN hToken = NULL;
7177 PTOKEN_STATISTICS pTokenInfo = NULL;
7178 BOOLEAN bCopyOnOpen = FALSE;
7179 BOOLEAN bEffectiveOnly = FALSE;
7180 BOOLEAN bPrimaryToken = FALSE;
7181 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7186 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7189 &stImpersonationLevel);
7194 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7199 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7200 AFS_TRACE_LEVEL_ERROR,
7201 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7203 try_return( ntStatus);
7206 bPrimaryToken = TRUE;
7209 ntStatus = SeQueryInformationToken( hToken,
7211 (PVOID *)&pTokenInfo);
7213 if( !NT_SUCCESS( ntStatus))
7216 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7217 AFS_TRACE_LEVEL_ERROR,
7218 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7220 try_return( ntStatus);
7223 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7224 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7226 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7227 AFS_TRACE_LEVEL_VERBOSE,
7228 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7239 PsDereferenceImpersonationToken( hToken);
7244 PsDereferencePrimaryToken( hToken);
7248 if( pTokenInfo != NULL)
7251 AFSExFreePool( pTokenInfo);
7259 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7263 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7265 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7268 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7270 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7273 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7275 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7278 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7280 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7283 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7285 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7292 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7295 BOOLEAN bIsValid = TRUE;
7297 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7299 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7301 while( pCurrentDirEntry != NULL)
7304 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7308 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7313 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7314 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7317 if( pDirEntry == NULL)
7324 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7327 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7330 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7332 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7334 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7343 AFSReferenceCacheFileObject()
7346 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7347 FILE_OBJECT *pCacheFileObject = NULL;
7349 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7352 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7354 if( pCacheFileObject != NULL)
7356 ObReferenceObject( pCacheFileObject);
7359 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7361 return pCacheFileObject;
7365 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7368 ASSERT( CacheFileObject != NULL);
7370 ObDereferenceObject( CacheFileObject);
7376 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7379 NTSTATUS ntStatus = STATUS_SUCCESS;
7380 AFSDeviceExt *pControlDevExt = NULL;
7381 ULONG ulTimeIncrement = 0;
7386 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7388 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7390 AFSServerName = LibraryInit->AFSServerName;
7392 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7395 // Callbacks in the framework
7398 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7400 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7402 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7404 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7406 AFSExFreePool = LibraryInit->AFSExFreePool;
7408 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7410 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7412 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7414 if( LibraryInit->AFSCacheBaseAddress != NULL)
7417 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7419 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7421 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7425 // Initialize some flush parameters
7428 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7430 ulTimeIncrement = KeQueryTimeIncrement();
7432 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7433 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7434 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7435 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7436 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7439 // Initialize the global root entry
7442 ntStatus = AFSInitVolume( NULL,
7443 &LibraryInit->GlobalRootFid,
7446 if( !NT_SUCCESS( ntStatus))
7449 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7450 AFS_TRACE_LEVEL_ERROR,
7451 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7454 try_return( ntStatus);
7457 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7460 if( !NT_SUCCESS( ntStatus))
7463 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7464 AFS_TRACE_LEVEL_ERROR,
7465 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7468 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7470 try_return( ntStatus);
7474 // Update the node type code to AFS_ROOT_ALL
7477 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7479 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7482 // Drop the locks acquired above
7485 AFSInitVolumeWorker( AFSGlobalRoot);
7487 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7489 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7503 NTSTATUS ntStatus = STATUS_SUCCESS;
7504 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7509 if( AFSGlobalDotDirEntry != NULL)
7512 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
7514 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7516 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7518 ExFreePool( AFSGlobalDotDirEntry);
7520 AFSGlobalDotDirEntry = NULL;
7523 if( AFSGlobalDotDotDirEntry != NULL)
7526 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
7528 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7530 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7532 ExFreePool( AFSGlobalDotDotDirEntry);
7534 AFSGlobalDotDotDirEntry = NULL;
7537 if( AFSSpecialShareNames != NULL)
7540 pDirNode = AFSSpecialShareNames;
7542 while( pDirNode != NULL)
7545 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7547 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
7549 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7551 ExFreePool( pDirNode->NonPaged);
7553 ExFreePool( pDirNode);
7555 pDirNode = pLastDirNode;
7558 AFSSpecialShareNames = NULL;
7566 AFSDefaultLogMsg( IN ULONG Subsystem,
7572 NTSTATUS ntStatus = STATUS_SUCCESS;
7574 char chDebugBuffer[ 256];
7579 va_start( va_args, Format);
7581 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7586 if( NT_SUCCESS( ntStatus))
7588 DbgPrint( chDebugBuffer);
7598 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7599 IN ULONG InputBufferLength,
7600 IN AFSStatusInfoCB *StatusInfo,
7601 OUT ULONG *ReturnLength)
7604 NTSTATUS ntStatus = STATUS_SUCCESS;
7605 AFSFcb *pFcb = NULL;
7606 AFSVolumeCB *pVolumeCB = NULL;
7607 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7608 AFSObjectInfoCB *pObjectInfo = NULL;
7609 ULONGLONG ullIndex = 0;
7610 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7611 AFSNameArrayHdr *pNameArray = NULL;
7612 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7619 // If we are given a FID then look up the entry by that, otherwise
7623 if( GetStatusInfo->FileID.Cell != 0 &&
7624 GetStatusInfo->FileID.Volume != 0 &&
7625 GetStatusInfo->FileID.Vnode != 0 &&
7626 GetStatusInfo->FileID.Unique != 0)
7629 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7632 // Locate the volume node
7635 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7637 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7639 (AFSBTreeEntry **)&pVolumeCB);
7641 if( pVolumeCB != NULL)
7644 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7646 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7647 AFS_TRACE_LEVEL_VERBOSE,
7648 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7653 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7655 if( !NT_SUCCESS( ntStatus) ||
7658 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7661 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
7664 pObjectInfo = &pVolumeCB->ObjectInformation;
7666 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7668 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7673 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
7676 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7678 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7679 AFS_TRACE_LEVEL_VERBOSE,
7680 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7684 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
7686 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
7688 (AFSBTreeEntry **)&pObjectInfo);
7690 if( pObjectInfo != NULL)
7694 // Reference the node so it won't be torn down
7697 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7699 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7700 AFS_TRACE_LEVEL_VERBOSE,
7701 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
7706 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
7708 if( !NT_SUCCESS( ntStatus) ||
7709 pObjectInfo == NULL)
7711 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7718 if( GetStatusInfo->FileNameLength == 0 ||
7719 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
7721 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7724 uniFullPathName.Length = GetStatusInfo->FileNameLength;
7725 uniFullPathName.MaximumLength = uniFullPathName.Length;
7727 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
7730 // This name should begin with the \afs server so parse it off and check it
7733 FsRtlDissectName( uniFullPathName,
7737 if( RtlCompareUnicodeString( &uniComponentName,
7741 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7742 AFS_TRACE_LEVEL_ERROR,
7743 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
7746 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
7749 uniFullPathName = uniRemainingPath;
7751 uniParsedName = uniFullPathName;
7757 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7760 if( pNameArray == NULL)
7762 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7765 pVolumeCB = AFSGlobalRoot;
7767 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7770 // Increment the ref count on the volume and dir entry for correct processing below
7773 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7775 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7776 AFS_TRACE_LEVEL_VERBOSE,
7777 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7781 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
7783 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7784 AFS_TRACE_LEVEL_VERBOSE,
7785 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7786 &pParentDirEntry->NameInformation.FileName,
7791 ntStatus = AFSLocateNameEntry( NULL,
7796 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
7797 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
7803 if( !NT_SUCCESS( ntStatus))
7807 // The volume lock was released on failure above
7808 // Except for STATUS_OBJECT_NAME_NOT_FOUND
7811 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
7814 if( pVolumeCB != NULL)
7817 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7819 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7820 AFS_TRACE_LEVEL_VERBOSE,
7821 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7826 if( pDirectoryEntry != NULL)
7829 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7831 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7832 AFS_TRACE_LEVEL_VERBOSE,
7833 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7834 &pDirectoryEntry->NameInformation.FileName,
7842 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
7844 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7845 AFS_TRACE_LEVEL_VERBOSE,
7846 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7847 &pParentDirEntry->NameInformation.FileName,
7856 try_return( ntStatus);
7860 // Remove the reference made above
7863 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7865 pObjectInfo = pDirectoryEntry->ObjectInformation;
7867 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7869 if( pVolumeCB != NULL)
7872 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7874 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7875 AFS_TRACE_LEVEL_VERBOSE,
7876 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
7878 pVolumeCB->VolumeReferenceCount);
7883 // At this point we have an object info block, return the information
7886 StatusInfo->FileId = pObjectInfo->FileId;
7888 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
7890 StatusInfo->Expiration = pObjectInfo->Expiration;
7892 StatusInfo->DataVersion = pObjectInfo->DataVersion;
7894 StatusInfo->FileType = pObjectInfo->FileType;
7896 StatusInfo->ObjectFlags = pObjectInfo->Flags;
7898 StatusInfo->CreationTime = pObjectInfo->CreationTime;
7900 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
7902 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
7904 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
7906 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
7908 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
7910 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
7912 StatusInfo->EaSize = pObjectInfo->EaSize;
7914 StatusInfo->Links = pObjectInfo->Links;
7917 // Return the information length
7920 *ReturnLength = sizeof( AFSStatusInfoCB);
7924 if( pObjectInfo != NULL)
7927 lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
7930 if( pNameArray != NULL)
7933 AFSFreeNameArray( pNameArray);
7941 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
7942 IN UNICODE_STRING *ComponentName)
7945 NTSTATUS ntStatus = STATUS_SUCCESS;
7946 AFSDirectoryCB *pDirEntry = NULL;
7954 // Search for the entry in the parent
7957 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7958 AFS_TRACE_LEVEL_VERBOSE_2,
7959 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
7962 ulCRC = AFSGenerateCRC( ComponentName,
7965 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7968 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7972 if( pDirEntry == NULL)
7976 // Missed so perform a case insensitive lookup
7979 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7980 AFS_TRACE_LEVEL_VERBOSE_2,
7981 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
7984 ulCRC = AFSGenerateCRC( ComponentName,
7987 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7991 if( pDirEntry == NULL)
7995 // OK, if this component is a valid short name then try
7996 // a lookup in the short name tree
7999 if( RtlIsNameLegalDOS8Dot3( ComponentName,
8004 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8005 AFS_TRACE_LEVEL_VERBOSE_2,
8006 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8009 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8016 if( pDirEntry != NULL)
8018 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
8021 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8023 if( pDirEntry == NULL)
8026 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8027 AFS_TRACE_LEVEL_VERBOSE_2,
8028 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
8031 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8035 // We have the symlink object but previously failed to process it so return access
8039 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8040 AFS_TRACE_LEVEL_VERBOSE_2,
8041 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8044 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8046 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
8057 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8058 OUT UNICODE_STRING *ComponentName)
8061 NTSTATUS ntStatus = STATUS_SUCCESS;
8062 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8064 uniFullPathName = *FullPathName;
8069 FsRtlDissectName( uniFullPathName,
8073 if( uniRemainingPath.Length == 0)
8078 uniFullPathName = uniRemainingPath;
8081 if( uniComponentName.Length > 0)
8083 *ComponentName = uniComponentName;
8090 AFSDumpTraceFiles_Default()
8096 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8099 BOOLEAN bIsValidName = TRUE;
8105 while( usIndex < FileName->Length/sizeof( WCHAR))
8108 if( FileName->Buffer[ usIndex] == L':' ||
8109 FileName->Buffer[ usIndex] == L'*' ||
8110 FileName->Buffer[ usIndex] == L'?' ||
8111 FileName->Buffer[ usIndex] == L'"' ||
8112 FileName->Buffer[ usIndex] == L'<' ||
8113 FileName->Buffer[ usIndex] == L'>')
8115 bIsValidName = FALSE;
8123 return bIsValidName;
8127 AFSCreateDefaultSecurityDescriptor()
8130 NTSTATUS ntStatus = STATUS_SUCCESS;
8132 ULONG ulSACLSize = 0;
8133 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8134 ULONG ulACESize = 0;
8135 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8136 ULONG ulSDLength = 0;
8137 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8138 PSID pWorldSID = NULL;
8139 ULONG *pulSubAuthority = NULL;
8140 ULONG ulWorldSIDLEngth = 0;
8145 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8147 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8149 AFS_GENERIC_MEMORY_29_TAG);
8151 if( pWorldSID == NULL)
8153 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8154 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8157 RtlZeroMemory( pWorldSID,
8160 RtlInitializeSid( pWorldSID,
8161 &SeWorldSidAuthority,
8164 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8165 *pulSubAuthority = SECURITY_WORLD_RID;
8167 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8170 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8175 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8177 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8179 AFS_GENERIC_MEMORY_29_TAG);
8184 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8186 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8189 RtlZeroMemory( pACE,
8192 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8193 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8194 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8195 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8197 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8199 SeExports->SeLowMandatorySid);
8201 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8202 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8204 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8206 AFS_GENERIC_MEMORY_29_TAG);
8211 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8213 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8216 ntStatus = RtlCreateAcl( pSACL,
8220 if( !NT_SUCCESS( ntStatus))
8223 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8226 try_return( ntStatus);
8229 ntStatus = RtlAddAce( pSACL,
8233 pACE->Header.AceSize);
8235 if( !NT_SUCCESS( ntStatus))
8238 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8241 try_return( ntStatus);
8245 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8246 sizeof( SECURITY_DESCRIPTOR),
8247 AFS_GENERIC_MEMORY_27_TAG);
8249 if( pSecurityDescr == NULL)
8252 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8254 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8257 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8258 SECURITY_DESCRIPTOR_REVISION);
8260 if( !NT_SUCCESS( ntStatus))
8263 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8266 try_return( ntStatus);
8269 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8271 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8276 if( !NT_SUCCESS( ntStatus))
8279 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8282 try_return( ntStatus);
8287 // Add in the group and owner to the SD
8290 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8292 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8296 if( !NT_SUCCESS( ntStatus))
8299 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8302 try_return( ntStatus);
8306 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8310 if( !NT_SUCCESS( ntStatus))
8313 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8316 try_return( ntStatus);
8319 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8322 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8324 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8327 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8329 AFS_GENERIC_MEMORY_27_TAG);
8331 if( pRelativeSecurityDescr == NULL)
8334 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8336 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8339 ulSDLength = PAGE_SIZE;
8341 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8342 pRelativeSecurityDescr,
8345 if( !NT_SUCCESS( ntStatus))
8348 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8351 try_return( ntStatus);
8354 AFSDefaultSD = pRelativeSecurityDescr;
8358 if( !NT_SUCCESS( ntStatus))
8361 if( pRelativeSecurityDescr != NULL)
8363 ExFreePool( pRelativeSecurityDescr);
8367 if( pSecurityDescr != NULL)
8369 ExFreePool( pSecurityDescr);
8382 if( pWorldSID != NULL)
8384 ExFreePool( pWorldSID);
8392 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8393 OUT UNICODE_STRING *ParentPath)
8398 *ParentPath = *FullFileName;
8401 // If the final character is a \, jump over it
8404 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8406 ParentPath->Length -= sizeof( WCHAR);
8409 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8411 ParentPath->Length -= sizeof( WCHAR);
8415 // And the separator
8418 ParentPath->Length -= sizeof( WCHAR);
8424 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8425 IN AFSObjectInfoCB *ObjectInfo,
8426 IN BOOLEAN WriteAccess,
8427 OUT GUID *AuthGroup)
8430 NTSTATUS ntStatus = STATUS_SUCCESS;
8431 GUID stAuthGroup, stZeroAuthGroup;
8432 BOOLEAN bFoundAuthGroup = FALSE;
8433 AFSCcb *pCcb = NULL;
8439 RtlZeroMemory( &stAuthGroup,
8442 RtlZeroMemory( &stZeroAuthGroup,
8448 if( ObjectInfo != NULL &&
8449 ObjectInfo->Fcb != NULL)
8451 pFcb = ObjectInfo->Fcb;
8458 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8461 pCcb = Fcb->CcbListHead;
8463 while( pCcb != NULL)
8467 pCcb->GrantedAccess & FILE_WRITE_DATA)
8469 RtlCopyMemory( &stAuthGroup,
8473 bFoundAuthGroup = TRUE;
8477 else if( pCcb->GrantedAccess & FILE_READ_DATA)
8480 // At least get the read-only access
8483 RtlCopyMemory( &stAuthGroup,
8487 bFoundAuthGroup = TRUE;
8490 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
8493 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
8496 if( !bFoundAuthGroup)
8499 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
8500 (ULONGLONG)PsGetCurrentThreadId(),
8503 if( RtlCompareMemory( &stZeroAuthGroup,
8505 sizeof( GUID)) == sizeof( GUID))
8508 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
8510 try_return( ntStatus = STATUS_ACCESS_DENIED);
8514 RtlCopyMemory( AuthGroup,
8527 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
8528 IN ULONG InvalidateReason)
8531 NTSTATUS ntStatus = STATUS_SUCCESS;
8532 IO_STATUS_BLOCK stIoStatus;
8535 ULONG ulProcessCount = 0;
8541 switch( InvalidateReason)
8544 case AFS_INVALIDATE_DELETED:
8547 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8548 ObjectInfo->Fcb != NULL)
8553 // Clear out the extents
8554 // And get rid of them (note this involves waiting
8555 // for any writes or reads to the cache to complete)
8558 (VOID) AFSTearDownFcbExtents( ObjectInfo->Fcb,
8565 case AFS_INVALIDATE_DATA_VERSION:
8568 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8569 ObjectInfo->Fcb != NULL)
8572 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
8575 AFSLockForExtentsTrim( ObjectInfo->Fcb);
8580 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
8584 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
8586 while( ulProcessCount < ulCount)
8588 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
8590 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
8592 CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
8593 &pEntry->FileOffset,
8602 __except( EXCEPTION_EXECUTE_HANDLER)
8605 ntStatus = GetExceptionCode();
8608 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
8610 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
8612 AFSReleaseCleanExtents( ObjectInfo->Fcb,
8626 if( ObjectInfo != NULL)
8628 InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);