2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSGeneric.cpp
39 #include "AFSCommon.h"
42 // Function: AFSExceptionFilter
46 // This function is the exception handler
50 // A status is returned for the function
54 AFSExceptionFilter( IN ULONG Code,
55 IN PEXCEPTION_POINTERS ExceptPtrs)
58 PEXCEPTION_RECORD ExceptRec;
64 ExceptRec = ExceptPtrs->ExceptionRecord;
66 Context = ExceptPtrs->ContextRecord;
70 "AFSExceptionFilter (Library) - EXR %p CXR %p Code %08lX Address %p Routine %p\n",
73 ExceptRec->ExceptionCode,
74 ExceptRec->ExceptionAddress,
75 (void *)AFSExceptionFilter);
77 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
79 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
80 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
82 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
84 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
87 KeBugCheck( (ULONG)-2);
95 __except( EXCEPTION_EXECUTE_HANDLER)
101 return EXCEPTION_EXECUTE_HANDLER;
105 // Function: AFSLibExAllocatePoolWithTag()
107 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
108 // is configured on, then bugcheck the system if
109 // a memory allocation fails. The routine should be
110 // used for all memory allocations that are to be freed
111 // when the library is unloaded. Memory allocations that
112 // are to survive library unload and reload should be
113 // performed using AFSExAllocatePoolWithTag() which is
114 // provided by the AFS Framework.
117 // POOL_TYPE PoolType - Paged or NonPaged
118 // SIZE_T NumberOfBytes - requested allocation size
119 // ULONG Tag - Pool Allocation Tag to be applied for tracking
122 // void * - the memory allocation
126 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
127 IN SIZE_T NumberOfBytes,
131 void *pBuffer = NULL;
133 pBuffer = ExAllocatePoolWithTag( PoolType,
140 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
143 KeBugCheck( (ULONG)-2);
150 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
154 PsGetCurrentThread());
164 // Function: AFSAcquireExcl()
166 // Purpose: Called to acquire a resource exclusive with optional wait
169 // PERESOURCE Resource - Resource to acquire
170 // BOOLEAN Wait - Whether to block
173 // BOOLEAN - Whether the mask was acquired
177 AFSAcquireExcl( IN PERESOURCE Resource,
181 BOOLEAN bStatus = FALSE;
184 // Normal kernel APCs must be disabled before calling
185 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
188 KeEnterCriticalRegion();
190 bStatus = ExAcquireResourceExclusiveLite( Resource,
196 KeLeaveCriticalRegion();
203 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
207 BOOLEAN bStatus = FALSE;
209 KeEnterCriticalRegion();
211 bStatus = ExAcquireSharedStarveExclusive( Resource,
217 KeLeaveCriticalRegion();
224 // Function: AFSAcquireShared()
226 // Purpose: Called to acquire a resource shared with optional wait
229 // PERESOURCE Resource - Resource to acquire
230 // BOOLEAN Wait - Whether to block
233 // BOOLEAN - Whether the mask was acquired
237 AFSAcquireShared( IN PERESOURCE Resource,
241 BOOLEAN bStatus = FALSE;
243 KeEnterCriticalRegion();
245 bStatus = ExAcquireResourceSharedLite( Resource,
251 KeLeaveCriticalRegion();
258 // Function: AFSReleaseResource()
260 // Purpose: Called to release a resource
263 // PERESOURCE Resource - Resource to release
270 AFSReleaseResource( IN PERESOURCE Resource)
273 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
274 AFS_TRACE_LEVEL_VERBOSE,
275 "AFSReleaseResource Releasing lock %08lX Thread %08lX\n",
277 PsGetCurrentThread());
279 ExReleaseResourceLite( Resource);
281 KeLeaveCriticalRegion();
287 AFSConvertToShared( IN PERESOURCE Resource)
290 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
291 AFS_TRACE_LEVEL_VERBOSE,
292 "AFSConvertToShared Converting lock %08lX Thread %08lX\n",
294 PsGetCurrentThread());
296 ExConvertExclusiveToSharedLite( Resource);
302 // Function: AFSCompleteRequest
306 // This function completes irps
310 // A status is returned for the function
314 AFSCompleteRequest( IN PIRP Irp,
318 Irp->IoStatus.Status = Status;
320 IoCompleteRequest( Irp,
327 // Function: AFSGenerateCRC
331 // Given a device and filename this function generates a CRC
335 // A status is returned for the function
339 AFSGenerateCRC( IN PUNICODE_STRING FileName,
340 IN BOOLEAN UpperCaseName)
344 NTSTATUS ntStatus = STATUS_SUCCESS;
346 ntStatus = RtlHashUnicodeString( FileName,
348 HASH_STRING_ALGORITHM_DEFAULT,
351 if( !NT_SUCCESS( ntStatus))
360 AFSLockSystemBuffer( IN PIRP Irp,
364 NTSTATUS Status = STATUS_SUCCESS;
365 void *pAddress = NULL;
367 if( Irp->MdlAddress != NULL)
370 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
373 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
376 pAddress = Irp->AssociatedIrp.SystemBuffer;
378 else if( Irp->UserBuffer != NULL)
381 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
387 if( Irp->MdlAddress != NULL)
391 // Lock the new Mdl in memory.
396 PIO_STACK_LOCATION pIoStack;
397 pIoStack = IoGetCurrentIrpStackLocation( Irp);
400 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
401 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
403 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
406 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
409 IoFreeMdl( Irp->MdlAddress );
410 Irp->MdlAddress = NULL;
420 AFSLockUserBuffer( IN void *UserBuffer,
421 IN ULONG BufferLength,
425 NTSTATUS ntStatus = STATUS_SUCCESS;
426 void *pAddress = NULL;
432 pMdl = IoAllocateMdl( UserBuffer,
441 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
445 // Lock the new Mdl in memory.
451 MmProbeAndLockPages( pMdl,
455 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
458 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
481 AFSMapToService( IN PIRP Irp,
485 NTSTATUS ntStatus = STATUS_SUCCESS;
486 void *pMappedBuffer = NULL;
487 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
493 if( pDevExt->Specific.Control.ServiceProcess == NULL)
496 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
499 if( Irp->MdlAddress == NULL)
502 if( AFSLockSystemBuffer( Irp,
506 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
511 // Attach to the service process for mapping
514 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
515 (PRKAPC_STATE)&stApcState);
517 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
524 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
531 return pMappedBuffer;
535 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
539 NTSTATUS ntStatus = STATUS_SUCCESS;
540 void *pMappedBuffer = NULL;
541 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
547 if( pDevExt->Specific.Control.ServiceProcess == NULL)
550 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
557 // Attach to the service process for mapping
560 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
561 (PRKAPC_STATE)&stApcState);
563 MmUnmapLockedPages( MappedBuffer,
566 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
578 AFSInitializeLibraryDevice()
581 NTSTATUS ntStatus = STATUS_SUCCESS;
582 AFSDeviceExt *pDeviceExt = NULL;
587 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
590 // The PIOCtl file name
593 RtlInitUnicodeString( &AFSPIOCtlName,
594 AFS_PIOCTL_FILE_INTERFACE_NAME);
597 // And the global root share name
600 RtlInitUnicodeString( &AFSGlobalRootName,
601 AFS_GLOBAL_ROOT_SHARE_NAME);
609 AFSRemoveLibraryDevice()
612 NTSTATUS ntStatus = STATUS_SUCCESS;
623 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
627 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
628 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
630 AFSCompleteRequest( Irp,
637 AFSInitializeGlobalDirectoryEntries()
640 NTSTATUS ntStatus = STATUS_SUCCESS;
641 AFSDirectoryCB *pDirNode = NULL;
642 ULONG ulEntryLength = 0;
643 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
644 AFSObjectInfoCB *pObjectInfoCB = NULL;
645 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
652 // Initialize the global . entry
655 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
658 if( pObjectInfoCB == NULL)
661 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
662 AFS_TRACE_LEVEL_ERROR,
663 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
666 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
669 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
671 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
672 AFS_TRACE_LEVEL_VERBOSE,
673 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
677 ntStatus = STATUS_SUCCESS;
679 ulEntryLength = sizeof( AFSDirectoryCB) +
682 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
686 if( pDirNode == NULL)
689 AFSDeleteObjectInfo( pObjectInfoCB);
691 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
692 AFS_TRACE_LEVEL_ERROR,
693 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
695 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
698 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
699 sizeof( AFSNonPagedDirectoryCB),
700 AFS_DIR_ENTRY_NP_TAG);
702 if( pNonPagedDirEntry == NULL)
705 ExFreePool( pDirNode);
707 AFSDeleteObjectInfo( pObjectInfoCB);
709 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
710 AFS_TRACE_LEVEL_ERROR,
711 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
713 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
716 RtlZeroMemory( pDirNode,
719 RtlZeroMemory( pNonPagedDirEntry,
720 sizeof( AFSNonPagedDirectoryCB));
722 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
724 pDirNode->NonPaged = pNonPagedDirEntry;
726 pDirNode->ObjectInformation = pObjectInfoCB;
732 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
734 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
737 // Setup the names in the entry
740 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
742 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
744 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
746 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
749 // Populate the rest of the data
752 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
754 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
756 AFSGlobalDotDirEntry = pDirNode;
762 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
765 if( pObjectInfoCB == NULL)
768 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
769 AFS_TRACE_LEVEL_ERROR,
770 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
773 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
776 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
778 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
779 AFS_TRACE_LEVEL_VERBOSE,
780 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
784 ntStatus = STATUS_SUCCESS;
786 ulEntryLength = sizeof( AFSDirectoryCB) +
787 ( 2 * sizeof( WCHAR));
789 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
793 if( pDirNode == NULL)
796 AFSDeleteObjectInfo( pObjectInfoCB);
798 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
801 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
802 sizeof( AFSNonPagedDirectoryCB),
803 AFS_DIR_ENTRY_NP_TAG);
805 if( pNonPagedDirEntry == NULL)
808 ExFreePool( pDirNode);
810 AFSDeleteObjectInfo( pObjectInfoCB);
812 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
815 RtlZeroMemory( pDirNode,
818 RtlZeroMemory( pNonPagedDirEntry,
819 sizeof( AFSNonPagedDirectoryCB));
821 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
823 pDirNode->NonPaged = pNonPagedDirEntry;
825 pDirNode->ObjectInformation = pObjectInfoCB;
831 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
833 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
836 // Setup the names in the entry
839 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
841 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
843 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
845 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
847 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
850 // Populate the rest of the data
853 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
855 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
857 AFSGlobalDotDotDirEntry = pDirNode;
861 if( !NT_SUCCESS( ntStatus))
864 if( AFSGlobalDotDirEntry != NULL)
867 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
869 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
871 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
873 ExFreePool( AFSGlobalDotDirEntry);
875 AFSGlobalDotDirEntry = NULL;
878 if( AFSGlobalDotDotDirEntry != NULL)
881 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
883 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
885 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
887 ExFreePool( AFSGlobalDotDotDirEntry);
889 AFSGlobalDotDotDirEntry = NULL;
898 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
899 IN PUNICODE_STRING FileName,
900 IN PUNICODE_STRING TargetName,
901 IN AFSDirEnumEntry *DirEnumEntry,
905 AFSDirectoryCB *pDirNode = NULL;
906 NTSTATUS ntStatus = STATUS_SUCCESS;
907 ULONG ulEntryLength = 0;
908 AFSDirEnumEntry *pDirEnumCB = NULL;
909 AFSFileID stTargetFileID;
911 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
912 AFSObjectInfoCB *pObjectInfoCB = NULL;
913 BOOLEAN bAllocatedObjectCB = FALSE;
914 ULONGLONG ullIndex = 0;
915 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
921 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
922 AFS_TRACE_LEVEL_VERBOSE,
923 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
925 ParentObjectInfo->FileId.Cell,
926 ParentObjectInfo->FileId.Volume,
927 ParentObjectInfo->FileId.Vnode,
928 ParentObjectInfo->FileId.Unique);
931 // First thing is to locate/create our object information block
935 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
938 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
940 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
942 (AFSBTreeEntry **)&pObjectInfoCB);
944 if( !NT_SUCCESS( ntStatus) ||
945 pObjectInfoCB == NULL)
949 // Allocate our object info cb
952 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
955 if( pObjectInfoCB == NULL)
958 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
960 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
963 bAllocatedObjectCB = TRUE;
965 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
966 AFS_TRACE_LEVEL_VERBOSE,
967 "AFSInitDirEntry initialized object %08lX Parent Object %08lX for %wZ\n",
973 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
975 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
976 AFS_TRACE_LEVEL_VERBOSE,
977 "AFSInitDirEntry Increment count on object %08lX Cnt %d\n",
981 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
983 ntStatus = STATUS_SUCCESS;
985 ulEntryLength = sizeof( AFSDirectoryCB) +
988 if( TargetName != NULL)
991 ulEntryLength += TargetName->Length;
994 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
998 if( pDirNode == NULL)
1001 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1004 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1005 sizeof( AFSNonPagedDirectoryCB),
1006 AFS_DIR_ENTRY_NP_TAG);
1008 if( pNonPagedDirEntry == NULL)
1011 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1014 RtlZeroMemory( pDirNode,
1017 RtlZeroMemory( pNonPagedDirEntry,
1018 sizeof( AFSNonPagedDirectoryCB));
1020 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1022 pDirNode->NonPaged = pNonPagedDirEntry;
1024 pDirNode->ObjectInformation = pObjectInfoCB;
1027 // Set valid entry and NOT_IN_PARENT flag
1030 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1032 pDirNode->FileIndex = FileIndex;
1035 // Setup the names in the entry
1038 if( FileName->Length > 0)
1041 pDirNode->NameInformation.FileName.Length = FileName->Length;
1043 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1045 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1047 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1049 pDirNode->NameInformation.FileName.Length);
1052 // Create a CRC for the file
1055 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1058 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1062 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1063 AFS_TRACE_LEVEL_VERBOSE,
1064 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1067 ParentObjectInfo->FileId.Cell,
1068 ParentObjectInfo->FileId.Volume,
1069 ParentObjectInfo->FileId.Vnode,
1070 ParentObjectInfo->FileId.Unique);
1072 if( TargetName != NULL &&
1073 TargetName->Length > 0)
1076 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1078 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1080 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1081 sizeof( AFSDirectoryCB) +
1082 pDirNode->NameInformation.FileName.Length);
1084 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1086 pDirNode->NameInformation.TargetName.Length);
1090 // If we allocated the object information cb then update the information
1093 if( bAllocatedObjectCB)
1097 // Populate the rest of the data
1100 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1102 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1104 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1106 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1108 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1110 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1112 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1114 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1116 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1118 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1120 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1123 pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1126 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1127 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1130 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1133 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1136 // Object specific information
1139 pObjectInfoCB->Links = DirEnumEntry->Links;
1141 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1143 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1146 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1147 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1151 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1152 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1153 pObjectInfoCB->TargetFileId.Unique == 0 &&
1154 pDirNode->NameInformation.TargetName.Length == 0)
1158 // This will ensure we perform a validation on the node
1161 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1164 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1167 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1173 if( !NT_SUCCESS( ntStatus))
1176 if( pNonPagedDirEntry != NULL)
1179 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1181 AFSExFreePool( pNonPagedDirEntry);
1184 if( pDirNode != NULL)
1187 AFSExFreePool( pDirNode);
1193 // Dereference our object info block if we have one
1196 if( pObjectInfoCB != NULL)
1199 lCount = InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
1201 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1202 AFS_TRACE_LEVEL_VERBOSE,
1203 "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
1207 if( bAllocatedObjectCB)
1210 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1212 AFSDeleteObjectInfo( pObjectInfoCB);
1222 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1223 IN BOOLEAN DirectoryEntry)
1226 BOOLEAN bReturn = TRUE;
1227 ACCESS_MASK stAccessMask = 0;
1230 // Get rid of anything we don't know about
1233 DesiredAccess = (DesiredAccess &
1239 ACCESS_SYSTEM_SECURITY |
1243 FILE_READ_ATTRIBUTES |
1244 FILE_WRITE_ATTRIBUTES |
1245 FILE_LIST_DIRECTORY |
1251 // Our 'read only' access mask. These are the accesses we will
1252 // allow for a read only file
1255 stAccessMask = DELETE |
1260 ACCESS_SYSTEM_SECURITY |
1264 FILE_READ_ATTRIBUTES |
1265 FILE_WRITE_ATTRIBUTES |
1267 FILE_LIST_DIRECTORY |
1271 // For a directory, add in the directory specific accesses
1277 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1282 if( FlagOn( DesiredAccess, ~stAccessMask))
1286 // A write access is set ...
1296 AFSEvaluateNode( IN GUID *AuthGroup,
1297 IN AFSDirectoryCB *DirEntry)
1300 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1301 NTSTATUS ntStatus = STATUS_SUCCESS;
1302 AFSDirEnumEntry *pDirEntry = NULL;
1303 UNICODE_STRING uniTargetName;
1308 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1313 if( !NT_SUCCESS( ntStatus))
1316 try_return( ntStatus);
1319 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1321 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1323 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1325 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1327 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1329 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1331 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1333 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1335 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1337 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1339 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1341 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1344 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1347 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1348 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1351 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1354 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1356 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1359 // If we have a target name then see if it needs updating ...
1362 if( pDirEntry->TargetNameLength > 0)
1366 // Update the target name information if needed
1369 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1371 uniTargetName.MaximumLength = uniTargetName.Length;
1373 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1375 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1378 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1379 RtlCompareUnicodeString( &uniTargetName,
1380 &DirEntry->NameInformation.TargetName,
1385 // Update the target name
1388 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1390 uniTargetName.Buffer,
1391 uniTargetName.Length);
1393 if( !NT_SUCCESS( ntStatus))
1396 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1398 try_return( ntStatus);
1402 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1407 if( pDirEntry != NULL)
1410 AFSExFreePool( pDirEntry);
1418 AFSValidateSymLink( IN GUID *AuthGroup,
1419 IN AFSDirectoryCB *DirEntry)
1422 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1423 NTSTATUS ntStatus = STATUS_SUCCESS;
1424 AFSDirEnumEntry *pDirEntry = NULL;
1425 UNICODE_STRING uniTargetName;
1430 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1435 if( !NT_SUCCESS( ntStatus))
1438 try_return( ntStatus);
1441 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1442 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1445 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1448 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1450 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1452 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1455 // Update the target name information if needed
1458 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1460 uniTargetName.MaximumLength = uniTargetName.Length;
1462 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1464 if( uniTargetName.Length > 0)
1467 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1470 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1471 RtlCompareUnicodeString( &uniTargetName,
1472 &DirEntry->NameInformation.TargetName,
1477 // Update the target name
1480 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1482 uniTargetName.Buffer,
1483 uniTargetName.Length);
1485 if( !NT_SUCCESS( ntStatus))
1488 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1490 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1494 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1498 // If the FileType is the same then nothing to do since it IS
1502 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1505 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1507 try_return( ntStatus = STATUS_SUCCESS);
1510 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1512 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1514 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1516 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1518 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1520 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1522 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1524 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1526 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1529 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1532 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1533 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1536 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1539 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1541 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1545 if( pDirEntry != NULL)
1548 AFSExFreePool( pDirEntry);
1556 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1560 NTSTATUS ntStatus = STATUS_SUCCESS;
1561 IO_STATUS_BLOCK stIoStatus;
1564 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1565 AFS_TRACE_LEVEL_VERBOSE,
1566 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1567 (*ppObjectInfo)->FileType,
1568 (*ppObjectInfo)->FileId.Cell,
1569 (*ppObjectInfo)->FileId.Volume,
1570 (*ppObjectInfo)->FileId.Vnode,
1571 (*ppObjectInfo)->FileId.Unique,
1574 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1575 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1576 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1579 // We only act on the mount point itself, not the target. If the
1580 // node has been deleted then mark it as such otherwise indicate
1581 // it requires verification
1584 if( Reason == AFS_INVALIDATE_DELETED)
1586 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1591 if( Reason == AFS_INVALIDATE_FLUSHED)
1594 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1596 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1599 (*ppObjectInfo)->Expiration.QuadPart = 0;
1601 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1603 (*ppObjectInfo)->TargetFileId.Unique = 0;
1605 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1606 AFS_TRACE_LEVEL_VERBOSE,
1607 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1608 (*ppObjectInfo)->FileId.Cell,
1609 (*ppObjectInfo)->FileId.Volume,
1610 (*ppObjectInfo)->FileId.Vnode,
1611 (*ppObjectInfo)->FileId.Unique);
1613 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1616 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1618 if( Reason == AFS_INVALIDATE_CREDS)
1620 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1623 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1624 Reason == AFS_INVALIDATE_FLUSHED)
1626 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1630 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1633 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1635 FILE_NOTIFY_CHANGE_FILE_NAME |
1636 FILE_NOTIFY_CHANGE_ATTRIBUTES,
1637 FILE_ACTION_MODIFIED);
1639 try_return( ntStatus);
1643 // Depending on the reason for invalidation then perform work on the node
1649 case AFS_INVALIDATE_DELETED:
1653 // Mark this node as invalid
1656 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1658 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1659 AFS_TRACE_LEVEL_VERBOSE,
1660 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1661 (*ppObjectInfo)->FileId.Cell,
1662 (*ppObjectInfo)->FileId.Volume,
1663 (*ppObjectInfo)->FileId.Vnode,
1664 (*ppObjectInfo)->FileId.Unique);
1666 if( (*ppObjectInfo)->ParentObjectInformation != NULL)
1669 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1670 AFS_TRACE_LEVEL_VERBOSE,
1671 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1672 (*ppObjectInfo)->ParentObjectInformation->FileId.Cell,
1673 (*ppObjectInfo)->ParentObjectInformation->FileId.Volume,
1674 (*ppObjectInfo)->ParentObjectInformation->FileId.Vnode,
1675 (*ppObjectInfo)->ParentObjectInformation->FileId.Unique);
1677 SetFlag( (*ppObjectInfo)->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1679 (*ppObjectInfo)->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1681 (*ppObjectInfo)->ParentObjectInformation->Expiration.QuadPart = 0;
1684 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1686 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1690 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1693 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1696 FILE_ACTION_REMOVED);
1698 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1701 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1707 case AFS_INVALIDATE_FLUSHED:
1710 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1711 (*ppObjectInfo)->Fcb != NULL)
1714 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1715 AFS_TRACE_LEVEL_VERBOSE,
1716 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1717 (*ppObjectInfo)->FileId.Cell,
1718 (*ppObjectInfo)->FileId.Volume,
1719 (*ppObjectInfo)->FileId.Vnode,
1720 (*ppObjectInfo)->FileId.Unique);
1722 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1728 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1733 if( !NT_SUCCESS( stIoStatus.Status))
1736 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1737 AFS_TRACE_LEVEL_ERROR,
1738 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1739 (*ppObjectInfo)->FileId.Cell,
1740 (*ppObjectInfo)->FileId.Volume,
1741 (*ppObjectInfo)->FileId.Vnode,
1742 (*ppObjectInfo)->FileId.Unique,
1744 stIoStatus.Information);
1746 ntStatus = stIoStatus.Status;
1749 CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1754 __except( EXCEPTION_EXECUTE_HANDLER)
1757 ntStatus = GetExceptionCode();
1760 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->Resource);
1763 // Clear out the extents
1764 // Get rid of them (note this involves waiting
1765 // for any writes or reads to the cache to complete)
1768 (VOID) AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1772 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1775 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1778 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1779 AFS_TRACE_LEVEL_VERBOSE,
1780 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1781 (*ppObjectInfo)->FileId.Cell,
1782 (*ppObjectInfo)->FileId.Volume,
1783 (*ppObjectInfo)->FileId.Vnode,
1784 (*ppObjectInfo)->FileId.Unique);
1786 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1789 // Fall through to the default processing
1795 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1797 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1801 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1804 if( Reason == AFS_INVALIDATE_CREDS)
1806 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1809 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1811 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1815 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1818 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo)->ParentObjectInformation,
1821 FILE_ACTION_MODIFIED);
1824 // Indicate this node requires re-evaluation for the remaining reasons
1827 (*ppObjectInfo)->Expiration.QuadPart = 0;
1829 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1830 AFS_TRACE_LEVEL_VERBOSE,
1831 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1832 (*ppObjectInfo)->FileId.Cell,
1833 (*ppObjectInfo)->FileId.Volume,
1834 (*ppObjectInfo)->FileId.Vnode,
1835 (*ppObjectInfo)->FileId.Unique);
1837 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1839 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1840 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1841 ( Reason == AFS_INVALIDATE_CALLBACK ||
1842 Reason == AFS_INVALIDATE_EXPIRED))
1844 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1845 AFS_INVALIDATE_DATA_VERSION)))
1848 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1862 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1865 NTSTATUS ntStatus = STATUS_SUCCESS;
1866 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1867 AFSVolumeCB *pVolumeCB = NULL;
1868 AFSFcb *pTargetDcb = NULL;
1869 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1870 AFSDirectoryCB *pCurrentDirEntry = NULL;
1871 BOOLEAN bIsChild = FALSE;
1872 ULONGLONG ullIndex = 0;
1873 AFSObjectInfoCB *pObjectInfo = NULL;
1879 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1880 AFS_TRACE_LEVEL_VERBOSE,
1881 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
1882 InvalidateCB->FileID.Cell,
1883 InvalidateCB->FileID.Volume,
1884 InvalidateCB->FileID.Vnode,
1885 InvalidateCB->FileID.Unique,
1886 InvalidateCB->FileType,
1887 InvalidateCB->WholeVolume,
1888 InvalidateCB->Reason);
1891 // Need to locate the Fcb for the directory to purge
1894 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1895 AFS_TRACE_LEVEL_VERBOSE,
1896 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1897 &pDevExt->Specific.RDR.VolumeTreeLock,
1898 PsGetCurrentThread());
1901 // Starve any exclusive waiters on this paticular call
1904 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1907 // Locate the volume node
1910 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1912 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1914 (AFSBTreeEntry **)&pVolumeCB);
1916 if( pVolumeCB != NULL)
1919 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1921 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1922 AFS_TRACE_LEVEL_VERBOSE,
1923 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1928 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1930 if( !NT_SUCCESS( ntStatus) ||
1934 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1935 AFS_TRACE_LEVEL_WARNING,
1936 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1937 InvalidateCB->FileID.Cell,
1938 InvalidateCB->FileID.Volume,
1939 InvalidateCB->FileID.Vnode,
1940 InvalidateCB->FileID.Unique,
1943 try_return( ntStatus = STATUS_SUCCESS);
1947 // If this is a whole volume invalidation then go do it now
1950 if( InvalidateCB->WholeVolume)
1953 ntStatus = AFSInvalidateVolume( pVolumeCB,
1954 InvalidateCB->Reason);
1956 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1958 try_return( ntStatus);
1961 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
1964 pObjectInfo = &pVolumeCB->ObjectInformation;
1969 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1972 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1974 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1975 AFS_TRACE_LEVEL_VERBOSE,
1976 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
1978 pVolumeCB->VolumeReferenceCount);
1980 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
1982 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
1984 (AFSBTreeEntry **)&pObjectInfo);
1986 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1990 if( pObjectInfo != NULL)
1994 // Reference the node so it won't be torn down
1997 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
1999 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2000 AFS_TRACE_LEVEL_VERBOSE,
2001 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
2006 if( !NT_SUCCESS( ntStatus) ||
2007 pObjectInfo == NULL)
2010 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2011 AFS_TRACE_LEVEL_WARNING,
2012 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2013 InvalidateCB->FileID.Cell,
2014 InvalidateCB->FileID.Volume,
2015 InvalidateCB->FileID.Vnode,
2016 InvalidateCB->FileID.Unique,
2019 try_return( ntStatus = STATUS_SUCCESS);
2022 AFSInvalidateObject( &pObjectInfo,
2023 InvalidateCB->Reason);
2027 if( pObjectInfo != NULL)
2030 lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
2032 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2033 AFS_TRACE_LEVEL_VERBOSE,
2034 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
2044 AFSIsChildOfParent( IN AFSFcb *Dcb,
2048 BOOLEAN bIsChild = FALSE;
2049 AFSFcb *pCurrentFcb = Fcb;
2051 while( pCurrentFcb != NULL)
2054 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2062 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2070 AFSCreateHighIndex( IN AFSFileID *FileID)
2073 ULONGLONG ullIndex = 0;
2075 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2082 AFSCreateLowIndex( IN AFSFileID *FileID)
2085 ULONGLONG ullIndex = 0;
2087 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2093 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2094 IN ACCESS_MASK GrantedAccess,
2095 IN BOOLEAN DirectoryEntry)
2098 BOOLEAN bAccessGranted = TRUE;
2101 // Check if we are asking for read/write and granted only read only
2102 // NOTE: There will be more checks here
2105 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2107 AFSCheckForReadOnlyAccess( GrantedAccess,
2111 bAccessGranted = FALSE;
2114 return bAccessGranted;
2118 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2121 NTSTATUS ntStatus = STATUS_SUCCESS;
2122 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2128 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2130 if( AFSGlobalRoot == NULL)
2137 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2140 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2147 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2154 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2155 IN UNICODE_STRING *SubstituteName,
2156 IN ULONG StringIndex)
2159 NTSTATUS ntStatus = STATUS_SUCCESS;
2160 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2161 AFSSysNameCB *pSysName = NULL;
2162 ERESOURCE *pSysNameLock = NULL;
2165 UNICODE_STRING uniSysName;
2172 if( IoIs32bitProcess( NULL))
2175 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2177 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2182 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2184 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2188 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2190 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2194 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2195 AFS_TRACE_LEVEL_VERBOSE,
2196 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2198 PsGetCurrentThread());
2200 AFSAcquireShared( pSysNameLock,
2204 // Find where we are in the list
2207 while( pSysName != NULL &&
2208 ulIndex < StringIndex)
2211 pSysName = pSysName->fLink;
2216 if( pSysName == NULL)
2219 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2222 RtlInitUnicodeString( &uniSysName,
2225 // If it is a full component of @SYS then just substitue the
2229 if( RtlCompareUnicodeString( &uniSysName,
2234 SubstituteName->Length = pSysName->SysName.Length;
2235 SubstituteName->MaximumLength = SubstituteName->Length;
2237 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2238 SubstituteName->Length,
2239 AFS_SUBST_BUFFER_TAG);
2241 if( SubstituteName->Buffer == NULL)
2244 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2247 RtlCopyMemory( SubstituteName->Buffer,
2248 pSysName->SysName.Buffer,
2249 pSysName->SysName.Length);
2256 while( ComponentName->Buffer[ usIndex] != L'@')
2262 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2263 SubstituteName->MaximumLength = SubstituteName->Length;
2265 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2266 SubstituteName->Length,
2267 AFS_SUBST_BUFFER_TAG);
2269 if( SubstituteName->Buffer == NULL)
2272 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2275 RtlCopyMemory( SubstituteName->Buffer,
2276 ComponentName->Buffer,
2277 usIndex * sizeof( WCHAR));
2279 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2280 pSysName->SysName.Buffer,
2281 pSysName->SysName.Length);
2286 AFSReleaseResource( pSysNameLock);
2293 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2294 IN OUT UNICODE_STRING *ComponentName,
2295 IN UNICODE_STRING *SubstituteName,
2296 IN OUT UNICODE_STRING *RemainingPath,
2297 IN BOOLEAN FreePathName)
2300 NTSTATUS ntStatus = STATUS_SUCCESS;
2301 UNICODE_STRING uniPathName;
2302 USHORT usPrefixNameLen = 0;
2303 SHORT sNameLenDelta = 0;
2309 // If the passed in name can handle the additional length
2310 // then just moves things around
2313 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2315 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2317 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2320 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2323 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2324 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2325 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2328 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2329 SubstituteName->Buffer,
2330 SubstituteName->Length);
2332 FullPathName->Length += sNameLenDelta;
2334 ComponentName->Length += sNameLenDelta;
2336 ComponentName->MaximumLength = ComponentName->Length;
2338 if ( RemainingPath->Buffer)
2341 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2344 try_return( ntStatus);
2348 // Need to re-allocate the buffer
2351 uniPathName.Length = FullPathName->Length -
2352 ComponentName->Length +
2353 SubstituteName->Length;
2355 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2357 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2358 uniPathName.MaximumLength,
2359 AFS_NAME_BUFFER_FOUR_TAG);
2361 if( uniPathName.Buffer == NULL)
2364 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2367 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2369 usPrefixNameLen *= sizeof( WCHAR);
2371 RtlZeroMemory( uniPathName.Buffer,
2372 uniPathName.MaximumLength);
2374 RtlCopyMemory( uniPathName.Buffer,
2375 FullPathName->Buffer,
2378 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2379 SubstituteName->Buffer,
2380 SubstituteName->Length);
2382 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2385 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2386 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2387 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2390 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2392 ComponentName->Length += sNameLenDelta;
2394 ComponentName->MaximumLength = ComponentName->Length;
2396 if ( RemainingPath->Buffer)
2399 RemainingPath->Buffer = uniPathName.Buffer
2400 + (RemainingPath->Buffer - FullPathName->Buffer)
2401 + sNameLenDelta/sizeof( WCHAR);
2406 AFSExFreePool( FullPathName->Buffer);
2409 *FullPathName = uniPathName;
2420 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2424 NTSTATUS ntStatus = STATUS_SUCCESS;
2425 AFSObjectInfoCB *pCurrentObject = NULL;
2426 AFSObjectInfoCB *pNextObject = NULL;
2428 AFSFcb *pFcb = NULL;
2434 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2435 AFS_TRACE_LEVEL_VERBOSE,
2436 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2437 VolumeCB->ObjectInformation.FileId.Cell,
2438 VolumeCB->ObjectInformation.FileId.Volume,
2439 VolumeCB->ObjectInformation.FileId.Vnode,
2440 VolumeCB->ObjectInformation.FileId.Unique,
2444 // Depending on the reason for invalidation then perform work on the node
2450 case AFS_INVALIDATE_DELETED:
2454 // Mark this volume as invalid
2457 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2459 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2466 // Invalidate the volume root directory
2469 pCurrentObject = &VolumeCB->ObjectInformation;
2471 if ( pCurrentObject )
2474 lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
2476 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2477 AFS_TRACE_LEVEL_VERBOSE,
2478 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2482 AFSInvalidateObject( &pCurrentObject,
2485 lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
2487 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2488 AFS_TRACE_LEVEL_VERBOSE,
2489 "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
2495 // Apply invalidation to all other volume objects
2498 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2501 pCurrentObject = VolumeCB->ObjectInfoListHead;
2503 if ( pCurrentObject)
2507 // Reference the node so it won't be torn down
2510 lCount = InterlockedIncrement( &pCurrentObject->ObjectReferenceCount);
2512 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2513 AFS_TRACE_LEVEL_VERBOSE,
2514 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2519 while( pCurrentObject != NULL)
2522 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2528 // Reference the node so it won't be torn down
2531 lCount = InterlockedIncrement( &pNextObject->ObjectReferenceCount);
2533 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2534 AFS_TRACE_LEVEL_VERBOSE,
2535 "AFSInvalidateVolumeObjects Increment count on object %08lX Cnt %d\n",
2540 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2542 AFSInvalidateObject( &pCurrentObject,
2545 if ( pCurrentObject )
2548 lCount = InterlockedDecrement( &pCurrentObject->ObjectReferenceCount);
2550 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2551 AFS_TRACE_LEVEL_VERBOSE,
2552 "AFSInvalidateVolumeObjects Decrement count on object %08lX Cnt %d\n",
2557 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2560 pCurrentObject = pNextObject;
2563 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2570 AFSInvalidateAllVolumes( VOID)
2572 AFSVolumeCB *pVolumeCB = NULL;
2573 AFSVolumeCB *pNextVolumeCB = NULL;
2574 AFSDeviceExt *pRDRDeviceExt = NULL;
2577 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2579 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2580 AFS_TRACE_LEVEL_VERBOSE,
2581 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %08lX SHARED %08lX\n",
2582 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2583 PsGetCurrentThread());
2585 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2588 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2593 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2594 AFS_TRACE_LEVEL_VERBOSE,
2595 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %08lX SHARED %08lX\n",
2596 pVolumeCB->ObjectInfoTree.TreeLock,
2597 PsGetCurrentThread());
2599 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
2602 while( pVolumeCB != NULL)
2605 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2610 lCount = InterlockedIncrement( &pNextVolumeCB->VolumeReferenceCount);
2613 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2615 // do I need to hold the volume lock here?
2617 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2619 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2622 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
2624 pVolumeCB = pNextVolumeCB;
2627 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2631 AFSVerifyEntry( IN GUID *AuthGroup,
2632 IN AFSDirectoryCB *DirEntry)
2635 NTSTATUS ntStatus = STATUS_SUCCESS;
2636 AFSDirEnumEntry *pDirEnumEntry = NULL;
2637 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2638 IO_STATUS_BLOCK stIoStatus;
2643 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2644 AFS_TRACE_LEVEL_VERBOSE_2,
2645 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2646 &DirEntry->NameInformation.FileName,
2647 pObjectInfo->FileId.Cell,
2648 pObjectInfo->FileId.Volume,
2649 pObjectInfo->FileId.Vnode,
2650 pObjectInfo->FileId.Unique);
2652 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2657 if( !NT_SUCCESS( ntStatus))
2660 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2661 AFS_TRACE_LEVEL_ERROR,
2662 "AFSValidateEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2663 &DirEntry->NameInformation.FileName,
2664 pObjectInfo->FileId.Cell,
2665 pObjectInfo->FileId.Volume,
2666 pObjectInfo->FileId.Vnode,
2667 pObjectInfo->FileId.Unique,
2670 try_return( ntStatus);
2674 // Check the data version of the file
2677 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2678 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2681 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2682 AFS_TRACE_LEVEL_VERBOSE,
2683 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2684 pObjectInfo->DataVersion.QuadPart,
2685 &DirEntry->NameInformation.FileName,
2686 pObjectInfo->FileId.Cell,
2687 pObjectInfo->FileId.Volume,
2688 pObjectInfo->FileId.Vnode,
2689 pObjectInfo->FileId.Unique);
2692 // We are ok, just get out
2695 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2697 try_return( ntStatus = STATUS_SUCCESS);
2701 // New data version so we will need to process the node based on the type
2704 switch( pDirEnumEntry->FileType)
2707 case AFS_FILE_TYPE_MOUNTPOINT:
2711 // For a mount point we need to ensure the target is the same
2714 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2715 &pDirEnumEntry->TargetFileId))
2721 // Update the metadata for the entry
2724 ntStatus = AFSUpdateMetaData( DirEntry,
2727 if( NT_SUCCESS( ntStatus))
2730 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2736 case AFS_FILE_TYPE_SYMLINK:
2739 ASSERT( pDirEnumEntry->TargetNameLength > 0);
2742 // Update the metadata for the entry
2745 ntStatus = AFSUpdateMetaData( DirEntry,
2748 if( NT_SUCCESS( ntStatus))
2751 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2757 case AFS_FILE_TYPE_FILE:
2759 FILE_OBJECT * pCCFileObject = NULL;
2760 BOOLEAN bPurgeExtents = FALSE;
2762 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2764 bPurgeExtents = TRUE;
2766 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2767 AFS_TRACE_LEVEL_VERBOSE,
2768 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2769 &DirEntry->NameInformation.FileName,
2770 pObjectInfo->FileId.Cell,
2771 pObjectInfo->FileId.Volume,
2772 pObjectInfo->FileId.Vnode,
2773 pObjectInfo->FileId.Unique);
2775 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2779 // Update the metadata for the entry
2782 ntStatus = AFSUpdateMetaData( DirEntry,
2785 if( !NT_SUCCESS( ntStatus))
2788 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2789 AFS_TRACE_LEVEL_ERROR,
2790 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2791 &DirEntry->NameInformation.FileName,
2792 pObjectInfo->FileId.Cell,
2793 pObjectInfo->FileId.Volume,
2794 pObjectInfo->FileId.Vnode,
2795 pObjectInfo->FileId.Unique,
2801 if( pObjectInfo->Fcb != NULL)
2804 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2805 AFS_TRACE_LEVEL_VERBOSE,
2806 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2807 &DirEntry->NameInformation.FileName,
2808 pObjectInfo->FileId.Cell,
2809 pObjectInfo->FileId.Volume,
2810 pObjectInfo->FileId.Vnode,
2811 pObjectInfo->FileId.Unique);
2813 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2819 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2824 if( !NT_SUCCESS( stIoStatus.Status))
2827 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2828 AFS_TRACE_LEVEL_ERROR,
2829 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2830 &DirEntry->NameInformation.FileName,
2831 pObjectInfo->FileId.Cell,
2832 pObjectInfo->FileId.Volume,
2833 pObjectInfo->FileId.Vnode,
2834 pObjectInfo->FileId.Unique,
2836 stIoStatus.Information);
2838 ntStatus = stIoStatus.Status;
2844 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2850 __except( EXCEPTION_EXECUTE_HANDLER)
2852 ntStatus = GetExceptionCode();
2854 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2855 AFS_TRACE_LEVEL_ERROR,
2856 "AFSVerifyEntry CcFlushCache or CcPurgeCacheSection Exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2857 &DirEntry->NameInformation.FileName,
2858 pObjectInfo->FileId.Cell,
2859 pObjectInfo->FileId.Volume,
2860 pObjectInfo->FileId.Vnode,
2861 pObjectInfo->FileId.Unique,
2865 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2869 AFSFlushExtents( pObjectInfo->Fcb,
2874 // Reacquire the Fcb to purge the cache
2877 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2878 AFS_TRACE_LEVEL_VERBOSE,
2879 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2880 &pObjectInfo->Fcb->NPFcb->Resource,
2881 PsGetCurrentThread());
2883 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2887 // Update file sizes
2890 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2891 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2892 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2894 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2896 if ( pCCFileObject != NULL)
2898 CcSetFileSizes( pCCFileObject,
2899 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
2902 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2906 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2907 AFS_TRACE_LEVEL_WARNING,
2908 "AFSValidateEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2909 &DirEntry->NameInformation.FileName,
2910 pObjectInfo->FileId.Cell,
2911 pObjectInfo->FileId.Volume,
2912 pObjectInfo->FileId.Vnode,
2913 pObjectInfo->FileId.Unique);
2916 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2921 case AFS_FILE_TYPE_DIRECTORY:
2924 AFSFcb *pCurrentFcb = NULL;
2925 AFSDirectoryCB *pCurrentDirEntry = NULL;
2928 // For a directory or root entry flush the content of
2929 // the directory enumeration.
2932 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2935 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2936 AFS_TRACE_LEVEL_VERBOSE_2,
2937 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2938 &DirEntry->NameInformation.FileName,
2939 pObjectInfo->FileId.Cell,
2940 pObjectInfo->FileId.Volume,
2941 pObjectInfo->FileId.Vnode,
2942 pObjectInfo->FileId.Unique);
2944 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2947 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
2950 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2952 if ( !NT_SUCCESS( ntStatus))
2955 try_return( ntStatus);
2960 // Update the metadata for the entry
2963 ntStatus = AFSUpdateMetaData( DirEntry,
2966 if( NT_SUCCESS( ntStatus))
2969 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2975 case AFS_FILE_TYPE_DFSLINK:
2978 UNICODE_STRING uniTargetName;
2981 // For a DFS link need to check the target name has not changed
2984 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
2986 uniTargetName.MaximumLength = uniTargetName.Length;
2988 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
2990 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
2993 if( DirEntry->NameInformation.TargetName.Length == 0 ||
2994 RtlCompareUnicodeString( &uniTargetName,
2995 &DirEntry->NameInformation.TargetName,
3000 // Update the target name
3003 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3005 uniTargetName.Buffer,
3006 uniTargetName.Length);
3008 if( !NT_SUCCESS( ntStatus))
3011 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3017 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3020 // Update the metadata for the entry
3023 ntStatus = AFSUpdateMetaData( DirEntry,
3026 if( NT_SUCCESS( ntStatus))
3029 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3037 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3038 AFS_TRACE_LEVEL_WARNING,
3039 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3040 pObjectInfo->FileType,
3041 &DirEntry->NameInformation.FileName,
3042 pObjectInfo->FileId.Cell,
3043 pObjectInfo->FileId.Volume,
3044 pObjectInfo->FileId.Vnode,
3045 pObjectInfo->FileId.Unique);
3052 if( pDirEnumEntry != NULL)
3055 AFSExFreePool( pDirEnumEntry);
3063 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3066 NTSTATUS ntStatus = STATUS_SUCCESS;
3067 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3068 ULONGLONG ullIndex = 0;
3069 AFSVolumeCB *pVolumeCB = NULL;
3070 AFSFcb *pFcb = NULL;
3071 AFSObjectInfoCB *pCurrentObject = NULL;
3077 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3078 AFS_TRACE_LEVEL_VERBOSE,
3079 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3080 VolumeStatus->Online,
3081 VolumeStatus->FileID.Cell,
3082 VolumeStatus->FileID.Volume);
3085 // Need to locate the Fcb for the directory to purge
3088 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3089 AFS_TRACE_LEVEL_VERBOSE,
3090 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3091 &pDevExt->Specific.RDR.VolumeTreeLock,
3092 PsGetCurrentThread());
3094 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3097 // Locate the volume node
3100 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3102 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3104 (AFSBTreeEntry **)&pVolumeCB);
3106 if( pVolumeCB != NULL)
3109 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3111 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3114 // Set the volume state accordingly
3117 if( VolumeStatus->Online)
3120 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3125 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3128 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3131 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3133 while( pCurrentObject != NULL)
3136 if( VolumeStatus->Online)
3139 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3141 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3143 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3148 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3151 pFcb = pCurrentObject->Fcb;
3154 !(VolumeStatus->Online) &&
3155 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3158 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3159 AFS_TRACE_LEVEL_ERROR,
3160 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3161 VolumeStatus->FileID.Cell,
3162 VolumeStatus->FileID.Volume);
3165 // Clear out the extents
3168 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3169 AFS_TRACE_LEVEL_VERBOSE,
3170 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3171 &pFcb->NPFcb->Specific.File.ExtentsResource,
3172 PsGetCurrentThread());
3174 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3177 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3179 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3183 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3184 AFS_TRACE_LEVEL_VERBOSE,
3185 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3186 &pFcb->NPFcb->Specific.File.ExtentsResource,
3187 PsGetCurrentThread());
3189 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3192 // And get rid of them (note this involves waiting
3193 // for any writes or reads to the cache to complete)
3196 (VOID) AFSTearDownFcbExtents( pFcb,
3200 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3203 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3205 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3210 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3218 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3221 NTSTATUS ntStatus = STATUS_SUCCESS;
3226 if( AFSGlobalRoot == NULL)
3229 try_return( ntStatus);
3232 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3236 // Set the network state according to the information
3239 if( NetworkStatus->Online)
3242 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3247 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3250 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3261 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3265 NTSTATUS ntStatus = STATUS_SUCCESS;
3266 BOOLEAN bAcquiredLock = FALSE;
3267 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3268 AFSFcb *pFcb = NULL;
3273 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3274 AFS_TRACE_LEVEL_VERBOSE,
3275 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3276 ObjectInfo->FileId.Cell,
3277 ObjectInfo->FileId.Volume,
3278 ObjectInfo->FileId.Vnode,
3279 ObjectInfo->FileId.Unique);
3281 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3284 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3285 AFS_TRACE_LEVEL_VERBOSE,
3286 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3287 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3288 PsGetCurrentThread());
3290 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3293 bAcquiredLock = TRUE;
3297 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3300 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3301 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3304 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3305 AFS_TRACE_LEVEL_ERROR,
3306 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
3307 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3308 ObjectInfo->FileId.Cell,
3309 ObjectInfo->FileId.Volume,
3310 ObjectInfo->FileId.Vnode,
3311 ObjectInfo->FileId.Unique);
3315 // Reset the directory list information by clearing all valid entries
3318 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3320 while( pCurrentDirEntry != NULL)
3323 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3325 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3329 // If this entry has been deleted then process it here
3332 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3333 pCurrentDirEntry->OpenReferenceCount == 0)
3336 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3337 AFS_TRACE_LEVEL_VERBOSE,
3338 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3340 &pCurrentDirEntry->NameInformation.FileName);
3342 AFSDeleteDirEntry( ObjectInfo,
3348 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3350 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3351 AFS_TRACE_LEVEL_VERBOSE,
3352 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3354 pCurrentDirEntry->OpenReferenceCount);
3357 // We pull the short name from the parent tree since it could change below
3360 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3363 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3364 AFS_TRACE_LEVEL_VERBOSE,
3365 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3367 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3368 &pCurrentDirEntry->NameInformation.FileName);
3370 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3373 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3378 pCurrentDirEntry = pNextDirEntry;
3382 // Reget the directory contents
3385 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3388 if ( !NT_SUCCESS( ntStatus))
3390 try_return( ntStatus);
3394 // Now start again and tear down any entries not valid
3397 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3399 while( pCurrentDirEntry != NULL)
3402 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3404 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3407 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3408 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3411 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3414 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3416 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3417 AFS_TRACE_LEVEL_VERBOSE,
3418 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3420 &pCurrentDirEntry->NameInformation.FileName);
3422 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3427 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3430 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3431 AFS_TRACE_LEVEL_VERBOSE,
3432 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3434 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3435 &pCurrentDirEntry->NameInformation.FileName);
3439 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3441 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3442 AFS_TRACE_LEVEL_VERBOSE,
3443 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3445 &pCurrentDirEntry->NameInformation.FileName);
3450 pCurrentDirEntry = pNextDirEntry;
3455 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3456 AFS_TRACE_LEVEL_VERBOSE,
3457 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3459 pCurrentDirEntry->OpenReferenceCount);
3461 if( pCurrentDirEntry->OpenReferenceCount == 0)
3464 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3465 AFS_TRACE_LEVEL_VERBOSE,
3466 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3467 &pCurrentDirEntry->NameInformation.FileName,
3468 ObjectInfo->FileId.Cell,
3469 ObjectInfo->FileId.Volume,
3470 ObjectInfo->FileId.Vnode,
3471 ObjectInfo->FileId.Unique);
3473 AFSDeleteDirEntry( ObjectInfo,
3479 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3480 AFS_TRACE_LEVEL_VERBOSE,
3481 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3483 &pCurrentDirEntry->NameInformation.FileName,
3484 ObjectInfo->FileId.Cell,
3485 ObjectInfo->FileId.Volume,
3486 ObjectInfo->FileId.Vnode,
3487 ObjectInfo->FileId.Unique);
3489 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3491 AFSRemoveNameEntry( ObjectInfo,
3495 pCurrentDirEntry = pNextDirEntry;
3499 if( !AFSValidateDirList( ObjectInfo))
3502 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3511 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3519 AFSIsVolumeFID( IN AFSFileID *FileID)
3522 BOOLEAN bIsVolume = FALSE;
3524 if( FileID->Vnode == 1 &&
3525 FileID->Unique == 1)
3535 AFSIsFinalNode( IN AFSFcb *Fcb)
3538 BOOLEAN bIsFinalNode = FALSE;
3540 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3541 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3542 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3543 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3544 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3547 bIsFinalNode = TRUE;
3552 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3553 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3556 return bIsFinalNode;
3560 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3561 IN AFSDirEnumEntry *DirEnumEntry)
3564 NTSTATUS ntStatus = STATUS_SUCCESS;
3565 UNICODE_STRING uniTargetName;
3566 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3571 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3573 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3575 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3577 pObjectInfo->FileType = DirEnumEntry->FileType;
3579 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3581 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3583 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3585 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3587 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3589 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3591 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3593 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3596 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3599 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3600 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3603 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3606 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3608 pObjectInfo->Links = DirEnumEntry->Links;
3610 if( DirEnumEntry->TargetNameLength > 0)
3614 // Update the target name information if needed
3617 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3619 uniTargetName.MaximumLength = uniTargetName.Length;
3621 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3623 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3626 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3627 RtlCompareUnicodeString( &uniTargetName,
3628 &DirEntry->NameInformation.TargetName,
3633 // Update the target name
3636 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3638 uniTargetName.Buffer,
3639 uniTargetName.Length);
3641 if( !NT_SUCCESS( ntStatus))
3644 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3646 try_return( ntStatus);
3650 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3652 else if( DirEntry->NameInformation.TargetName.Length > 0)
3655 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3658 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3659 DirEntry->NameInformation.TargetName.Buffer != NULL)
3661 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
3664 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3666 DirEntry->NameInformation.TargetName.Length = 0;
3667 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3668 DirEntry->NameInformation.TargetName.Buffer = NULL;
3670 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3682 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3684 IN BOOLEAN PurgeContent,
3685 IN BOOLEAN FastCall)
3688 NTSTATUS ntStatus = STATUS_SUCCESS;
3689 LARGE_INTEGER liSystemTime;
3690 AFSDirEnumEntry *pDirEnumEntry = NULL;
3691 AFSFcb *pCurrentFcb = NULL;
3692 BOOLEAN bReleaseFcb = FALSE;
3693 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3699 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3703 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3704 AFS_TRACE_LEVEL_VERBOSE_2,
3705 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3706 &DirEntry->NameInformation.FileName,
3707 pObjectInfo->FileId.Cell,
3708 pObjectInfo->FileId.Volume,
3709 pObjectInfo->FileId.Vnode,
3710 pObjectInfo->FileId.Unique);
3713 // If this is a fake node then bail since the service knows nothing about it
3716 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3719 try_return( ntStatus);
3723 pObjectInfo->Fcb != NULL)
3726 pCurrentFcb = pObjectInfo->Fcb;
3728 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3731 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3732 AFS_TRACE_LEVEL_VERBOSE,
3733 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3734 &pCurrentFcb->NPFcb->Resource,
3735 PsGetCurrentThread());
3737 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3745 // This routine ensures that the current entry is valid by:
3747 // 1) Checking that the expiration time is non-zero and after where we
3751 KeQuerySystemTime( &liSystemTime);
3753 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3754 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3755 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3756 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3759 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3760 AFS_TRACE_LEVEL_VERBOSE_2,
3761 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3762 &DirEntry->NameInformation.FileName,
3763 pObjectInfo->FileId.Cell,
3764 pObjectInfo->FileId.Volume,
3765 pObjectInfo->FileId.Vnode,
3766 pObjectInfo->FileId.Unique);
3768 try_return( ntStatus);
3772 // This node requires updating
3775 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3780 if( !NT_SUCCESS( ntStatus))
3783 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3784 AFS_TRACE_LEVEL_ERROR,
3785 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3787 &DirEntry->NameInformation.FileName,
3788 pObjectInfo->FileId.Cell,
3789 pObjectInfo->FileId.Volume,
3790 pObjectInfo->FileId.Vnode,
3791 pObjectInfo->FileId.Unique,
3795 // Failed validation of node so return access-denied
3798 try_return( ntStatus);
3801 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3802 AFS_TRACE_LEVEL_VERBOSE,
3803 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3805 &DirEntry->NameInformation.FileName,
3806 pObjectInfo->FileId.Cell,
3807 pObjectInfo->FileId.Volume,
3808 pObjectInfo->FileId.Vnode,
3809 pObjectInfo->FileId.Unique,
3810 pObjectInfo->DataVersion.QuadPart,
3811 pDirEnumEntry->DataVersion.QuadPart,
3812 pDirEnumEntry->FileType);
3816 // Based on the file type, process the node
3819 switch( pDirEnumEntry->FileType)
3822 case AFS_FILE_TYPE_MOUNTPOINT:
3826 // Update the metadata for the entry
3829 ntStatus = AFSUpdateMetaData( DirEntry,
3832 if( NT_SUCCESS( ntStatus))
3835 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3841 case AFS_FILE_TYPE_SYMLINK:
3842 case AFS_FILE_TYPE_DFSLINK:
3846 // Update the metadata for the entry
3849 ntStatus = AFSUpdateMetaData( DirEntry,
3852 if( NT_SUCCESS( ntStatus))
3855 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3861 case AFS_FILE_TYPE_FILE:
3865 // For a file where the data version has become invalid we need to
3866 // fail any current extent requests and purge the cache for the file
3867 // Can't hold the Fcb resource while doing this
3870 if( pCurrentFcb != NULL &&
3871 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3872 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3875 IO_STATUS_BLOCK stIoStatus;
3876 BOOLEAN bPurgeExtents = FALSE;
3878 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3879 AFS_TRACE_LEVEL_VERBOSE_2,
3880 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3881 &DirEntry->NameInformation.FileName,
3882 pObjectInfo->FileId.Cell,
3883 pObjectInfo->FileId.Volume,
3884 pObjectInfo->FileId.Vnode,
3885 pObjectInfo->FileId.Unique);
3887 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3889 bPurgeExtents = TRUE;
3891 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3892 AFS_TRACE_LEVEL_VERBOSE,
3893 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3894 &DirEntry->NameInformation.FileName,
3895 pObjectInfo->FileId.Cell,
3896 pObjectInfo->FileId.Volume,
3897 pObjectInfo->FileId.Vnode,
3898 pObjectInfo->FileId.Unique);
3900 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3906 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
3911 if( !NT_SUCCESS( stIoStatus.Status))
3914 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3915 AFS_TRACE_LEVEL_ERROR,
3916 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3917 &DirEntry->NameInformation.FileName,
3918 pObjectInfo->FileId.Cell,
3919 pObjectInfo->FileId.Volume,
3920 pObjectInfo->FileId.Vnode,
3921 pObjectInfo->FileId.Unique,
3923 stIoStatus.Information);
3925 ntStatus = stIoStatus.Status;
3931 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3937 __except( EXCEPTION_EXECUTE_HANDLER)
3939 ntStatus = GetExceptionCode();
3941 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3942 AFS_TRACE_LEVEL_ERROR,
3943 "AFSValidateEntry CcFlushCache or CcPurgeCacheSection exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3944 &DirEntry->NameInformation.FileName,
3945 pObjectInfo->FileId.Cell,
3946 pObjectInfo->FileId.Volume,
3947 pObjectInfo->FileId.Vnode,
3948 pObjectInfo->FileId.Unique,
3953 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3957 AFSFlushExtents( pCurrentFcb,
3962 // Reacquire the Fcb to purge the cache
3965 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3966 AFS_TRACE_LEVEL_VERBOSE,
3967 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3968 &pCurrentFcb->NPFcb->Resource,
3969 PsGetCurrentThread());
3971 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3976 // Update the metadata for the entry
3979 ntStatus = AFSUpdateMetaData( DirEntry,
3982 if( !NT_SUCCESS( ntStatus))
3985 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3986 AFS_TRACE_LEVEL_ERROR,
3987 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3988 &DirEntry->NameInformation.FileName,
3989 pObjectInfo->FileId.Cell,
3990 pObjectInfo->FileId.Volume,
3991 pObjectInfo->FileId.Vnode,
3992 pObjectInfo->FileId.Unique,
3998 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4001 // Update file sizes
4004 if( pObjectInfo->Fcb != NULL)
4006 FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4008 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4009 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4010 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4012 if ( pCCFileObject != NULL)
4014 CcSetFileSizes( pCCFileObject,
4015 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4022 case AFS_FILE_TYPE_DIRECTORY:
4025 AFSDirectoryCB *pCurrentDirEntry = NULL;
4027 if( pCurrentFcb != NULL &&
4028 pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4032 // For a directory or root entry flush the content of
4033 // the directory enumeration.
4036 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4037 AFS_TRACE_LEVEL_VERBOSE,
4038 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4039 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4040 PsGetCurrentThread());
4042 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4045 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4046 AFS_TRACE_LEVEL_VERBOSE_2,
4047 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4048 &DirEntry->NameInformation.FileName,
4049 pObjectInfo->FileId.Cell,
4050 pObjectInfo->FileId.Volume,
4051 pObjectInfo->FileId.Vnode,
4052 pObjectInfo->FileId.Unique);
4054 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4057 AFSValidateDirectoryCache( pCurrentFcb->ObjectInformation,
4060 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4063 if( !NT_SUCCESS( ntStatus))
4066 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4067 AFS_TRACE_LEVEL_ERROR,
4068 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4069 &DirEntry->NameInformation.FileName,
4070 pObjectInfo->FileId.Cell,
4071 pObjectInfo->FileId.Volume,
4072 pObjectInfo->FileId.Vnode,
4073 pObjectInfo->FileId.Unique,
4081 // Update the metadata for the entry
4084 ntStatus = AFSUpdateMetaData( DirEntry,
4087 if( NT_SUCCESS( ntStatus))
4090 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4098 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4099 AFS_TRACE_LEVEL_WARNING,
4100 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4101 pObjectInfo->FileType,
4103 &DirEntry->NameInformation.FileName,
4104 pObjectInfo->FileId.Cell,
4105 pObjectInfo->FileId.Volume,
4106 pObjectInfo->FileId.Vnode,
4107 pObjectInfo->FileId.Unique);
4117 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4120 if( pDirEnumEntry != NULL)
4123 AFSExFreePool( pDirEnumEntry);
4131 AFSInitializeSpecialShareNameList()
4134 NTSTATUS ntStatus = STATUS_SUCCESS;
4135 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4136 AFSObjectInfoCB *pObjectInfoCB = NULL;
4137 UNICODE_STRING uniShareName;
4138 ULONG ulEntryLength = 0;
4139 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4144 RtlInitUnicodeString( &uniShareName,
4147 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4150 if( pObjectInfoCB == NULL)
4153 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4156 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4157 AFS_TRACE_LEVEL_VERBOSE,
4158 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
4161 pObjectInfoCB->ObjectReferenceCount = 1;
4163 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4165 ulEntryLength = sizeof( AFSDirectoryCB) +
4166 uniShareName.Length;
4168 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4172 if( pDirNode == NULL)
4175 AFSDeleteObjectInfo( pObjectInfoCB);
4177 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4180 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4181 sizeof( AFSNonPagedDirectoryCB),
4182 AFS_DIR_ENTRY_NP_TAG);
4184 if( pNonPagedDirEntry == NULL)
4187 ExFreePool( pDirNode);
4189 AFSDeleteObjectInfo( pObjectInfoCB);
4191 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4194 RtlZeroMemory( pDirNode,
4197 RtlZeroMemory( pNonPagedDirEntry,
4198 sizeof( AFSNonPagedDirectoryCB));
4200 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4202 pDirNode->NonPaged = pNonPagedDirEntry;
4204 pDirNode->ObjectInformation = pObjectInfoCB;
4210 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
4212 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4214 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4216 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4218 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4219 uniShareName.Buffer,
4220 pDirNode->NameInformation.FileName.Length);
4222 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4225 AFSSpecialShareNames = pDirNode;
4227 pLastDirNode = pDirNode;
4229 RtlInitUnicodeString( &uniShareName,
4232 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4235 if( pObjectInfoCB == NULL)
4238 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4241 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4242 AFS_TRACE_LEVEL_VERBOSE,
4243 "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
4246 pObjectInfoCB->ObjectReferenceCount = 1;
4248 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4250 ulEntryLength = sizeof( AFSDirectoryCB) +
4251 uniShareName.Length;
4253 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4257 if( pDirNode == NULL)
4260 AFSDeleteObjectInfo( pObjectInfoCB);
4262 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4265 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4266 sizeof( AFSNonPagedDirectoryCB),
4267 AFS_DIR_ENTRY_NP_TAG);
4269 if( pNonPagedDirEntry == NULL)
4272 ExFreePool( pDirNode);
4274 AFSDeleteObjectInfo( pObjectInfoCB);
4276 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4279 RtlZeroMemory( pDirNode,
4282 RtlZeroMemory( pNonPagedDirEntry,
4283 sizeof( AFSNonPagedDirectoryCB));
4285 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4287 pDirNode->NonPaged = pNonPagedDirEntry;
4289 pDirNode->ObjectInformation = pObjectInfoCB;
4295 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
4297 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4299 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4301 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4303 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4304 uniShareName.Buffer,
4305 pDirNode->NameInformation.FileName.Length);
4307 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4310 pLastDirNode->ListEntry.fLink = pDirNode;
4312 pDirNode->ListEntry.bLink = pLastDirNode;
4314 pLastDirNode = pDirNode;
4316 RtlInitUnicodeString( &uniShareName,
4319 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4322 if( pObjectInfoCB == NULL)
4325 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4328 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4329 AFS_TRACE_LEVEL_VERBOSE,
4330 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4333 pObjectInfoCB->ObjectReferenceCount = 1;
4335 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4337 ulEntryLength = sizeof( AFSDirectoryCB) +
4338 uniShareName.Length;
4340 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4344 if( pDirNode == NULL)
4347 AFSDeleteObjectInfo( pObjectInfoCB);
4349 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4352 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4353 sizeof( AFSNonPagedDirectoryCB),
4354 AFS_DIR_ENTRY_NP_TAG);
4356 if( pNonPagedDirEntry == NULL)
4359 ExFreePool( pDirNode);
4361 AFSDeleteObjectInfo( pObjectInfoCB);
4363 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4366 RtlZeroMemory( pDirNode,
4369 RtlZeroMemory( pNonPagedDirEntry,
4370 sizeof( AFSNonPagedDirectoryCB));
4372 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4374 pDirNode->NonPaged = pNonPagedDirEntry;
4376 pDirNode->ObjectInformation = pObjectInfoCB;
4382 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4384 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4386 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4388 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4390 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4391 uniShareName.Buffer,
4392 pDirNode->NameInformation.FileName.Length);
4394 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4397 pLastDirNode->ListEntry.fLink = pDirNode;
4399 pDirNode->ListEntry.bLink = pLastDirNode;
4403 if( !NT_SUCCESS( ntStatus))
4406 if( AFSSpecialShareNames != NULL)
4409 pDirNode = AFSSpecialShareNames;
4411 while( pDirNode != NULL)
4414 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4416 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4418 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4420 ExFreePool( pDirNode->NonPaged);
4422 ExFreePool( pDirNode);
4424 pDirNode = pLastDirNode;
4427 AFSSpecialShareNames = NULL;
4436 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4437 IN UNICODE_STRING *SecondaryName)
4440 AFSDirectoryCB *pDirectoryCB = NULL;
4441 ULONGLONG ullHash = 0;
4442 UNICODE_STRING uniFullShareName;
4448 // Build up the entire name here. We are guaranteed that if there is a
4449 // secondary name, it is pointing to a portion of the share name buffer
4452 if( SecondaryName->Length > 0 &&
4453 SecondaryName->Buffer != NULL)
4456 uniFullShareName = *SecondaryName;
4459 // The calling routine strips off the leading slash so add it back in
4462 uniFullShareName.Buffer--;
4463 uniFullShareName.Length += sizeof( WCHAR);
4464 uniFullShareName.MaximumLength += sizeof( WCHAR);
4467 // And the share name
4470 uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
4471 uniFullShareName.Length += ShareName->Length;
4472 uniFullShareName.MaximumLength += ShareName->Length;
4477 uniFullShareName = *ShareName;
4481 // Generate our hash value
4484 ullHash = AFSGenerateCRC( &uniFullShareName,
4488 // Loop through our special share names to see if this is one of them
4491 pDirectoryCB = AFSSpecialShareNames;
4493 while( pDirectoryCB != NULL)
4496 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4502 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4506 return pDirectoryCB;
4510 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4514 // Block on the queue flush event
4517 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4527 AFSWaitOnQueuedReleases()
4530 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4533 // Block on the queue flush event
4536 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4546 AFSIsEqualFID( IN AFSFileID *FileId1,
4547 IN AFSFileID *FileId2)
4550 BOOLEAN bIsEqual = FALSE;
4552 if( FileId1->Unique == FileId2->Unique &&
4553 FileId1->Vnode == FileId2->Vnode &&
4554 FileId1->Volume == FileId2->Volume &&
4555 FileId1->Cell == FileId2->Cell)
4565 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4568 NTSTATUS ntStatus = STATUS_SUCCESS;
4569 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4574 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4577 // Reset the directory list information
4580 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4582 while( pCurrentDirEntry != NULL)
4585 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4587 if( pCurrentDirEntry->OpenReferenceCount == 0)
4590 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4591 AFS_TRACE_LEVEL_VERBOSE,
4592 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4594 &pCurrentDirEntry->NameInformation.FileName);
4596 AFSDeleteDirEntry( ObjectInfoCB,
4602 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4603 AFS_TRACE_LEVEL_VERBOSE,
4604 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4606 &pCurrentDirEntry->NameInformation.FileName);
4608 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4610 AFSRemoveNameEntry( ObjectInfoCB,
4614 pCurrentDirEntry = pNextDirEntry;
4617 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4619 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4621 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4623 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4625 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4627 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4629 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4630 AFS_TRACE_LEVEL_VERBOSE,
4631 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4632 ObjectInfoCB->FileId.Cell,
4633 ObjectInfoCB->FileId.Volume,
4634 ObjectInfoCB->FileId.Vnode,
4635 ObjectInfoCB->FileId.Unique);
4642 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4645 NTSTATUS ntStatus = STATUS_SUCCESS;
4646 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4647 UNICODE_STRING uniFullName;
4652 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4653 AFS_TRACE_LEVEL_VERBOSE,
4654 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4655 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4656 PsGetCurrentThread());
4658 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4661 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4664 try_return( ntStatus);
4668 // Initialize the root information
4671 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4674 // Enumerate the shares in the volume
4677 ntStatus = AFSEnumerateDirectory( AuthGroup,
4678 &AFSGlobalRoot->ObjectInformation,
4681 if( !NT_SUCCESS( ntStatus))
4684 try_return( ntStatus);
4687 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4690 // Indicate the node is initialized
4693 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4695 uniFullName.MaximumLength = PAGE_SIZE;
4696 uniFullName.Length = 0;
4698 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4699 uniFullName.MaximumLength,
4700 AFS_GENERIC_MEMORY_12_TAG);
4702 if( uniFullName.Buffer == NULL)
4706 // Reset the directory content
4709 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4711 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4713 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4717 // Populate our list of entries in the NP enumeration list
4720 while( pDirGlobalDirNode != NULL)
4723 uniFullName.Buffer[ 0] = L'\\';
4724 uniFullName.Buffer[ 1] = L'\\';
4726 uniFullName.Length = 2 * sizeof( WCHAR);
4728 RtlCopyMemory( &uniFullName.Buffer[ 2],
4729 AFSServerName.Buffer,
4730 AFSServerName.Length);
4732 uniFullName.Length += AFSServerName.Length;
4734 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4736 uniFullName.Length += sizeof( WCHAR);
4738 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4739 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4740 pDirGlobalDirNode->NameInformation.FileName.Length);
4742 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4744 AFSAddConnectionEx( &uniFullName,
4745 RESOURCEDISPLAYTYPE_SHARE,
4748 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4751 AFSExFreePool( uniFullName.Buffer);
4755 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4762 AFSIsRelativeName( IN UNICODE_STRING *Name)
4765 BOOLEAN bIsRelative = FALSE;
4767 if( Name->Buffer[ 0] != L'\\')
4777 AFSUpdateName( IN UNICODE_STRING *Name)
4782 while( usIndex < Name->Length/sizeof( WCHAR))
4785 if( Name->Buffer[ usIndex] == L'/')
4788 Name->Buffer[ usIndex] = L'\\';
4798 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4799 IN OUT ULONG *Flags,
4800 IN WCHAR *NameBuffer,
4801 IN USHORT NameLength)
4804 NTSTATUS ntStatus = STATUS_SUCCESS;
4805 WCHAR *pTmpBuffer = NULL;
4811 // If we have enough space then just move in the name otherwise
4812 // allocate a new buffer
4815 if( TargetName->Length < NameLength)
4818 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4820 AFS_NAME_BUFFER_FIVE_TAG);
4822 if( pTmpBuffer == NULL)
4825 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4828 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4831 AFSExFreePool( TargetName->Buffer);
4834 TargetName->MaximumLength = NameLength;
4836 TargetName->Buffer = pTmpBuffer;
4838 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4841 TargetName->Length = NameLength;
4843 RtlCopyMemory( TargetName->Buffer,
4845 TargetName->Length);
4848 // Update the name in the buffer
4851 AFSUpdateName( TargetName);
4862 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4863 IN ULONG InitialElementCount)
4866 AFSNameArrayHdr *pNameArray = NULL;
4867 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4873 if( InitialElementCount == 0)
4876 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
4879 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
4880 sizeof( AFSNameArrayHdr) +
4881 (InitialElementCount * sizeof( AFSNameArrayCB)),
4882 AFS_NAME_ARRAY_TAG);
4884 if( pNameArray == NULL)
4887 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4888 AFS_TRACE_LEVEL_ERROR,
4889 "AFSInitNameArray Failed to allocate name array\n");
4891 try_return( pNameArray);
4894 RtlZeroMemory( pNameArray,
4895 sizeof( AFSNameArrayHdr) +
4896 (InitialElementCount * sizeof( AFSNameArrayCB)));
4898 pNameArray->MaxElementCount = InitialElementCount;
4900 if( DirectoryCB != NULL)
4903 pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
4905 lCount = InterlockedIncrement( &pNameArray->Count);
4907 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
4909 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4910 AFS_TRACE_LEVEL_VERBOSE,
4911 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
4912 &DirectoryCB->NameInformation.FileName,
4916 pNameArray->CurrentEntry->DirectoryCB = DirectoryCB;
4918 pNameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
4920 pNameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
4932 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
4933 IN UNICODE_STRING *Path,
4934 IN AFSDirectoryCB *DirectoryCB)
4937 NTSTATUS ntStatus = STATUS_SUCCESS;
4938 AFSNameArrayCB *pCurrentElement = NULL;
4939 UNICODE_STRING uniComponentName, uniRemainingPath;
4940 AFSObjectInfoCB *pCurrentObject = NULL;
4941 ULONG ulTotalCount = 0;
4943 USHORT usLength = 0;
4950 // Init some info in the header
4953 pCurrentElement = &NameArray->ElementArray[ 0];
4955 NameArray->CurrentEntry = pCurrentElement;
4958 // The first entry points at the root
4961 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
4963 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4965 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4966 AFS_TRACE_LEVEL_VERBOSE,
4967 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
4968 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4969 pCurrentElement->DirectoryCB,
4972 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
4974 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
4976 NameArray->Count = 1;
4978 NameArray->LinkCount = 0;
4981 // If the root is the parent then we are done ...
4984 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
4986 try_return( ntStatus);
4998 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
4999 IN AFSNameArrayHdr *RelatedNameArray,
5000 IN AFSDirectoryCB *DirectoryCB)
5003 NTSTATUS ntStatus = STATUS_SUCCESS;
5004 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
5005 UNICODE_STRING uniComponentName, uniRemainingPath;
5006 AFSObjectInfoCB *pObjectInfo = NULL;
5007 ULONG ulTotalCount = 0;
5009 USHORT usLength = 0;
5016 // Init some info in the header
5019 pCurrentElement = &NameArray->ElementArray[ 0];
5021 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5023 NameArray->Count = 0;
5025 NameArray->LinkCount = RelatedNameArray->LinkCount;
5028 // Populate the name array with the data from the related array
5034 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5036 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5038 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5040 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5042 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5043 AFS_TRACE_LEVEL_VERBOSE,
5044 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
5045 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5046 pCurrentElement->DirectoryCB,
5049 lCount = InterlockedIncrement( &NameArray->Count);
5051 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5052 NameArray->Count == RelatedNameArray->Count)
5064 pCurrentRelatedElement++;
5067 if( NameArray->Count > 0)
5069 NameArray->CurrentEntry = pCurrentElement;
5077 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5080 NTSTATUS ntStatus = STATUS_SUCCESS;
5081 AFSNameArrayCB *pCurrentElement = NULL;
5087 pCurrentElement = &NameArray->ElementArray[ 0];
5092 if( pCurrentElement->DirectoryCB == NULL)
5098 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5100 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5101 AFS_TRACE_LEVEL_VERBOSE,
5102 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
5103 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5104 pCurrentElement->DirectoryCB,
5110 AFSExFreePool( NameArray);
5117 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5118 IN AFSDirectoryCB *DirEntry)
5121 NTSTATUS ntStatus = STATUS_SUCCESS;
5122 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5128 if( NameArray->Count == NameArray->MaxElementCount)
5131 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5134 if( NameArray->CurrentEntry != NULL &&
5135 NameArray->CurrentEntry->DirectoryCB == DirEntry)
5138 try_return( ntStatus);
5141 if( NameArray->Count > 0)
5144 NameArray->CurrentEntry++;
5148 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5151 lCount = InterlockedIncrement( &NameArray->Count);
5153 lCount = InterlockedIncrement( &DirEntry->OpenReferenceCount);
5155 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5156 AFS_TRACE_LEVEL_VERBOSE,
5157 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
5158 &DirEntry->NameInformation.FileName,
5162 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5164 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5166 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5177 AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
5178 IN AFSDirectoryCB *DirectoryCB)
5182 ASSERT( NameArray->CurrentEntry != NULL);
5184 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5186 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5187 AFS_TRACE_LEVEL_VERBOSE,
5188 "AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
5189 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5190 NameArray->CurrentEntry->DirectoryCB,
5193 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5195 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5196 AFS_TRACE_LEVEL_VERBOSE,
5197 "AFSReplaceCurrentElement Increment count on %wZ DE %p Cnt %d\n",
5198 &DirectoryCB->NameInformation.FileName,
5202 NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
5204 NameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
5206 NameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
5208 if( DirectoryCB->ObjectInformation->ParentObjectInformation == NULL)
5211 SetFlag( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5218 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5221 AFSDirectoryCB *pCurrentDirEntry = NULL;
5227 if( NameArray->Count == 0)
5229 try_return( pCurrentDirEntry);
5232 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5234 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5235 AFS_TRACE_LEVEL_VERBOSE,
5236 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5237 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5238 NameArray->CurrentEntry->DirectoryCB,
5241 NameArray->CurrentEntry->DirectoryCB = NULL;
5243 lCount = InterlockedDecrement( &NameArray->Count);
5247 NameArray->CurrentEntry = NULL;
5251 NameArray->CurrentEntry--;
5252 pCurrentDirEntry = NameArray->CurrentEntry->DirectoryCB;
5260 return pCurrentDirEntry;
5264 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5267 AFSDirectoryCB *pDirEntry = NULL;
5268 AFSNameArrayCB *pElement = NULL;
5273 if( NameArray->Count == 0 ||
5274 NameArray->Count == 1)
5277 try_return( pDirEntry = NULL);
5280 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5282 pDirEntry = pElement->DirectoryCB;
5293 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5294 IN AFSDirectoryCB *DirEntry)
5297 AFSNameArrayCB *pCurrentElement = NULL;
5298 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5304 pCurrentElement = &NameArray->ElementArray[ 0];
5309 if( pCurrentElement->DirectoryCB == NULL)
5315 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5317 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5318 AFS_TRACE_LEVEL_VERBOSE,
5319 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5320 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5321 pCurrentElement->DirectoryCB,
5327 RtlZeroMemory( NameArray,
5328 sizeof( AFSNameArrayHdr) +
5329 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5331 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5333 if( DirEntry != NULL)
5336 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5338 lCount = InterlockedIncrement( &NameArray->Count);
5340 lCount = InterlockedIncrement( &DirEntry->OpenReferenceCount);
5342 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5343 AFS_TRACE_LEVEL_VERBOSE,
5344 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5345 &DirEntry->NameInformation.FileName,
5349 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5351 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5353 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5361 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5364 AFSNameArrayCB *pCurrentElement = NULL;
5366 pCurrentElement = &NameArray->ElementArray[ 0];
5368 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5370 while( pCurrentElement->DirectoryCB != NULL)
5373 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5374 pCurrentElement->FileId.Cell,
5375 pCurrentElement->FileId.Volume,
5376 pCurrentElement->FileId.Vnode,
5377 pCurrentElement->FileId.Unique,
5378 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5383 AFSPrint("AFSDumpNameArray End\n\n");
5389 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5394 // Depending on the type of node, set the event
5397 switch( Fcb->Header.NodeTypeCode)
5400 case AFS_DIRECTORY_FCB:
5405 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5415 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5421 // Depending on the type of node, set the event
5424 switch( Fcb->Header.NodeTypeCode)
5427 case AFS_DIRECTORY_FCB:
5432 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5434 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5444 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5447 BOOLEAN bIsInProcess = FALSE;
5452 if( ObjectInfo->Fcb == NULL)
5455 try_return( bIsInProcess);
5458 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5461 case AFS_DIRECTORY_FCB:
5466 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5469 bIsInProcess = TRUE;
5481 return bIsInProcess;
5485 AFSVerifyVolume( IN ULONGLONG ProcessId,
5486 IN AFSVolumeCB *VolumeCB)
5489 NTSTATUS ntStatus = STATUS_SUCCESS;
5496 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5499 NTSTATUS ntStatus = STATUS_SUCCESS;
5500 AFSObjectInfoCB *pObjectInfoCB = NULL;
5501 AFSDirectoryCB *pDirNode = NULL;
5502 ULONG ulEntryLength = 0;
5503 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5509 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5512 if( pObjectInfoCB == NULL)
5515 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5518 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5519 AFS_TRACE_LEVEL_VERBOSE,
5520 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5523 pObjectInfoCB->ObjectReferenceCount = 1;
5525 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5527 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5529 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5531 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5535 if( pDirNode == NULL)
5538 AFSDeleteObjectInfo( pObjectInfoCB);
5540 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5543 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5544 sizeof( AFSNonPagedDirectoryCB),
5545 AFS_DIR_ENTRY_NP_TAG);
5547 if( pNonPagedDirEntry == NULL)
5550 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5553 RtlZeroMemory( pDirNode,
5556 RtlZeroMemory( pNonPagedDirEntry,
5557 sizeof( AFSNonPagedDirectoryCB));
5559 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5561 pDirNode->NonPaged = pNonPagedDirEntry;
5563 pDirNode->ObjectInformation = pObjectInfoCB;
5565 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5571 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5573 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5575 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5577 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5579 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5580 AFSPIOCtlName.Buffer,
5581 pDirNode->NameInformation.FileName.Length);
5583 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5586 if ( InterlockedCompareExchangePointer( (PVOID *)&ObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5589 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5590 AFS_TRACE_LEVEL_WARNING,
5591 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %08lX pFcb %08lX\n",
5592 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5596 // Increment the open reference and handle on the node
5599 lCount = InterlockedIncrement( &pDirNode->ObjectInformation->ObjectReferenceCount);
5601 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
5602 AFS_TRACE_LEVEL_VERBOSE,
5603 "AFSInitPIOCtlDirectoryCB Increment count on Object %08lX Cnt %d\n",
5604 pDirNode->ObjectInformation,
5607 try_return( ntStatus = STATUS_REPARSE);
5612 if ( ntStatus != STATUS_SUCCESS)
5615 if ( pDirNode != NULL)
5618 AFSExFreePool( pDirNode);
5621 if ( pObjectInfoCB != NULL)
5624 AFSDeleteObjectInfo( pObjectInfoCB);
5633 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5634 IN AFSDirectoryCB *DirectoryCB,
5635 IN UNICODE_STRING *ParentPathName,
5636 IN AFSNameArrayHdr *RelatedNameArray,
5638 OUT AFSFileInfoCB *FileInfo)
5641 NTSTATUS ntStatus = STATUS_SUCCESS;
5642 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
5643 UNICODE_STRING uniFullPathName;
5644 AFSNameArrayHdr *pNameArray = NULL;
5645 AFSVolumeCB *pVolumeCB = NULL;
5646 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5647 WCHAR *pwchBuffer = NULL;
5648 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5649 ULONG ulNameDifference = 0;
5656 // Retrieve a target name for the entry
5659 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5662 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5665 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5667 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5672 if( !NT_SUCCESS( ntStatus) ||
5673 pDirEntry->TargetNameLength == 0)
5676 if( pDirEntry != NULL)
5679 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5682 try_return( ntStatus);
5685 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5688 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5692 // Update the target name
5695 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5696 &DirectoryCB->Flags,
5697 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5698 (USHORT)pDirEntry->TargetNameLength);
5700 if( !NT_SUCCESS( ntStatus))
5703 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5705 try_return( ntStatus);
5709 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5713 // Need to pass the full path in for parsing.
5716 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5719 uniFullPathName.Length = 0;
5720 uniFullPathName.MaximumLength = ParentPathName->Length +
5722 DirectoryCB->NameInformation.TargetName.Length;
5724 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5725 uniFullPathName.MaximumLength,
5726 AFS_NAME_BUFFER_SIX_TAG);
5728 if( uniFullPathName.Buffer == NULL)
5731 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5733 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5736 pwchBuffer = uniFullPathName.Buffer;
5738 RtlZeroMemory( uniFullPathName.Buffer,
5739 uniFullPathName.MaximumLength);
5741 RtlCopyMemory( uniFullPathName.Buffer,
5742 ParentPathName->Buffer,
5743 ParentPathName->Length);
5745 uniFullPathName.Length = ParentPathName->Length;
5747 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5748 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5751 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5753 uniFullPathName.Length += sizeof( WCHAR);
5756 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5757 DirectoryCB->NameInformation.TargetName.Buffer,
5758 DirectoryCB->NameInformation.TargetName.Length);
5760 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5762 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5763 uniParsedName.MaximumLength = uniParsedName.Length;
5765 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5767 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5770 // We populate up to the current parent
5773 if( RelatedNameArray != NULL)
5776 pNameArray = AFSInitNameArray( NULL,
5777 RelatedNameArray->MaxElementCount);
5779 if( pNameArray == NULL)
5782 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5785 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5792 pNameArray = AFSInitNameArray( NULL,
5795 if( pNameArray == NULL)
5798 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5801 ntStatus = AFSPopulateNameArray( pNameArray,
5806 if( !NT_SUCCESS( ntStatus))
5809 try_return( ntStatus);
5812 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5814 pParentDirEntry = ParentDirectoryCB;
5819 uniFullPathName.Length = 0;
5820 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5822 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5823 uniFullPathName.MaximumLength,
5824 AFS_NAME_BUFFER_SEVEN_TAG);
5826 if( uniFullPathName.Buffer == NULL)
5829 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5831 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5834 pwchBuffer = uniFullPathName.Buffer;
5836 RtlZeroMemory( uniFullPathName.Buffer,
5837 uniFullPathName.MaximumLength);
5839 RtlCopyMemory( uniFullPathName.Buffer,
5840 DirectoryCB->NameInformation.TargetName.Buffer,
5841 DirectoryCB->NameInformation.TargetName.Length);
5843 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5846 // This name should begin with the \afs server so parse it off and check it
5849 FsRtlDissectName( uniFullPathName,
5853 if( RtlCompareUnicodeString( &uniComponentName,
5858 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5860 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5861 AFS_TRACE_LEVEL_ERROR,
5862 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5865 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5868 uniFullPathName = uniRemainingPath;
5870 uniParsedName = uniFullPathName;
5872 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5874 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5880 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5883 if( pNameArray == NULL)
5886 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5889 pVolumeCB = AFSGlobalRoot;
5891 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5895 // Increment the ref count on the volume and dir entry for correct processing below
5898 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
5900 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5901 AFS_TRACE_LEVEL_VERBOSE,
5902 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
5906 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
5908 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5909 AFS_TRACE_LEVEL_VERBOSE,
5910 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5911 &pParentDirEntry->NameInformation.FileName,
5916 ntStatus = AFSLocateNameEntry( NULL,
5921 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5927 if( !NT_SUCCESS( ntStatus))
5931 // The volume lock was released on failure above
5932 // Except for STATUS_OBJECT_NAME_NOT_FOUND
5935 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
5938 if( pVolumeCB != NULL)
5941 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5943 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5944 AFS_TRACE_LEVEL_VERBOSE,
5945 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
5950 if( pDirectoryEntry != NULL)
5953 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5955 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5956 AFS_TRACE_LEVEL_VERBOSE,
5957 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5958 &pDirectoryEntry->NameInformation.FileName,
5966 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
5968 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5969 AFS_TRACE_LEVEL_VERBOSE,
5970 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5971 &pParentDirEntry->NameInformation.FileName,
5980 try_return( ntStatus);
5984 // Store off the information
5987 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5990 // Check for the mount point being returned
5993 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
5996 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5998 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
5999 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6002 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6005 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6010 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6014 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6016 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6018 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6020 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6022 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6024 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6027 // Remove the reference made above
6030 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6032 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6033 AFS_TRACE_LEVEL_VERBOSE,
6034 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
6035 &pDirectoryEntry->NameInformation.FileName,
6042 if( pDirEntry != NULL)
6045 AFSExFreePool( pDirEntry);
6048 if( pVolumeCB != NULL)
6051 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6053 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6054 AFS_TRACE_LEVEL_VERBOSE,
6055 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
6060 if( pNameArray != NULL)
6063 AFSFreeNameArray( pNameArray);
6066 if( pwchBuffer != NULL)
6070 // Always free the buffer that we allocated as AFSLocateNameEntry
6071 // will not free it. If uniFullPathName.Buffer was allocated by
6072 // AFSLocateNameEntry, then we must free that as well.
6073 // Check that the uniFullPathName.Buffer in the string is not the same
6074 // offset by the length of the server name
6077 if( uniFullPathName.Length > 0 &&
6078 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6081 AFSExFreePool( uniFullPathName.Buffer);
6084 AFSExFreePool( pwchBuffer);
6092 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6093 IN ULONGLONG HashIndex)
6096 NTSTATUS ntStatus = STATUS_SUCCESS;
6097 AFSObjectInfoCB *pObjectInfo = NULL;
6103 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6104 sizeof( AFSObjectInfoCB),
6105 AFS_OBJECT_INFO_TAG);
6107 if( pObjectInfo == NULL)
6110 try_return( pObjectInfo);
6113 RtlZeroMemory( pObjectInfo,
6114 sizeof( AFSObjectInfoCB));
6116 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6117 sizeof( AFSNonPagedObjectInfoCB),
6118 AFS_NP_OBJECT_INFO_TAG);
6120 if( pObjectInfo->NonPagedInfo == NULL)
6123 AFSExFreePool( pObjectInfo);
6125 try_return( pObjectInfo = NULL);
6128 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6130 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6132 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6134 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6136 if( ParentObjectInfo != NULL)
6138 lCount = InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
6142 // Initialize the access time
6145 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6151 // Insert the entry into the object tree and list
6154 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6156 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6159 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6164 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6165 &pObjectInfo->TreeEntry);
6167 ASSERT( NT_SUCCESS( ntStatus));
6171 // And the object list in the volume
6174 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6177 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6182 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6184 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6187 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6190 // Indicate the object is in the hash tree and linked list in the volume
6193 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6205 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6208 BOOLEAN bAcquiredTreeLock = FALSE;
6211 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6214 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6216 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6219 bAcquiredTreeLock = TRUE;
6223 // Remove it from the tree and list if it was inserted
6226 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6229 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6230 &ObjectInfo->TreeEntry);
6233 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6236 if( ObjectInfo->ListEntry.fLink == NULL)
6239 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6241 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6244 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6250 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6253 if( ObjectInfo->ListEntry.bLink == NULL)
6256 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6258 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6261 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6267 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6271 if( ObjectInfo->ParentObjectInformation != NULL)
6274 lCount = InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
6277 if( bAcquiredTreeLock)
6280 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6284 // Release the fid in the service
6287 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6290 AFSReleaseFid( &ObjectInfo->FileId);
6293 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6295 AFSExFreePool( ObjectInfo->NonPagedInfo);
6297 AFSExFreePool( ObjectInfo);
6303 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6304 OUT AFSDirectoryCB **TargetDirEntry)
6307 NTSTATUS ntStatus = STATUS_SUCCESS;
6308 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6309 UNICODE_STRING uniFullPathName;
6310 AFSNameArrayHdr *pNameArray = NULL;
6311 AFSVolumeCB *pVolumeCB = NULL;
6312 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6313 WCHAR *pwchBuffer = NULL;
6314 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6315 ULONG ulNameDifference = 0;
6322 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6323 DirectoryCB->ObjectInformation,
6327 if( !NT_SUCCESS( ntStatus))
6329 try_return( ntStatus);
6333 // Retrieve a target name for the entry
6336 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6339 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6342 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6344 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6349 if( !NT_SUCCESS( ntStatus) ||
6350 pDirEntry->TargetNameLength == 0)
6353 if( pDirEntry != NULL)
6356 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6359 try_return( ntStatus);
6362 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6365 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6369 // Update the target name
6372 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6373 &DirectoryCB->Flags,
6374 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6375 (USHORT)pDirEntry->TargetNameLength);
6377 if( !NT_SUCCESS( ntStatus))
6380 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6382 try_return( ntStatus);
6386 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6390 // Need to pass the full path in for parsing.
6393 uniFullPathName.Length = 0;
6394 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6396 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6397 uniFullPathName.MaximumLength,
6398 AFS_NAME_BUFFER_EIGHT_TAG);
6400 if( uniFullPathName.Buffer == NULL)
6403 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6405 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6408 pwchBuffer = uniFullPathName.Buffer;
6410 RtlZeroMemory( uniFullPathName.Buffer,
6411 uniFullPathName.MaximumLength);
6413 RtlCopyMemory( uniFullPathName.Buffer,
6414 DirectoryCB->NameInformation.TargetName.Buffer,
6415 DirectoryCB->NameInformation.TargetName.Length);
6417 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6420 // This name should begin with the \afs server so parse it off and chech it
6423 FsRtlDissectName( uniFullPathName,
6427 if( RtlCompareUnicodeString( &uniComponentName,
6433 // Try evaluating the full path
6436 uniFullPathName.Buffer = pwchBuffer;
6438 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6440 uniFullPathName.MaximumLength = uniFullPathName.Length;
6445 uniFullPathName = uniRemainingPath;
6448 uniParsedName = uniFullPathName;
6450 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6452 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6458 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6461 if( pNameArray == NULL)
6464 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6467 pVolumeCB = AFSGlobalRoot;
6469 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6471 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6473 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6474 AFS_TRACE_LEVEL_VERBOSE,
6475 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6479 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6481 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6482 AFS_TRACE_LEVEL_VERBOSE,
6483 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6484 &pParentDirEntry->NameInformation.FileName,
6489 ntStatus = AFSLocateNameEntry( NULL,
6500 if( !NT_SUCCESS( ntStatus))
6504 // The volume lock was released on failure above
6505 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6508 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6511 if( pVolumeCB != NULL)
6514 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6516 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6517 AFS_TRACE_LEVEL_VERBOSE,
6518 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
6523 if( pDirectoryEntry != NULL)
6526 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6528 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6529 AFS_TRACE_LEVEL_VERBOSE,
6530 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6531 &pDirectoryEntry->NameInformation.FileName,
6539 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6541 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6542 AFS_TRACE_LEVEL_VERBOSE,
6543 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6544 &pParentDirEntry->NameInformation.FileName,
6553 try_return( ntStatus);
6557 // Pass back the target dir entry for this request
6560 *TargetDirEntry = pDirectoryEntry;
6564 if( pDirEntry != NULL)
6567 AFSExFreePool( pDirEntry);
6570 if( pVolumeCB != NULL)
6573 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6575 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6576 AFS_TRACE_LEVEL_VERBOSE,
6577 "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
6582 if( pNameArray != NULL)
6585 AFSFreeNameArray( pNameArray);
6588 if( pwchBuffer != NULL)
6592 // Always free the buffer that we allocated as AFSLocateNameEntry
6593 // will not free it. If uniFullPathName.Buffer was allocated by
6594 // AFSLocateNameEntry, then we must free that as well.
6595 // Check that the uniFullPathName.Buffer in the string is not the same
6596 // offset by the length of the server name
6599 if( uniFullPathName.Length > 0 &&
6600 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6603 AFSExFreePool( uniFullPathName.Buffer);
6606 AFSExFreePool( pwchBuffer);
6614 AFSCleanupFcb( IN AFSFcb *Fcb,
6615 IN BOOLEAN ForceFlush)
6618 NTSTATUS ntStatus = STATUS_SUCCESS;
6619 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6620 LARGE_INTEGER liTime;
6621 IO_STATUS_BLOCK stIoStatus;
6626 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6628 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6630 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6633 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6634 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6637 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6640 if( Fcb->OpenReferenceCount > 0)
6646 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6651 if( !NT_SUCCESS( stIoStatus.Status))
6654 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6655 AFS_TRACE_LEVEL_ERROR,
6656 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6657 Fcb->ObjectInformation->FileId.Cell,
6658 Fcb->ObjectInformation->FileId.Volume,
6659 Fcb->ObjectInformation->FileId.Vnode,
6660 Fcb->ObjectInformation->FileId.Unique,
6662 stIoStatus.Information);
6664 ntStatus = stIoStatus.Status;
6667 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6672 __except( EXCEPTION_EXECUTE_HANDLER)
6674 ntStatus = GetExceptionCode();
6678 AFSReleaseResource( &Fcb->NPFcb->Resource);
6681 // Wait for any currently running flush or release requests to complete
6684 AFSWaitOnQueuedFlushes( Fcb);
6687 // Now perform another flush on the file
6690 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6694 AFSReleaseExtentsWithFlush( Fcb,
6699 if( Fcb->OpenReferenceCount == 0 ||
6700 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6701 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6704 AFSTearDownFcbExtents( Fcb,
6708 try_return( ntStatus);
6711 KeQueryTickCount( &liTime);
6714 // First up are there dirty extents in the cache to flush?
6718 ( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6719 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
6720 ( Fcb->Specific.File.ExtentsDirtyCount ||
6721 Fcb->Specific.File.ExtentCount) &&
6722 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6723 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6725 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6727 Fcb->OpenReferenceCount == 0)
6730 AFSReleaseExtentsWithFlush( Fcb,
6734 else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6735 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6739 // The file has been marked as invalid. Dump it
6742 AFSTearDownFcbExtents( Fcb,
6747 // If there are extents and they haven't been used recently *and*
6748 // are not being used
6752 ( 0 != Fcb->Specific.File.ExtentCount &&
6753 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6754 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6755 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
6756 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6763 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6768 if( !NT_SUCCESS( stIoStatus.Status))
6771 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6772 AFS_TRACE_LEVEL_ERROR,
6773 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6774 Fcb->ObjectInformation->FileId.Cell,
6775 Fcb->ObjectInformation->FileId.Volume,
6776 Fcb->ObjectInformation->FileId.Vnode,
6777 Fcb->ObjectInformation->FileId.Unique,
6779 stIoStatus.Information);
6781 ntStatus = stIoStatus.Status;
6787 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6793 __except( EXCEPTION_EXECUTE_HANDLER)
6795 ntStatus = GetExceptionCode();
6798 AFSReleaseResource( &Fcb->NPFcb->Resource);
6800 if( Fcb->OpenReferenceCount == 0)
6804 // Tear em down we'll not be needing them again
6807 AFSTearDownFcbExtents( Fcb,
6821 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
6822 IN UNICODE_STRING *NewFileName)
6825 NTSTATUS ntStatus = STATUS_SUCCESS;
6826 WCHAR *pTmpBuffer = NULL;
6831 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
6834 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
6837 AFSExFreePool( DirectoryCB->NameInformation.FileName.Buffer);
6839 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6841 DirectoryCB->NameInformation.FileName.Buffer = NULL;
6845 // OK, we need to allocate a new name buffer
6848 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6849 NewFileName->Length,
6850 AFS_NAME_BUFFER_NINE_TAG);
6852 if( pTmpBuffer == NULL)
6855 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6858 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
6860 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
6862 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6865 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
6867 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
6868 NewFileName->Buffer,
6869 NewFileName->Length);
6880 AFSReadCacheFile( IN void *ReadBuffer,
6881 IN LARGE_INTEGER *ReadOffset,
6882 IN ULONG RequestedDataLength,
6883 IN OUT PULONG BytesRead)
6886 NTSTATUS ntStatus = STATUS_SUCCESS;
6889 PIO_STACK_LOCATION pIoStackLocation = NULL;
6890 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6891 DEVICE_OBJECT *pTargetDeviceObject = NULL;
6892 FILE_OBJECT *pCacheFileObject = NULL;
6897 pCacheFileObject = AFSReferenceCacheFileObject();
6899 if( pCacheFileObject == NULL)
6901 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
6904 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
6907 // Initialize the event
6910 KeInitializeEvent( &kEvent,
6911 SynchronizationEvent,
6915 // Allocate an irp for this request. This could also come from a
6916 // private pool, for instance.
6919 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
6925 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6929 // Build the IRP's main body
6932 pIrp->UserBuffer = ReadBuffer;
6934 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
6935 pIrp->RequestorMode = KernelMode;
6936 pIrp->Flags |= IRP_READ_OPERATION;
6939 // Set up the I/O stack location.
6942 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
6943 pIoStackLocation->MajorFunction = IRP_MJ_READ;
6944 pIoStackLocation->DeviceObject = pTargetDeviceObject;
6945 pIoStackLocation->FileObject = pCacheFileObject;
6946 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
6948 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
6951 // Set the completion routine.
6954 IoSetCompletionRoutine( pIrp,
6962 // Send it to the FSD
6965 ntStatus = IoCallDriver( pTargetDeviceObject,
6968 if( NT_SUCCESS( ntStatus))
6975 ntStatus = KeWaitForSingleObject( &kEvent,
6981 if( NT_SUCCESS( ntStatus))
6984 ntStatus = pIrp->IoStatus.Status;
6986 *BytesRead = (ULONG)pIrp->IoStatus.Information;
6992 if( pCacheFileObject != NULL)
6994 AFSReleaseCacheFileObject( pCacheFileObject);
7000 if( pIrp->MdlAddress != NULL)
7003 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7006 MmUnlockPages( pIrp->MdlAddress);
7009 IoFreeMdl( pIrp->MdlAddress);
7012 pIrp->MdlAddress = NULL;
7026 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7031 KEVENT *pEvent = (KEVENT *)Context;
7037 return STATUS_MORE_PROCESSING_REQUIRED;
7041 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7044 BOOLEAN bIsEmpty = FALSE;
7045 AFSDirectoryCB *pDirEntry = NULL;
7050 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7055 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7058 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7060 while( pDirEntry != NULL)
7063 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7064 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7072 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7077 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7084 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7085 IN AFSDirectoryCB *DirEntry)
7088 NTSTATUS ntStatus = STATUS_SUCCESS;
7093 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7096 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7097 AFS_TRACE_LEVEL_VERBOSE,
7098 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7100 &DirEntry->NameInformation.FileName);
7102 try_return( ntStatus);
7105 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7108 // Remove the entry from the parent tree
7111 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7112 AFS_TRACE_LEVEL_VERBOSE,
7113 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7115 &DirEntry->NameInformation.FileName);
7117 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7120 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7121 AFS_TRACE_LEVEL_VERBOSE,
7122 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7124 &DirEntry->NameInformation.FileName);
7126 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7129 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7133 // From the short name tree
7136 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7137 AFS_TRACE_LEVEL_VERBOSE,
7138 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7140 &DirEntry->NameInformation.FileName);
7142 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7145 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7148 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7149 AFS_TRACE_LEVEL_VERBOSE,
7150 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7152 &DirEntry->NameInformation.FileName);
7154 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7156 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7167 AFSGetAuthenticationId()
7170 LARGE_INTEGER liAuthId = {0,0};
7171 NTSTATUS ntStatus = STATUS_SUCCESS;
7172 PACCESS_TOKEN hToken = NULL;
7173 PTOKEN_STATISTICS pTokenInfo = NULL;
7174 BOOLEAN bCopyOnOpen = FALSE;
7175 BOOLEAN bEffectiveOnly = FALSE;
7176 BOOLEAN bPrimaryToken = FALSE;
7177 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7182 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7185 &stImpersonationLevel);
7190 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7195 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7196 AFS_TRACE_LEVEL_ERROR,
7197 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7199 try_return( ntStatus);
7202 bPrimaryToken = TRUE;
7205 ntStatus = SeQueryInformationToken( hToken,
7207 (PVOID *)&pTokenInfo);
7209 if( !NT_SUCCESS( ntStatus))
7212 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7213 AFS_TRACE_LEVEL_ERROR,
7214 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7216 try_return( ntStatus);
7219 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7220 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7222 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7223 AFS_TRACE_LEVEL_VERBOSE,
7224 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7235 PsDereferenceImpersonationToken( hToken);
7240 PsDereferencePrimaryToken( hToken);
7244 if( pTokenInfo != NULL)
7247 AFSExFreePool( pTokenInfo);
7255 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7259 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7261 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7264 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7266 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7269 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7271 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7274 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7276 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7279 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7281 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7288 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7291 BOOLEAN bIsValid = TRUE;
7293 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7295 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7297 while( pCurrentDirEntry != NULL)
7300 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7304 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7309 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7310 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7313 if( pDirEntry == NULL)
7320 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7323 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7326 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7328 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7330 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7339 AFSReferenceCacheFileObject()
7342 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7343 FILE_OBJECT *pCacheFileObject = NULL;
7345 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7348 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7350 if( pCacheFileObject != NULL)
7352 ObReferenceObject( pCacheFileObject);
7355 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7357 return pCacheFileObject;
7361 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7364 ASSERT( CacheFileObject != NULL);
7366 ObDereferenceObject( CacheFileObject);
7372 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7375 NTSTATUS ntStatus = STATUS_SUCCESS;
7376 AFSDeviceExt *pControlDevExt = NULL;
7377 ULONG ulTimeIncrement = 0;
7382 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7384 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7386 AFSServerName = LibraryInit->AFSServerName;
7388 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7391 // Callbacks in the framework
7394 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7396 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7398 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7400 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7402 AFSExFreePool = LibraryInit->AFSExFreePool;
7404 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7406 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7408 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7410 if( LibraryInit->AFSCacheBaseAddress != NULL)
7413 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7415 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7417 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7421 // Initialize some flush parameters
7424 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7426 ulTimeIncrement = KeQueryTimeIncrement();
7428 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7429 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7430 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7431 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7432 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7435 // Initialize the global root entry
7438 ntStatus = AFSInitVolume( NULL,
7439 &LibraryInit->GlobalRootFid,
7442 if( !NT_SUCCESS( ntStatus))
7445 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7446 AFS_TRACE_LEVEL_ERROR,
7447 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7450 try_return( ntStatus);
7453 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7456 if( !NT_SUCCESS( ntStatus))
7459 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7460 AFS_TRACE_LEVEL_ERROR,
7461 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7464 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7466 try_return( ntStatus);
7470 // Update the node type code to AFS_ROOT_ALL
7473 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7475 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7478 // Invalidate all known volumes since contact with the service and therefore
7479 // the file server was lost.
7482 AFSInvalidateAllVolumes();
7485 // Drop the locks acquired above
7488 AFSInitVolumeWorker( AFSGlobalRoot);
7490 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7492 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7506 NTSTATUS ntStatus = STATUS_SUCCESS;
7507 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7512 if( AFSGlobalDotDirEntry != NULL)
7515 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
7517 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7519 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7521 ExFreePool( AFSGlobalDotDirEntry);
7523 AFSGlobalDotDirEntry = NULL;
7526 if( AFSGlobalDotDotDirEntry != NULL)
7529 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
7531 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7533 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7535 ExFreePool( AFSGlobalDotDotDirEntry);
7537 AFSGlobalDotDotDirEntry = NULL;
7540 if( AFSSpecialShareNames != NULL)
7543 pDirNode = AFSSpecialShareNames;
7545 while( pDirNode != NULL)
7548 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7550 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
7552 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7554 ExFreePool( pDirNode->NonPaged);
7556 ExFreePool( pDirNode);
7558 pDirNode = pLastDirNode;
7561 AFSSpecialShareNames = NULL;
7569 AFSDefaultLogMsg( IN ULONG Subsystem,
7575 NTSTATUS ntStatus = STATUS_SUCCESS;
7577 char chDebugBuffer[ 256];
7582 va_start( va_args, Format);
7584 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7589 if( NT_SUCCESS( ntStatus))
7591 DbgPrint( chDebugBuffer);
7601 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7602 IN ULONG InputBufferLength,
7603 IN AFSStatusInfoCB *StatusInfo,
7604 OUT ULONG *ReturnLength)
7607 NTSTATUS ntStatus = STATUS_SUCCESS;
7608 AFSFcb *pFcb = NULL;
7609 AFSVolumeCB *pVolumeCB = NULL;
7610 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7611 AFSObjectInfoCB *pObjectInfo = NULL;
7612 ULONGLONG ullIndex = 0;
7613 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7614 AFSNameArrayHdr *pNameArray = NULL;
7615 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7622 // If we are given a FID then look up the entry by that, otherwise
7626 if( GetStatusInfo->FileID.Cell != 0 &&
7627 GetStatusInfo->FileID.Volume != 0 &&
7628 GetStatusInfo->FileID.Vnode != 0 &&
7629 GetStatusInfo->FileID.Unique != 0)
7632 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7635 // Locate the volume node
7638 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7640 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7642 (AFSBTreeEntry **)&pVolumeCB);
7644 if( pVolumeCB != NULL)
7647 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7649 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7650 AFS_TRACE_LEVEL_VERBOSE,
7651 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7656 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7658 if( !NT_SUCCESS( ntStatus) ||
7661 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7664 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
7667 pObjectInfo = &pVolumeCB->ObjectInformation;
7669 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7671 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7676 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
7679 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7681 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7682 AFS_TRACE_LEVEL_VERBOSE,
7683 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7687 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
7689 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
7691 (AFSBTreeEntry **)&pObjectInfo);
7693 if( pObjectInfo != NULL)
7697 // Reference the node so it won't be torn down
7700 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7702 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7703 AFS_TRACE_LEVEL_VERBOSE,
7704 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
7709 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
7711 if( !NT_SUCCESS( ntStatus) ||
7712 pObjectInfo == NULL)
7714 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7721 if( GetStatusInfo->FileNameLength == 0 ||
7722 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
7724 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7727 uniFullPathName.Length = GetStatusInfo->FileNameLength;
7728 uniFullPathName.MaximumLength = uniFullPathName.Length;
7730 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
7733 // This name should begin with the \afs server so parse it off and check it
7736 FsRtlDissectName( uniFullPathName,
7740 if( RtlCompareUnicodeString( &uniComponentName,
7744 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7745 AFS_TRACE_LEVEL_ERROR,
7746 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
7749 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
7752 uniFullPathName = uniRemainingPath;
7754 uniParsedName = uniFullPathName;
7760 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7763 if( pNameArray == NULL)
7765 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7768 pVolumeCB = AFSGlobalRoot;
7770 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7773 // Increment the ref count on the volume and dir entry for correct processing below
7776 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7778 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7779 AFS_TRACE_LEVEL_VERBOSE,
7780 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7784 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
7786 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7787 AFS_TRACE_LEVEL_VERBOSE,
7788 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7789 &pParentDirEntry->NameInformation.FileName,
7794 ntStatus = AFSLocateNameEntry( NULL,
7799 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
7800 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
7806 if( !NT_SUCCESS( ntStatus))
7810 // The volume lock was released on failure above
7811 // Except for STATUS_OBJECT_NAME_NOT_FOUND
7814 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
7817 if( pVolumeCB != NULL)
7820 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7822 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7823 AFS_TRACE_LEVEL_VERBOSE,
7824 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7829 if( pDirectoryEntry != NULL)
7832 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7834 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7835 AFS_TRACE_LEVEL_VERBOSE,
7836 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7837 &pDirectoryEntry->NameInformation.FileName,
7845 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
7847 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7848 AFS_TRACE_LEVEL_VERBOSE,
7849 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7850 &pParentDirEntry->NameInformation.FileName,
7859 try_return( ntStatus);
7863 // Remove the reference made above
7866 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7868 pObjectInfo = pDirectoryEntry->ObjectInformation;
7870 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7872 if( pVolumeCB != NULL)
7875 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7877 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7878 AFS_TRACE_LEVEL_VERBOSE,
7879 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
7881 pVolumeCB->VolumeReferenceCount);
7886 // At this point we have an object info block, return the information
7889 StatusInfo->FileId = pObjectInfo->FileId;
7891 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
7893 StatusInfo->Expiration = pObjectInfo->Expiration;
7895 StatusInfo->DataVersion = pObjectInfo->DataVersion;
7897 StatusInfo->FileType = pObjectInfo->FileType;
7899 StatusInfo->ObjectFlags = pObjectInfo->Flags;
7901 StatusInfo->CreationTime = pObjectInfo->CreationTime;
7903 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
7905 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
7907 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
7909 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
7911 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
7913 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
7915 StatusInfo->EaSize = pObjectInfo->EaSize;
7917 StatusInfo->Links = pObjectInfo->Links;
7920 // Return the information length
7923 *ReturnLength = sizeof( AFSStatusInfoCB);
7927 if( pObjectInfo != NULL)
7930 lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
7933 if( pNameArray != NULL)
7936 AFSFreeNameArray( pNameArray);
7944 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
7945 IN UNICODE_STRING *ComponentName)
7948 NTSTATUS ntStatus = STATUS_SUCCESS;
7949 AFSDirectoryCB *pDirEntry = NULL;
7957 // Search for the entry in the parent
7960 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7961 AFS_TRACE_LEVEL_VERBOSE_2,
7962 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
7965 ulCRC = AFSGenerateCRC( ComponentName,
7968 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7971 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7975 if( pDirEntry == NULL)
7979 // Missed so perform a case insensitive lookup
7982 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7983 AFS_TRACE_LEVEL_VERBOSE_2,
7984 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
7987 ulCRC = AFSGenerateCRC( ComponentName,
7990 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7994 if( pDirEntry == NULL)
7998 // OK, if this component is a valid short name then try
7999 // a lookup in the short name tree
8002 if( RtlIsNameLegalDOS8Dot3( ComponentName,
8007 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8008 AFS_TRACE_LEVEL_VERBOSE_2,
8009 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8012 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8019 if( pDirEntry != NULL)
8021 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
8024 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8026 if( pDirEntry == NULL)
8029 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8030 AFS_TRACE_LEVEL_VERBOSE_2,
8031 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
8034 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8038 // We have the symlink object but previously failed to process it so return access
8042 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8043 AFS_TRACE_LEVEL_VERBOSE_2,
8044 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8047 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8049 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
8060 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8061 OUT UNICODE_STRING *ComponentName)
8064 NTSTATUS ntStatus = STATUS_SUCCESS;
8065 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8067 uniFullPathName = *FullPathName;
8072 FsRtlDissectName( uniFullPathName,
8076 if( uniRemainingPath.Length == 0)
8081 uniFullPathName = uniRemainingPath;
8084 if( uniComponentName.Length > 0)
8086 *ComponentName = uniComponentName;
8093 AFSDumpTraceFiles_Default()
8099 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8102 BOOLEAN bIsValidName = TRUE;
8108 while( usIndex < FileName->Length/sizeof( WCHAR))
8111 if( FileName->Buffer[ usIndex] == L':' ||
8112 FileName->Buffer[ usIndex] == L'*' ||
8113 FileName->Buffer[ usIndex] == L'?' ||
8114 FileName->Buffer[ usIndex] == L'"' ||
8115 FileName->Buffer[ usIndex] == L'<' ||
8116 FileName->Buffer[ usIndex] == L'>')
8118 bIsValidName = FALSE;
8126 return bIsValidName;
8130 AFSCreateDefaultSecurityDescriptor()
8133 NTSTATUS ntStatus = STATUS_SUCCESS;
8135 ULONG ulSACLSize = 0;
8136 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8137 ULONG ulACESize = 0;
8138 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8139 ULONG ulSDLength = 0;
8140 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8141 PSID pWorldSID = NULL;
8142 ULONG *pulSubAuthority = NULL;
8143 ULONG ulWorldSIDLEngth = 0;
8148 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8150 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8152 AFS_GENERIC_MEMORY_29_TAG);
8154 if( pWorldSID == NULL)
8156 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8157 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8160 RtlZeroMemory( pWorldSID,
8163 RtlInitializeSid( pWorldSID,
8164 &SeWorldSidAuthority,
8167 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8168 *pulSubAuthority = SECURITY_WORLD_RID;
8170 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8173 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8178 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8180 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8182 AFS_GENERIC_MEMORY_29_TAG);
8187 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8189 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8192 RtlZeroMemory( pACE,
8195 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8196 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8197 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8198 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8200 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8202 SeExports->SeLowMandatorySid);
8204 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8205 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8207 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8209 AFS_GENERIC_MEMORY_29_TAG);
8214 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8216 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8219 ntStatus = RtlCreateAcl( pSACL,
8223 if( !NT_SUCCESS( ntStatus))
8226 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8229 try_return( ntStatus);
8232 ntStatus = RtlAddAce( pSACL,
8236 pACE->Header.AceSize);
8238 if( !NT_SUCCESS( ntStatus))
8241 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8244 try_return( ntStatus);
8248 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8249 sizeof( SECURITY_DESCRIPTOR),
8250 AFS_GENERIC_MEMORY_27_TAG);
8252 if( pSecurityDescr == NULL)
8255 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8257 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8260 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8261 SECURITY_DESCRIPTOR_REVISION);
8263 if( !NT_SUCCESS( ntStatus))
8266 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8269 try_return( ntStatus);
8272 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8274 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8279 if( !NT_SUCCESS( ntStatus))
8282 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8285 try_return( ntStatus);
8290 // Add in the group and owner to the SD
8293 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8295 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8299 if( !NT_SUCCESS( ntStatus))
8302 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8305 try_return( ntStatus);
8309 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8313 if( !NT_SUCCESS( ntStatus))
8316 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8319 try_return( ntStatus);
8322 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8325 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8327 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8330 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8332 AFS_GENERIC_MEMORY_27_TAG);
8334 if( pRelativeSecurityDescr == NULL)
8337 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8339 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8342 ulSDLength = PAGE_SIZE;
8344 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8345 pRelativeSecurityDescr,
8348 if( !NT_SUCCESS( ntStatus))
8351 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8354 try_return( ntStatus);
8357 AFSDefaultSD = pRelativeSecurityDescr;
8361 if( !NT_SUCCESS( ntStatus))
8364 if( pRelativeSecurityDescr != NULL)
8366 ExFreePool( pRelativeSecurityDescr);
8370 if( pSecurityDescr != NULL)
8372 ExFreePool( pSecurityDescr);
8385 if( pWorldSID != NULL)
8387 ExFreePool( pWorldSID);
8395 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8396 OUT UNICODE_STRING *ParentPath)
8401 *ParentPath = *FullFileName;
8404 // If the final character is a \, jump over it
8407 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8409 ParentPath->Length -= sizeof( WCHAR);
8412 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8414 ParentPath->Length -= sizeof( WCHAR);
8418 // And the separator
8421 ParentPath->Length -= sizeof( WCHAR);
8427 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8428 IN AFSObjectInfoCB *ObjectInfo,
8429 IN BOOLEAN WriteAccess,
8430 OUT GUID *AuthGroup)
8433 NTSTATUS ntStatus = STATUS_SUCCESS;
8434 GUID stAuthGroup, stZeroAuthGroup;
8435 BOOLEAN bFoundAuthGroup = FALSE;
8436 AFSCcb *pCcb = NULL;
8442 RtlZeroMemory( &stAuthGroup,
8445 RtlZeroMemory( &stZeroAuthGroup,
8451 if( ObjectInfo != NULL &&
8452 ObjectInfo->Fcb != NULL)
8454 pFcb = ObjectInfo->Fcb;
8461 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8464 pCcb = Fcb->CcbListHead;
8466 while( pCcb != NULL)
8470 pCcb->GrantedAccess & FILE_WRITE_DATA)
8472 RtlCopyMemory( &stAuthGroup,
8476 bFoundAuthGroup = TRUE;
8480 else if( pCcb->GrantedAccess & FILE_READ_DATA)
8483 // At least get the read-only access
8486 RtlCopyMemory( &stAuthGroup,
8490 bFoundAuthGroup = TRUE;
8493 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
8496 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
8499 if( !bFoundAuthGroup)
8502 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
8503 (ULONGLONG)PsGetCurrentThreadId(),
8506 if( RtlCompareMemory( &stZeroAuthGroup,
8508 sizeof( GUID)) == sizeof( GUID))
8511 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
8513 try_return( ntStatus = STATUS_ACCESS_DENIED);
8517 RtlCopyMemory( AuthGroup,
8530 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
8531 IN ULONG InvalidateReason)
8534 NTSTATUS ntStatus = STATUS_SUCCESS;
8535 IO_STATUS_BLOCK stIoStatus;
8538 ULONG ulProcessCount = 0;
8544 switch( InvalidateReason)
8547 case AFS_INVALIDATE_DELETED:
8550 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8551 ObjectInfo->Fcb != NULL)
8556 // Clear out the extents
8557 // And get rid of them (note this involves waiting
8558 // for any writes or reads to the cache to complete)
8561 (VOID) AFSTearDownFcbExtents( ObjectInfo->Fcb,
8568 case AFS_INVALIDATE_DATA_VERSION:
8571 LARGE_INTEGER liCurrentOffset = {0,0};
8572 LARGE_INTEGER liFlushLength = {0,0};
8573 ULONG ulFlushLength = 0;
8575 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
8576 ObjectInfo->Fcb != NULL)
8579 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
8582 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
8583 AFS_TRACE_LEVEL_VERBOSE,
8584 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %08lX EXCL %08lX\n",
8585 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
8586 PsGetCurrentThread());
8588 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
8594 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
8598 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
8602 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
8604 while( ulProcessCount < ulCount)
8606 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
8608 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
8610 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
8611 &pEntry->FileOffset,
8615 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
8619 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
8622 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
8624 while( liFlushLength.QuadPart > 0)
8627 if( liFlushLength.QuadPart > 512 * 1024000)
8629 ulFlushLength = 512 * 1024000;
8633 ulFlushLength = liFlushLength.LowPart;
8636 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
8641 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
8644 liFlushLength.QuadPart -= ulFlushLength;
8648 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
8656 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
8661 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
8665 __except( EXCEPTION_EXECUTE_HANDLER)
8668 ntStatus = GetExceptionCode();
8671 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
8673 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
8675 AFSReleaseCleanExtents( ObjectInfo->Fcb,
8689 if( ObjectInfo != NULL)
8691 InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);