2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2012, 2013 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
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
16 * nor the names of their contributors may be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission from Kernel Drivers, LLC and Your File System, Inc.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 // File: AFSGeneric.cpp
37 #include "AFSCommon.h"
40 // Function: AFSExceptionFilter
44 // This function is the exception handler
48 // A status is returned for the function
52 AFSExceptionFilter( IN CHAR *FunctionString,
54 IN PEXCEPTION_POINTERS ExceptPtrs)
57 UNREFERENCED_PARAMETER(Code);
58 PEXCEPTION_RECORD ExceptRec;
64 ExceptRec = ExceptPtrs->ExceptionRecord;
66 Context = ExceptPtrs->ContextRecord;
70 "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
74 ExceptRec->ExceptionCode,
75 ExceptRec->ExceptionAddress,
76 (void *)AFSExceptionFilter));
78 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
80 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
81 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
83 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
85 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
88 KeBugCheck( (ULONG)-2);
96 __except( EXCEPTION_EXECUTE_HANDLER)
102 return EXCEPTION_EXECUTE_HANDLER;
106 // Function: AFSLibExAllocatePoolWithTag()
108 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
109 // is configured on, then bugcheck the system if
110 // a memory allocation fails. The routine should be
111 // used for all memory allocations that are to be freed
112 // when the library is unloaded. Memory allocations that
113 // are to survive library unload and reload should be
114 // performed using AFSExAllocatePoolWithTag() which is
115 // provided by the AFS Framework.
118 // POOL_TYPE PoolType - Paged or NonPaged
119 // SIZE_T NumberOfBytes - requested allocation size
120 // ULONG Tag - Pool Allocation Tag to be applied for tracking
123 // void * - the memory allocation
127 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
128 IN SIZE_T NumberOfBytes,
132 void *pBuffer = NULL;
134 pBuffer = ExAllocatePoolWithTag( PoolType,
141 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
144 KeBugCheck( (ULONG)-2);
151 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
155 PsGetCurrentThread()));
165 // Function: AFSAcquireExcl()
167 // Purpose: Called to acquire a resource exclusive with optional wait
170 // PERESOURCE Resource - Resource to acquire
171 // BOOLEAN Wait - Whether to block
174 // BOOLEAN - Whether the mask was acquired
178 AFSAcquireExcl( IN PERESOURCE Resource,
182 BOOLEAN bStatus = FALSE;
185 // Normal kernel APCs must be disabled before calling
186 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
189 KeEnterCriticalRegion();
191 bStatus = ExAcquireResourceExclusiveLite( Resource,
197 KeLeaveCriticalRegion();
204 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
208 BOOLEAN bStatus = FALSE;
210 KeEnterCriticalRegion();
212 bStatus = ExAcquireSharedStarveExclusive( Resource,
218 KeLeaveCriticalRegion();
225 // Function: AFSAcquireShared()
227 // Purpose: Called to acquire a resource shared with optional wait
230 // PERESOURCE Resource - Resource to acquire
231 // BOOLEAN Wait - Whether to block
234 // BOOLEAN - Whether the mask was acquired
238 AFSAcquireShared( IN PERESOURCE Resource,
242 BOOLEAN bStatus = FALSE;
244 KeEnterCriticalRegion();
246 bStatus = ExAcquireResourceSharedLite( Resource,
252 KeLeaveCriticalRegion();
259 // Function: AFSReleaseResource()
261 // Purpose: Called to release a resource
264 // PERESOURCE Resource - Resource to release
271 AFSReleaseResource( IN PERESOURCE Resource)
274 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
275 AFS_TRACE_LEVEL_VERBOSE,
276 "AFSReleaseResource Releasing lock %p Thread %08lX\n",
278 PsGetCurrentThread()));
280 ExReleaseResourceLite( Resource);
282 KeLeaveCriticalRegion();
288 AFSConvertToShared( IN PERESOURCE Resource)
291 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
292 AFS_TRACE_LEVEL_VERBOSE,
293 "AFSConvertToShared Converting lock %p Thread %08lX\n",
295 PsGetCurrentThread()));
297 ExConvertExclusiveToSharedLite( Resource);
303 // Function: AFSCompleteRequest
307 // This function completes irps
311 // A status is returned for the function
315 AFSCompleteRequest( IN PIRP Irp,
319 Irp->IoStatus.Status = Status;
321 IoCompleteRequest( Irp,
328 // Function: AFSGenerateCRC
332 // Given a device and filename this function generates a CRC
336 // A status is returned for the function
340 AFSGenerateCRC( IN PUNICODE_STRING FileName,
341 IN BOOLEAN UpperCaseName)
345 NTSTATUS ntStatus = STATUS_SUCCESS;
347 ntStatus = RtlHashUnicodeString( FileName,
349 HASH_STRING_ALGORITHM_DEFAULT,
352 if( !NT_SUCCESS( ntStatus))
361 AFSLockSystemBuffer( IN PIRP Irp,
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( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
409 AFSDumpTraceFilesFnc();
411 IoFreeMdl( Irp->MdlAddress );
412 Irp->MdlAddress = NULL;
422 AFSLockUserBuffer( IN void *UserBuffer,
423 IN ULONG BufferLength,
427 NTSTATUS ntStatus = STATUS_SUCCESS;
428 void *pAddress = NULL;
434 pMdl = IoAllocateMdl( UserBuffer,
443 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
447 // Lock the new Mdl in memory.
453 MmProbeAndLockPages( pMdl,
457 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
460 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
463 AFSDumpTraceFilesFnc();
485 AFSMapToService( IN PIRP Irp,
489 NTSTATUS ntStatus = STATUS_SUCCESS;
490 void *pMappedBuffer = NULL;
491 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
497 if( pDevExt->Specific.Control.ServiceProcess == NULL)
500 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
503 if( Irp->MdlAddress == NULL)
506 if( AFSLockSystemBuffer( Irp,
510 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
515 // Attach to the service process for mapping
518 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
519 (PRKAPC_STATE)&stApcState);
521 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
528 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
535 return pMappedBuffer;
539 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
543 NTSTATUS ntStatus = STATUS_SUCCESS;
544 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
550 if( pDevExt->Specific.Control.ServiceProcess == NULL)
553 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
560 // Attach to the service process for mapping
563 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
564 (PRKAPC_STATE)&stApcState);
566 MmUnmapLockedPages( MappedBuffer,
569 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
581 AFSInitializeLibraryDevice()
584 NTSTATUS ntStatus = STATUS_SUCCESS;
585 AFSDeviceExt *pDeviceExt = NULL;
590 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
593 // The PIOCtl file name
596 RtlInitUnicodeString( &AFSPIOCtlName,
597 AFS_PIOCTL_FILE_INTERFACE_NAME);
600 // And the global root share name
603 RtlInitUnicodeString( &AFSGlobalRootName,
604 AFS_GLOBAL_ROOT_SHARE_NAME);
612 AFSRemoveLibraryDevice()
615 NTSTATUS ntStatus = STATUS_SUCCESS;
626 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
630 UNREFERENCED_PARAMETER(DeviceObject);
631 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
633 AFSCompleteRequest( Irp,
640 AFSInitializeGlobalDirectoryEntries()
643 NTSTATUS ntStatus = STATUS_SUCCESS;
644 AFSDirectoryCB *pDirNode = NULL;
645 ULONG ulEntryLength = 0;
646 AFSObjectInfoCB *pObjectInfoCB = NULL;
647 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
654 // Initialize the global . entry
657 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
660 if( pObjectInfoCB == NULL)
663 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
664 AFS_TRACE_LEVEL_ERROR,
665 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
668 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
671 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
672 AFS_OBJECT_REFERENCE_GLOBAL);
674 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
675 AFS_TRACE_LEVEL_VERBOSE,
676 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
680 ntStatus = STATUS_SUCCESS;
682 ulEntryLength = sizeof( AFSDirectoryCB) +
685 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
689 if( pDirNode == NULL)
692 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
693 AFS_OBJECT_REFERENCE_GLOBAL);
695 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
696 AFS_TRACE_LEVEL_VERBOSE,
697 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
704 AFSDeleteObjectInfo( &pObjectInfoCB);
707 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
708 AFS_TRACE_LEVEL_ERROR,
709 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n"));
711 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
714 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
715 AFS_TRACE_LEVEL_VERBOSE,
716 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocated %p\n",
719 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
720 sizeof( AFSNonPagedDirectoryCB),
721 AFS_DIR_ENTRY_NP_TAG);
723 if( pNonPagedDirEntry == NULL)
726 AFSLibExFreePoolWithTag( pDirNode,
729 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
730 AFS_OBJECT_REFERENCE_GLOBAL);
732 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
733 AFS_TRACE_LEVEL_VERBOSE,
734 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
741 AFSDeleteObjectInfo( &pObjectInfoCB);
744 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
745 AFS_TRACE_LEVEL_ERROR,
746 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n"));
748 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
751 RtlZeroMemory( pDirNode,
754 RtlZeroMemory( pNonPagedDirEntry,
755 sizeof( AFSNonPagedDirectoryCB));
757 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
759 pDirNode->NonPaged = pNonPagedDirEntry;
761 pDirNode->ObjectInformation = pObjectInfoCB;
767 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
769 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
772 // Setup the names in the entry
775 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
777 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
779 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
781 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
784 // Populate the rest of the data
787 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
789 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
791 AFSGlobalDotDirEntry = pDirNode;
797 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
800 if( pObjectInfoCB == NULL)
803 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
804 AFS_TRACE_LEVEL_ERROR,
805 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
808 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
811 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
812 AFS_OBJECT_REFERENCE_GLOBAL);
814 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
815 AFS_TRACE_LEVEL_VERBOSE,
816 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
820 ntStatus = STATUS_SUCCESS;
822 ulEntryLength = sizeof( AFSDirectoryCB) +
823 ( 2 * sizeof( WCHAR));
825 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
829 if( pDirNode == NULL)
832 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
833 AFS_TRACE_LEVEL_ERROR,
834 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocation failure\n"));
836 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
837 AFS_OBJECT_REFERENCE_GLOBAL);
839 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
840 AFS_TRACE_LEVEL_VERBOSE,
841 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
848 AFSDeleteObjectInfo( &pObjectInfoCB);
851 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
854 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
855 AFS_TRACE_LEVEL_VERBOSE,
856 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocated %p\n",
859 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
860 sizeof( AFSNonPagedDirectoryCB),
861 AFS_DIR_ENTRY_NP_TAG);
863 if( pNonPagedDirEntry == NULL)
866 AFSLibExFreePoolWithTag( pDirNode,
869 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
870 AFS_OBJECT_REFERENCE_GLOBAL);
872 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
873 AFS_TRACE_LEVEL_VERBOSE,
874 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
881 AFSDeleteObjectInfo( &pObjectInfoCB);
884 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
887 RtlZeroMemory( pDirNode,
890 RtlZeroMemory( pNonPagedDirEntry,
891 sizeof( AFSNonPagedDirectoryCB));
893 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
895 pDirNode->NonPaged = pNonPagedDirEntry;
897 pDirNode->ObjectInformation = pObjectInfoCB;
903 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
905 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
908 // Setup the names in the entry
911 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
913 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
915 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
917 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
919 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
922 // Populate the rest of the data
925 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
927 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
929 AFSGlobalDotDotDirEntry = pDirNode;
933 if( !NT_SUCCESS( ntStatus))
936 if( AFSGlobalDotDirEntry != NULL)
939 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
940 AFS_OBJECT_REFERENCE_GLOBAL);
942 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
943 AFS_TRACE_LEVEL_VERBOSE,
944 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
945 AFSGlobalDotDirEntry->ObjectInformation,
951 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
954 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
956 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry->NonPaged,
957 AFS_DIR_ENTRY_NP_TAG);
959 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry,
962 AFSGlobalDotDirEntry = NULL;
965 if( AFSGlobalDotDotDirEntry != NULL)
968 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
969 AFS_OBJECT_REFERENCE_GLOBAL);
971 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
972 AFS_TRACE_LEVEL_VERBOSE,
973 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
974 AFSGlobalDotDotDirEntry->ObjectInformation,
980 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
983 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
985 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry->NonPaged,
986 AFS_DIR_ENTRY_NP_TAG);
988 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry,
991 AFSGlobalDotDotDirEntry = NULL;
1000 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
1001 IN PUNICODE_STRING FileName,
1002 IN PUNICODE_STRING TargetName,
1003 IN AFSDirEnumEntry *DirEnumEntry,
1007 AFSDirectoryCB *pDirNode = NULL;
1008 NTSTATUS ntStatus = STATUS_SUCCESS;
1009 ULONG ulEntryLength = 0;
1010 AFSObjectInfoCB *pObjectInfoCB = NULL;
1011 ULONGLONG ullIndex = 0;
1012 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
1018 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1019 AFS_TRACE_LEVEL_VERBOSE,
1020 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
1022 ParentObjectInfo->FileId.Cell,
1023 ParentObjectInfo->FileId.Volume,
1024 ParentObjectInfo->FileId.Vnode,
1025 ParentObjectInfo->FileId.Unique));
1028 // First thing is to locate/create our object information block
1032 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
1035 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
1037 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
1039 (AFSBTreeEntry **)&pObjectInfoCB);
1041 if( !NT_SUCCESS( ntStatus))
1045 // Allocate our object info cb
1048 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
1051 if( pObjectInfoCB == NULL)
1054 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1056 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1059 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1060 AFS_TRACE_LEVEL_VERBOSE,
1061 "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
1067 // If we allocated the object information cb then set the information
1070 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1072 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1074 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1076 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1078 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1079 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1082 pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1085 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
1088 if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1091 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1096 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1101 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1102 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1106 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1107 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1108 pObjectInfoCB->TargetFileId.Unique == 0 &&
1109 (TargetName == NULL || TargetName->Length == 0))
1113 // This will ensure we perform a validation on the node
1116 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1119 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1122 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1125 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1128 if ( BooleanFlagOn( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY))
1131 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1133 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1135 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1137 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1139 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1141 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1143 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1145 pObjectInfoCB->Links = DirEnumEntry->Links;
1147 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1149 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1151 ClearFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1155 // This reference count is either stored into the return DirectoryCB
1156 // or released before function exit.
1159 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
1160 AFS_OBJECT_REFERENCE_DIRENTRY);
1162 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1163 AFS_TRACE_LEVEL_VERBOSE,
1164 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
1168 KeQueryTickCount( &pObjectInfoCB->LastAccessCount);
1170 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1172 ntStatus = STATUS_SUCCESS;
1174 ulEntryLength = sizeof( AFSDirectoryCB) +
1177 if( TargetName != NULL)
1180 ulEntryLength += TargetName->Length;
1183 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1187 if( pDirNode == NULL)
1190 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1193 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1194 AFS_TRACE_LEVEL_VERBOSE,
1195 "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
1198 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1199 sizeof( AFSNonPagedDirectoryCB),
1200 AFS_DIR_ENTRY_NP_TAG);
1202 if( pNonPagedDirEntry == NULL)
1205 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1208 RtlZeroMemory( pDirNode,
1211 RtlZeroMemory( pNonPagedDirEntry,
1212 sizeof( AFSNonPagedDirectoryCB));
1214 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1216 pDirNode->NonPaged = pNonPagedDirEntry;
1218 pDirNode->ObjectInformation = pObjectInfoCB;
1221 // Set valid entry and NOT_IN_PARENT flag
1224 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1226 pDirNode->FileIndex = FileIndex;
1229 // Setup the names in the entry
1232 if( FileName->Length > 0)
1235 pDirNode->NameInformation.FileName.Length = FileName->Length;
1237 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1239 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1241 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1243 pDirNode->NameInformation.FileName.Length);
1246 // Create a CRC for the file
1249 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1252 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1256 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1257 AFS_TRACE_LEVEL_VERBOSE,
1258 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1261 ParentObjectInfo->FileId.Cell,
1262 ParentObjectInfo->FileId.Volume,
1263 ParentObjectInfo->FileId.Vnode,
1264 ParentObjectInfo->FileId.Unique));
1266 if( TargetName != NULL &&
1267 TargetName->Length > 0)
1270 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1272 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1274 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1275 sizeof( AFSDirectoryCB) +
1276 pDirNode->NameInformation.FileName.Length);
1278 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1280 pDirNode->NameInformation.TargetName.Length);
1286 if( !NT_SUCCESS( ntStatus))
1289 if( pNonPagedDirEntry != NULL)
1292 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1294 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1297 if( pDirNode != NULL)
1300 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1301 AFS_TRACE_LEVEL_VERBOSE,
1302 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1305 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1311 // Dereference our object info block if we have one
1314 if( pObjectInfoCB != NULL)
1317 AFSAcquireShared( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
1320 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1321 AFS_OBJECT_REFERENCE_DIRENTRY);
1323 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1324 AFS_TRACE_LEVEL_VERBOSE,
1325 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1329 AFSReleaseResource( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
1338 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1339 IN BOOLEAN DirectoryEntry)
1342 BOOLEAN bReturn = TRUE;
1343 ACCESS_MASK stAccessMask = 0;
1346 // Get rid of anything we don't know about
1349 DesiredAccess = (DesiredAccess &
1355 ACCESS_SYSTEM_SECURITY |
1359 FILE_READ_ATTRIBUTES |
1360 FILE_WRITE_ATTRIBUTES |
1361 FILE_LIST_DIRECTORY |
1367 // Our 'read only' access mask. These are the accesses we will
1368 // allow for a read only file
1371 stAccessMask = DELETE |
1376 ACCESS_SYSTEM_SECURITY |
1380 FILE_READ_ATTRIBUTES |
1381 FILE_WRITE_ATTRIBUTES |
1383 FILE_LIST_DIRECTORY |
1387 // For a directory, add in the directory specific accesses
1393 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1398 if( FlagOn( DesiredAccess, ~stAccessMask))
1402 // A write access is set ...
1412 AFSEvaluateNode( IN GUID *AuthGroup,
1413 IN AFSDirectoryCB *DirEntry)
1416 NTSTATUS ntStatus = STATUS_SUCCESS;
1417 AFSDirEnumEntry *pDirEntry = NULL;
1418 UNICODE_STRING uniTargetName;
1423 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1428 if( !NT_SUCCESS( ntStatus))
1431 try_return( ntStatus);
1434 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1436 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1438 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1440 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1442 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1444 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1446 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1448 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1450 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1452 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1454 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1456 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1457 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1460 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1463 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1466 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1469 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1474 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1478 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1480 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1483 // If we have a target name then see if it needs updating ...
1486 if( pDirEntry->TargetNameLength > 0)
1490 // Update the target name information if needed
1493 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1495 uniTargetName.MaximumLength = uniTargetName.Length;
1497 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1499 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1502 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1503 RtlCompareUnicodeString( &uniTargetName,
1504 &DirEntry->NameInformation.TargetName,
1509 // Update the target name
1512 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1514 uniTargetName.Buffer,
1515 uniTargetName.Length);
1517 if( !NT_SUCCESS( ntStatus))
1520 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1522 try_return( ntStatus);
1526 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1531 if( pDirEntry != NULL)
1534 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1542 AFSValidateSymLink( IN GUID *AuthGroup,
1543 IN AFSDirectoryCB *DirEntry)
1546 NTSTATUS ntStatus = STATUS_SUCCESS;
1547 AFSDirEnumEntry *pDirEntry = NULL;
1548 UNICODE_STRING uniTargetName;
1553 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1558 if( !NT_SUCCESS( ntStatus))
1561 try_return( ntStatus);
1564 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1565 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1568 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1569 AFS_TRACE_LEVEL_VERBOSE_2,
1570 "AFSValidateSymLink Invalid type Status %08lX\n",
1571 STATUS_OBJECT_NAME_NOT_FOUND));
1573 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1576 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1578 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1580 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1583 // Update the target name information if needed
1586 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1588 uniTargetName.MaximumLength = uniTargetName.Length;
1590 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1592 if( uniTargetName.Length > 0)
1595 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1598 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1599 RtlCompareUnicodeString( &uniTargetName,
1600 &DirEntry->NameInformation.TargetName,
1605 // Update the target name
1608 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1610 uniTargetName.Buffer,
1611 uniTargetName.Length);
1613 if( !NT_SUCCESS( ntStatus))
1616 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1618 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1622 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1626 // If the FileType is the same then nothing to do since it IS
1630 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1633 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1635 try_return( ntStatus = STATUS_SUCCESS);
1638 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1640 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1642 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1644 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1646 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1648 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1650 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1652 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1654 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1655 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1658 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1661 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1664 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1667 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1672 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1676 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1678 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1682 if( pDirEntry != NULL)
1685 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1693 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1697 NTSTATUS ntStatus = STATUS_SUCCESS;
1698 IO_STATUS_BLOCK stIoStatus;
1700 AFSObjectInfoCB * pParentObjectInfo = NULL;
1702 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1703 AFS_TRACE_LEVEL_VERBOSE,
1704 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1705 (*ppObjectInfo)->FileType,
1706 (*ppObjectInfo)->FileId.Cell,
1707 (*ppObjectInfo)->FileId.Volume,
1708 (*ppObjectInfo)->FileId.Vnode,
1709 (*ppObjectInfo)->FileId.Unique,
1712 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1715 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1716 &(*ppObjectInfo)->ParentFileId,
1720 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1721 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1722 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1725 // We only act on the mount point itself, not the target. If the
1726 // node has been deleted then mark it as such otherwise indicate
1727 // it requires verification
1730 if( Reason == AFS_INVALIDATE_DELETED)
1732 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1737 if( Reason == AFS_INVALIDATE_FLUSHED)
1740 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1742 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1745 (*ppObjectInfo)->Expiration.QuadPart = 0;
1747 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1749 (*ppObjectInfo)->TargetFileId.Unique = 0;
1751 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1752 AFS_TRACE_LEVEL_VERBOSE,
1753 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1754 (*ppObjectInfo)->FileId.Cell,
1755 (*ppObjectInfo)->FileId.Volume,
1756 (*ppObjectInfo)->FileId.Vnode,
1757 (*ppObjectInfo)->FileId.Unique));
1759 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1762 if ( pParentObjectInfo != NULL)
1765 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1767 if( Reason == AFS_INVALIDATE_CREDS)
1769 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1772 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1773 Reason == AFS_INVALIDATE_FLUSHED)
1775 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1779 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1782 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1785 FILE_ACTION_MODIFIED);
1788 try_return( ntStatus);
1792 // Depending on the reason for invalidation then perform work on the node
1798 case AFS_INVALIDATE_DELETED:
1802 // Mark this node as invalid
1805 (*ppObjectInfo)->Links = 0;
1807 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1809 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1810 AFS_TRACE_LEVEL_VERBOSE,
1811 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1812 (*ppObjectInfo)->FileId.Cell,
1813 (*ppObjectInfo)->FileId.Volume,
1814 (*ppObjectInfo)->FileId.Vnode,
1815 (*ppObjectInfo)->FileId.Unique));
1817 if( pParentObjectInfo != NULL)
1820 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1821 AFS_TRACE_LEVEL_VERBOSE,
1822 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1823 pParentObjectInfo->FileId.Cell,
1824 pParentObjectInfo->FileId.Volume,
1825 pParentObjectInfo->FileId.Vnode,
1826 pParentObjectInfo->FileId.Unique));
1828 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1830 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1832 pParentObjectInfo->Expiration.QuadPart = 0;
1834 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1836 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1840 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1843 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1846 FILE_ACTION_REMOVED);
1849 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1852 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1858 case AFS_INVALIDATE_FLUSHED:
1861 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1862 (*ppObjectInfo)->Fcb != NULL)
1865 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1866 AFS_TRACE_LEVEL_VERBOSE,
1867 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1868 (*ppObjectInfo)->FileId.Cell,
1869 (*ppObjectInfo)->FileId.Volume,
1870 (*ppObjectInfo)->FileId.Vnode,
1871 (*ppObjectInfo)->FileId.Unique));
1873 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1874 AFS_TRACE_LEVEL_VERBOSE,
1875 "AFSInvalidateObject Flush/purge Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
1876 &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1877 PsGetCurrentThread()));
1879 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1885 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1890 if( !NT_SUCCESS( stIoStatus.Status))
1893 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1894 AFS_TRACE_LEVEL_ERROR,
1895 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1896 (*ppObjectInfo)->FileId.Cell,
1897 (*ppObjectInfo)->FileId.Volume,
1898 (*ppObjectInfo)->FileId.Vnode,
1899 (*ppObjectInfo)->FileId.Unique,
1901 stIoStatus.Information));
1903 ntStatus = stIoStatus.Status;
1907 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1910 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1916 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1917 AFS_TRACE_LEVEL_WARNING,
1918 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1919 (*ppObjectInfo)->FileId.Cell,
1920 (*ppObjectInfo)->FileId.Volume,
1921 (*ppObjectInfo)->FileId.Vnode,
1922 (*ppObjectInfo)->FileId.Unique));
1924 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1928 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
1931 ntStatus = GetExceptionCode();
1935 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1936 (*ppObjectInfo)->FileId.Cell,
1937 (*ppObjectInfo)->FileId.Volume,
1938 (*ppObjectInfo)->FileId.Vnode,
1939 (*ppObjectInfo)->FileId.Unique,
1942 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1945 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1946 AFS_TRACE_LEVEL_VERBOSE,
1947 "AFSInvalidateObject Flush/purge Releasing Fcb SectionObject lock %p EXCL %08lX\n",
1948 &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1949 PsGetCurrentThread()));
1951 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1954 // Clear out the extents
1955 // Get rid of them (note this involves waiting
1956 // for any writes or reads to the cache to complete)
1959 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1963 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1966 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1969 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1970 AFS_TRACE_LEVEL_VERBOSE,
1971 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1972 (*ppObjectInfo)->FileId.Cell,
1973 (*ppObjectInfo)->FileId.Volume,
1974 (*ppObjectInfo)->FileId.Vnode,
1975 (*ppObjectInfo)->FileId.Unique));
1977 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1980 // Fall through to the default processing
1986 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1988 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1992 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1995 if( Reason == AFS_INVALIDATE_CREDS)
1997 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2000 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2002 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2006 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2009 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
2012 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
2015 FILE_ACTION_MODIFIED);
2017 else if ( pParentObjectInfo != NULL)
2020 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2023 FILE_ACTION_MODIFIED);
2027 // Indicate this node requires re-evaluation for the remaining reasons
2030 (*ppObjectInfo)->Expiration.QuadPart = 0;
2032 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2033 AFS_TRACE_LEVEL_VERBOSE,
2034 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2035 (*ppObjectInfo)->FileId.Cell,
2036 (*ppObjectInfo)->FileId.Volume,
2037 (*ppObjectInfo)->FileId.Vnode,
2038 (*ppObjectInfo)->FileId.Unique));
2040 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
2042 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2043 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
2044 ( Reason == AFS_INVALIDATE_CALLBACK ||
2045 Reason == AFS_INVALIDATE_EXPIRED))
2047 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
2048 AFS_INVALIDATE_DATA_VERSION)))
2051 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
2061 if ( pParentObjectInfo != NULL)
2064 AFSReleaseObjectInfo( &pParentObjectInfo);
2071 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
2074 NTSTATUS ntStatus = STATUS_SUCCESS;
2075 AFSVolumeCB *pVolumeCB = NULL;
2076 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2077 ULONGLONG ullIndex = 0;
2078 AFSObjectInfoCB *pObjectInfo = NULL;
2084 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2085 AFS_TRACE_LEVEL_VERBOSE,
2086 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
2087 InvalidateCB->FileID.Cell,
2088 InvalidateCB->FileID.Volume,
2089 InvalidateCB->FileID.Vnode,
2090 InvalidateCB->FileID.Unique,
2091 InvalidateCB->FileType,
2092 InvalidateCB->WholeVolume,
2093 InvalidateCB->Reason));
2096 // Need to locate the Fcb for the directory to purge
2099 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2100 AFS_TRACE_LEVEL_VERBOSE,
2101 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2102 &pDevExt->Specific.RDR.VolumeTreeLock,
2103 PsGetCurrentThread()));
2106 // Starve any exclusive waiters on this paticular call
2109 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2112 // Locate the volume node
2115 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2117 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2119 (AFSBTreeEntry **)&pVolumeCB);
2121 if( pVolumeCB != NULL)
2124 lCount = AFSVolumeIncrement( pVolumeCB,
2125 AFS_VOLUME_REFERENCE_INVALIDATE);
2127 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2128 AFS_TRACE_LEVEL_VERBOSE,
2129 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2134 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2136 if( !NT_SUCCESS( ntStatus) ||
2140 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2141 AFS_TRACE_LEVEL_WARNING,
2142 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2143 InvalidateCB->FileID.Cell,
2144 InvalidateCB->FileID.Volume,
2145 InvalidateCB->FileID.Vnode,
2146 InvalidateCB->FileID.Unique,
2149 try_return( ntStatus = STATUS_SUCCESS);
2153 // If this is a whole volume invalidation then go do it now
2156 if( InvalidateCB->WholeVolume)
2159 ntStatus = AFSInvalidateVolume( pVolumeCB,
2160 InvalidateCB->Reason);
2162 try_return( ntStatus);
2165 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
2168 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2171 pObjectInfo = &pVolumeCB->ObjectInformation;
2176 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2178 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2180 (AFSBTreeEntry **)&pObjectInfo);
2183 if( pObjectInfo != NULL)
2187 // Reference the node so it won't be torn down
2190 lCount = AFSObjectInfoIncrement( pObjectInfo,
2191 AFS_OBJECT_REFERENCE_INVALIDATION);
2193 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2194 AFS_TRACE_LEVEL_VERBOSE,
2195 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2200 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2202 if( !NT_SUCCESS( ntStatus) ||
2203 pObjectInfo == NULL)
2206 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2207 AFS_TRACE_LEVEL_VERBOSE,
2208 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2209 InvalidateCB->FileID.Cell,
2210 InvalidateCB->FileID.Volume,
2211 InvalidateCB->FileID.Vnode,
2212 InvalidateCB->FileID.Unique,
2215 try_return( ntStatus = STATUS_SUCCESS);
2218 AFSInvalidateObject( &pObjectInfo,
2219 InvalidateCB->Reason);
2223 if( pObjectInfo != NULL)
2226 lCount = AFSObjectInfoDecrement( pObjectInfo,
2227 AFS_OBJECT_REFERENCE_INVALIDATION);
2229 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2230 AFS_TRACE_LEVEL_VERBOSE,
2231 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2236 if ( pVolumeCB != NULL)
2239 lCount = AFSVolumeDecrement( pVolumeCB,
2240 AFS_VOLUME_REFERENCE_INVALIDATE);
2242 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2243 AFS_TRACE_LEVEL_VERBOSE,
2244 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2254 AFSIsChildOfParent( IN AFSFcb *Dcb,
2258 BOOLEAN bIsChild = FALSE;
2259 AFSFcb *pCurrentFcb = Fcb;
2260 AFSObjectInfoCB * pParentObjectInfo = NULL;
2262 while( pCurrentFcb != NULL)
2265 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2266 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2274 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2275 &pCurrentFcb->ObjectInformation->ParentFileId,
2278 if ( pParentObjectInfo != NULL)
2281 pCurrentFcb = pParentObjectInfo->Fcb;
2283 AFSReleaseObjectInfo( &pParentObjectInfo);
2297 AFSCreateHighIndex( IN AFSFileID *FileID)
2300 ULONGLONG ullIndex = 0;
2302 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2309 AFSCreateLowIndex( IN AFSFileID *FileID)
2312 ULONGLONG ullIndex = 0;
2314 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2320 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2321 IN ACCESS_MASK GrantedAccess,
2322 IN BOOLEAN DirectoryEntry)
2325 BOOLEAN bAccessGranted = TRUE;
2328 // Check if we are asking for read/write and granted only read only
2329 // NOTE: There will be more checks here
2332 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2334 AFSCheckForReadOnlyAccess( GrantedAccess,
2338 bAccessGranted = FALSE;
2341 return bAccessGranted;
2345 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2348 NTSTATUS ntStatus = STATUS_SUCCESS;
2349 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2355 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2357 if( AFSGlobalRoot == NULL)
2364 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2367 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2374 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2381 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2382 IN UNICODE_STRING *SubstituteName,
2383 IN ULONG StringIndex)
2386 NTSTATUS ntStatus = STATUS_SUCCESS;
2387 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2388 AFSSysNameCB *pSysName = NULL;
2389 ERESOURCE *pSysNameLock = NULL;
2392 UNICODE_STRING uniSysName;
2399 if( IoIs32bitProcess( NULL))
2402 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2404 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2409 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2411 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2415 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2417 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2421 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2422 AFS_TRACE_LEVEL_VERBOSE,
2423 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2425 PsGetCurrentThread()));
2427 AFSAcquireShared( pSysNameLock,
2431 // Find where we are in the list
2434 while( pSysName != NULL &&
2435 ulIndex < StringIndex)
2438 pSysName = pSysName->fLink;
2443 if( pSysName == NULL)
2446 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2447 AFS_TRACE_LEVEL_VERBOSE_2,
2448 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2450 STATUS_OBJECT_NAME_NOT_FOUND));
2452 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2455 RtlInitUnicodeString( &uniSysName,
2458 // If it is a full component of @SYS then just substitue the
2462 if( RtlCompareUnicodeString( &uniSysName,
2467 SubstituteName->Length = pSysName->SysName.Length;
2468 SubstituteName->MaximumLength = SubstituteName->Length;
2470 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2471 SubstituteName->Length,
2472 AFS_SUBST_BUFFER_TAG);
2474 if( SubstituteName->Buffer == NULL)
2477 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2480 RtlCopyMemory( SubstituteName->Buffer,
2481 pSysName->SysName.Buffer,
2482 pSysName->SysName.Length);
2489 while( ComponentName->Buffer[ usIndex] != L'@')
2495 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2496 SubstituteName->MaximumLength = SubstituteName->Length;
2498 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2499 SubstituteName->Length,
2500 AFS_SUBST_BUFFER_TAG);
2502 if( SubstituteName->Buffer == NULL)
2505 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2508 RtlCopyMemory( SubstituteName->Buffer,
2509 ComponentName->Buffer,
2510 usIndex * sizeof( WCHAR));
2512 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2513 pSysName->SysName.Buffer,
2514 pSysName->SysName.Length);
2519 AFSReleaseResource( pSysNameLock);
2526 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2527 IN OUT UNICODE_STRING *ComponentName,
2528 IN UNICODE_STRING *SubstituteName,
2529 IN OUT UNICODE_STRING *RemainingPath,
2530 IN BOOLEAN FreePathName)
2533 NTSTATUS ntStatus = STATUS_SUCCESS;
2534 UNICODE_STRING uniPathName;
2535 USHORT usPrefixNameLen = 0;
2536 SHORT sNameLenDelta = 0;
2542 // If the passed in name can handle the additional length
2543 // then just moves things around
2546 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2548 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2550 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2553 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2556 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2557 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2558 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2561 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2562 SubstituteName->Buffer,
2563 SubstituteName->Length);
2565 FullPathName->Length += sNameLenDelta;
2567 ComponentName->Length += sNameLenDelta;
2569 ComponentName->MaximumLength = ComponentName->Length;
2571 if ( RemainingPath->Buffer)
2574 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2577 try_return( ntStatus);
2581 // Need to re-allocate the buffer
2584 uniPathName.Length = FullPathName->Length -
2585 ComponentName->Length +
2586 SubstituteName->Length;
2588 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2590 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2591 uniPathName.MaximumLength,
2592 AFS_NAME_BUFFER_FOUR_TAG);
2594 if( uniPathName.Buffer == NULL)
2597 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2600 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2602 usPrefixNameLen *= sizeof( WCHAR);
2604 RtlZeroMemory( uniPathName.Buffer,
2605 uniPathName.MaximumLength);
2607 RtlCopyMemory( uniPathName.Buffer,
2608 FullPathName->Buffer,
2611 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2612 SubstituteName->Buffer,
2613 SubstituteName->Length);
2615 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2618 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2619 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2620 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2623 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2625 ComponentName->Length += sNameLenDelta;
2627 ComponentName->MaximumLength = ComponentName->Length;
2629 if ( RemainingPath->Buffer)
2632 RemainingPath->Buffer = uniPathName.Buffer
2633 + (RemainingPath->Buffer - FullPathName->Buffer)
2634 + sNameLenDelta/sizeof( WCHAR);
2639 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2642 *FullPathName = uniPathName;
2653 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2657 NTSTATUS ntStatus = STATUS_SUCCESS;
2658 AFSObjectInfoCB *pCurrentObject = NULL;
2659 AFSObjectInfoCB *pNextObject = NULL;
2665 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2666 AFS_TRACE_LEVEL_VERBOSE,
2667 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2668 VolumeCB->ObjectInformation.FileId.Cell,
2669 VolumeCB->ObjectInformation.FileId.Volume,
2670 VolumeCB->ObjectInformation.FileId.Vnode,
2671 VolumeCB->ObjectInformation.FileId.Unique,
2675 // Depending on the reason for invalidation then perform work on the node
2681 case AFS_INVALIDATE_DELETED:
2685 // Mark this volume as invalid
2688 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2690 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2696 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2700 // Invalidate the volume root directory
2703 pCurrentObject = &VolumeCB->ObjectInformation;
2705 if ( pCurrentObject )
2708 lCount = AFSObjectInfoIncrement( pCurrentObject,
2709 AFS_OBJECT_REFERENCE_INVALIDATION);
2711 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2712 AFS_TRACE_LEVEL_VERBOSE,
2713 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2717 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2719 AFSInvalidateObject( &pCurrentObject,
2722 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2725 if ( pCurrentObject)
2728 lCount = AFSObjectInfoDecrement( pCurrentObject,
2729 AFS_OBJECT_REFERENCE_INVALIDATION);
2731 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2732 AFS_TRACE_LEVEL_VERBOSE,
2733 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2740 // Apply invalidation to all other volume objects
2743 pCurrentObject = VolumeCB->ObjectInfoListHead;
2745 if ( pCurrentObject)
2749 // Reference the node so it won't be torn down
2752 lCount = AFSObjectInfoIncrement( pCurrentObject,
2753 AFS_OBJECT_REFERENCE_INVALIDATION);
2755 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2756 AFS_TRACE_LEVEL_VERBOSE,
2757 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2762 while( pCurrentObject != NULL)
2765 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2771 // Reference the node so it won't be torn down
2774 lCount = AFSObjectInfoIncrement( pNextObject,
2775 AFS_OBJECT_REFERENCE_INVALIDATION);
2777 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2778 AFS_TRACE_LEVEL_VERBOSE,
2779 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2784 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2786 AFSInvalidateObject( &pCurrentObject,
2789 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2792 if ( pCurrentObject )
2795 lCount = AFSObjectInfoDecrement( pCurrentObject,
2796 AFS_OBJECT_REFERENCE_INVALIDATION);
2798 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2799 AFS_TRACE_LEVEL_VERBOSE,
2800 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2805 pCurrentObject = pNextObject;
2808 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2815 AFSInvalidateAllVolumes( VOID)
2817 AFSVolumeCB *pVolumeCB = NULL;
2818 AFSVolumeCB *pNextVolumeCB = NULL;
2819 AFSDeviceExt *pRDRDeviceExt = NULL;
2822 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2824 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2825 AFS_TRACE_LEVEL_VERBOSE,
2826 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2827 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2828 PsGetCurrentThread()));
2830 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2833 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2838 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2839 AFS_TRACE_LEVEL_VERBOSE,
2840 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2841 pVolumeCB->ObjectInfoTree.TreeLock,
2842 PsGetCurrentThread()));
2844 lCount = AFSVolumeIncrement( pVolumeCB,
2845 AFS_VOLUME_REFERENCE_INVALIDATE);
2847 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2848 AFS_TRACE_LEVEL_VERBOSE,
2849 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2854 while( pVolumeCB != NULL)
2857 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2862 lCount = AFSVolumeIncrement( pNextVolumeCB,
2863 AFS_VOLUME_REFERENCE_INVALIDATE);
2865 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2866 AFS_TRACE_LEVEL_VERBOSE,
2867 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2872 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2874 // do I need to hold the volume lock here?
2876 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2878 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2881 lCount = AFSVolumeDecrement( pVolumeCB,
2882 AFS_VOLUME_REFERENCE_INVALIDATE);
2884 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2885 AFS_TRACE_LEVEL_VERBOSE,
2886 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2890 pVolumeCB = pNextVolumeCB;
2893 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2897 AFSVerifyEntry( IN GUID *AuthGroup,
2898 IN AFSDirectoryCB *DirEntry,
2899 IN BOOLEAN bFollowMountPoint)
2902 NTSTATUS ntStatus = STATUS_SUCCESS;
2903 AFSDirEnumEntry *pDirEnumEntry = NULL;
2904 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2905 IO_STATUS_BLOCK stIoStatus;
2910 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2911 AFS_TRACE_LEVEL_VERBOSE_2,
2912 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2913 &DirEntry->NameInformation.FileName,
2914 pObjectInfo->FileId.Cell,
2915 pObjectInfo->FileId.Volume,
2916 pObjectInfo->FileId.Vnode,
2917 pObjectInfo->FileId.Unique));
2919 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2921 bFollowMountPoint ? FALSE : TRUE,
2924 if( !NT_SUCCESS( ntStatus))
2927 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2928 AFS_TRACE_LEVEL_ERROR,
2929 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2930 &DirEntry->NameInformation.FileName,
2931 pObjectInfo->FileId.Cell,
2932 pObjectInfo->FileId.Volume,
2933 pObjectInfo->FileId.Vnode,
2934 pObjectInfo->FileId.Unique,
2937 try_return( ntStatus);
2941 // Check the data version of the file
2944 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2945 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2948 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2949 AFS_TRACE_LEVEL_VERBOSE,
2950 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2951 pObjectInfo->DataVersion.QuadPart,
2952 &DirEntry->NameInformation.FileName,
2953 pObjectInfo->FileId.Cell,
2954 pObjectInfo->FileId.Volume,
2955 pObjectInfo->FileId.Vnode,
2956 pObjectInfo->FileId.Unique));
2959 // We are ok, just get out
2962 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2964 try_return( ntStatus = STATUS_SUCCESS);
2968 // New data version so we will need to process the node based on the type
2971 switch( pDirEnumEntry->FileType)
2974 case AFS_FILE_TYPE_MOUNTPOINT:
2978 // For a mount point we need to ensure the target is the same
2981 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2982 &pDirEnumEntry->TargetFileId))
2988 // Update the metadata for the entry
2991 ntStatus = AFSUpdateMetaData( DirEntry,
2994 if( NT_SUCCESS( ntStatus))
2997 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3003 case AFS_FILE_TYPE_SYMLINK:
3007 // Update the metadata for the entry
3010 ntStatus = AFSUpdateMetaData( DirEntry,
3013 if( NT_SUCCESS( ntStatus))
3016 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3022 case AFS_FILE_TYPE_FILE:
3024 FILE_OBJECT * pCCFileObject = NULL;
3026 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3029 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3030 AFS_TRACE_LEVEL_VERBOSE,
3031 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3032 &DirEntry->NameInformation.FileName,
3033 pObjectInfo->FileId.Cell,
3034 pObjectInfo->FileId.Volume,
3035 pObjectInfo->FileId.Vnode,
3036 pObjectInfo->FileId.Unique));
3038 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3041 if( pObjectInfo->Fcb != NULL)
3044 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3045 AFS_TRACE_LEVEL_VERBOSE,
3046 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3047 &DirEntry->NameInformation.FileName,
3048 pObjectInfo->FileId.Cell,
3049 pObjectInfo->FileId.Volume,
3050 pObjectInfo->FileId.Vnode,
3051 pObjectInfo->FileId.Unique));
3053 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3054 AFS_TRACE_LEVEL_VERBOSE,
3055 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3056 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3057 PsGetCurrentThread()));
3059 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3065 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3070 if( !NT_SUCCESS( stIoStatus.Status))
3073 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3074 AFS_TRACE_LEVEL_ERROR,
3075 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3076 &DirEntry->NameInformation.FileName,
3077 pObjectInfo->FileId.Cell,
3078 pObjectInfo->FileId.Volume,
3079 pObjectInfo->FileId.Vnode,
3080 pObjectInfo->FileId.Unique,
3082 stIoStatus.Information));
3084 ntStatus = stIoStatus.Status;
3087 if ( pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3090 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3096 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3097 AFS_TRACE_LEVEL_WARNING,
3098 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3099 &DirEntry->NameInformation.FileName,
3100 pObjectInfo->FileId.Cell,
3101 pObjectInfo->FileId.Volume,
3102 pObjectInfo->FileId.Vnode,
3103 pObjectInfo->FileId.Unique));
3105 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3109 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3111 ntStatus = GetExceptionCode();
3115 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3116 &DirEntry->NameInformation.FileName,
3117 pObjectInfo->FileId.Cell,
3118 pObjectInfo->FileId.Volume,
3119 pObjectInfo->FileId.Vnode,
3120 pObjectInfo->FileId.Unique,
3123 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3126 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3127 AFS_TRACE_LEVEL_VERBOSE,
3128 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3129 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3130 PsGetCurrentThread()));
3132 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3134 AFSFlushExtents( pObjectInfo->Fcb,
3138 // Acquire the Fcb to purge the cache
3141 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3142 AFS_TRACE_LEVEL_VERBOSE,
3143 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3144 &pObjectInfo->Fcb->NPFcb->Resource,
3145 PsGetCurrentThread()));
3147 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3151 // Update the metadata for the entry
3154 ntStatus = AFSUpdateMetaData( DirEntry,
3157 if( !NT_SUCCESS( ntStatus))
3160 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3161 AFS_TRACE_LEVEL_ERROR,
3162 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3163 &DirEntry->NameInformation.FileName,
3164 pObjectInfo->FileId.Cell,
3165 pObjectInfo->FileId.Volume,
3166 pObjectInfo->FileId.Vnode,
3167 pObjectInfo->FileId.Unique,
3174 // Update file sizes
3177 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3178 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3179 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3181 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3182 AFS_TRACE_LEVEL_VERBOSE,
3183 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3184 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3185 PsGetCurrentThread()));
3187 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3193 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3195 if ( pCCFileObject != NULL)
3197 CcSetFileSizes( pCCFileObject,
3198 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3201 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3204 ntStatus = GetExceptionCode();
3208 "EXCEPTION - AFSVerifyEntry CcSetFileSized failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3209 pObjectInfo->FileId.Cell,
3210 pObjectInfo->FileId.Volume,
3211 pObjectInfo->FileId.Vnode,
3212 pObjectInfo->FileId.Unique,
3216 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3217 AFS_TRACE_LEVEL_VERBOSE,
3218 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3219 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3220 PsGetCurrentThread()));
3222 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3225 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3226 AFS_TRACE_LEVEL_VERBOSE,
3227 "AFSVerifyEntry Releasing Fcb lock %p EXCL %08lX\n",
3228 &pObjectInfo->Fcb->NPFcb->Resource,
3229 PsGetCurrentThread()));
3231 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3237 // Update the metadata for the entry
3240 ntStatus = AFSUpdateMetaData( DirEntry,
3243 if( !NT_SUCCESS( ntStatus))
3246 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3247 AFS_TRACE_LEVEL_ERROR,
3248 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3249 &DirEntry->NameInformation.FileName,
3250 pObjectInfo->FileId.Cell,
3251 pObjectInfo->FileId.Volume,
3252 pObjectInfo->FileId.Vnode,
3253 pObjectInfo->FileId.Unique,
3259 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3260 AFS_TRACE_LEVEL_WARNING,
3261 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3262 &DirEntry->NameInformation.FileName,
3263 pObjectInfo->FileId.Cell,
3264 pObjectInfo->FileId.Volume,
3265 pObjectInfo->FileId.Vnode,
3266 pObjectInfo->FileId.Unique));
3270 if ( NT_SUCCESS( ntStatus))
3273 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3278 case AFS_FILE_TYPE_DIRECTORY:
3282 // For a directory or root entry flush the content of
3283 // the directory enumeration.
3286 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3289 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3290 AFS_TRACE_LEVEL_VERBOSE_2,
3291 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3292 &DirEntry->NameInformation.FileName,
3293 pObjectInfo->FileId.Cell,
3294 pObjectInfo->FileId.Volume,
3295 pObjectInfo->FileId.Vnode,
3296 pObjectInfo->FileId.Unique));
3298 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3301 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3304 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3306 if ( !NT_SUCCESS( ntStatus))
3309 try_return( ntStatus);
3314 // Update the metadata for the entry
3317 ntStatus = AFSUpdateMetaData( DirEntry,
3320 if( NT_SUCCESS( ntStatus))
3323 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3329 case AFS_FILE_TYPE_DFSLINK:
3332 UNICODE_STRING uniTargetName;
3335 // For a DFS link need to check the target name has not changed
3338 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3340 uniTargetName.MaximumLength = uniTargetName.Length;
3342 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3344 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3347 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3348 RtlCompareUnicodeString( &uniTargetName,
3349 &DirEntry->NameInformation.TargetName,
3354 // Update the target name
3357 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3359 uniTargetName.Buffer,
3360 uniTargetName.Length);
3362 if( !NT_SUCCESS( ntStatus))
3365 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3371 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3374 // Update the metadata for the entry
3377 ntStatus = AFSUpdateMetaData( DirEntry,
3380 if( NT_SUCCESS( ntStatus))
3383 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3391 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3392 AFS_TRACE_LEVEL_WARNING,
3393 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3394 pObjectInfo->FileType,
3395 &DirEntry->NameInformation.FileName,
3396 pObjectInfo->FileId.Cell,
3397 pObjectInfo->FileId.Volume,
3398 pObjectInfo->FileId.Vnode,
3399 pObjectInfo->FileId.Unique));
3406 if( pDirEnumEntry != NULL)
3409 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3417 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3420 NTSTATUS ntStatus = STATUS_SUCCESS;
3421 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3422 ULONGLONG ullIndex = 0;
3423 AFSVolumeCB *pVolumeCB = NULL;
3429 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3430 AFS_TRACE_LEVEL_VERBOSE,
3431 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3432 VolumeStatus->Online,
3433 VolumeStatus->FileID.Cell,
3434 VolumeStatus->FileID.Volume));
3437 // Need to locate the Fcb for the directory to purge
3440 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3441 AFS_TRACE_LEVEL_VERBOSE,
3442 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3443 &pDevExt->Specific.RDR.VolumeTreeLock,
3444 PsGetCurrentThread()));
3446 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3449 // Locate the volume node
3452 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3454 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3456 (AFSBTreeEntry **)&pVolumeCB);
3458 if( pVolumeCB != NULL)
3461 lCount = AFSVolumeIncrement( pVolumeCB,
3462 AFS_VOLUME_REFERENCE_INVALIDATE);
3464 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3465 AFS_TRACE_LEVEL_VERBOSE,
3466 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3470 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3473 // Set the volume state accordingly
3476 if( VolumeStatus->Online)
3479 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3484 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3493 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3496 NTSTATUS ntStatus = STATUS_SUCCESS;
3501 if( AFSGlobalRoot == NULL)
3504 try_return( ntStatus);
3507 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3511 // Set the network state according to the information
3514 if( NetworkStatus->Online)
3517 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3522 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3525 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3536 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3540 NTSTATUS ntStatus = STATUS_SUCCESS;
3541 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3542 BOOLEAN bAcquiredLock = FALSE;
3543 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3548 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3549 AFS_TRACE_LEVEL_VERBOSE,
3550 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3551 ObjectInfo->FileId.Cell,
3552 ObjectInfo->FileId.Volume,
3553 ObjectInfo->FileId.Vnode,
3554 ObjectInfo->FileId.Unique));
3556 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3559 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3560 AFS_TRACE_LEVEL_VERBOSE,
3561 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3562 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3563 PsGetCurrentThread()));
3565 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3568 bAcquiredLock = TRUE;
3572 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3575 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3576 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3579 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3580 AFS_TRACE_LEVEL_ERROR,
3581 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3582 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3583 ObjectInfo->FileId.Cell,
3584 ObjectInfo->FileId.Volume,
3585 ObjectInfo->FileId.Vnode,
3586 ObjectInfo->FileId.Unique));
3590 // Reset the directory list information by clearing all valid entries
3593 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3595 while( pCurrentDirEntry != NULL)
3598 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3600 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3604 // If this entry has been deleted then process it here
3607 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3608 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3609 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3612 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3613 AFS_TRACE_LEVEL_VERBOSE,
3614 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3616 &pCurrentDirEntry->NameInformation.FileName));
3618 AFSDeleteDirEntry( ObjectInfo,
3624 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3626 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3627 AFS_TRACE_LEVEL_VERBOSE,
3628 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3630 pCurrentDirEntry->DirOpenReferenceCount));
3633 // We pull the short name from the parent tree since it could change below
3636 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3639 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3640 AFS_TRACE_LEVEL_VERBOSE,
3641 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3643 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3644 &pCurrentDirEntry->NameInformation.FileName));
3646 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3649 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3654 pCurrentDirEntry = pNextDirEntry;
3658 // Reget the directory contents
3661 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3664 if ( !NT_SUCCESS( ntStatus))
3666 try_return( ntStatus);
3670 // Now start again and tear down any entries not valid
3673 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3675 while( pCurrentDirEntry != NULL)
3678 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3680 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3683 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3684 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3685 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3688 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3691 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3693 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3694 AFS_TRACE_LEVEL_VERBOSE,
3695 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3697 &pCurrentDirEntry->NameInformation.FileName));
3699 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3704 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3707 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3708 AFS_TRACE_LEVEL_VERBOSE,
3709 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3711 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3712 &pCurrentDirEntry->NameInformation.FileName));
3716 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3718 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3719 AFS_TRACE_LEVEL_VERBOSE,
3720 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3722 &pCurrentDirEntry->NameInformation.FileName));
3727 pCurrentDirEntry = pNextDirEntry;
3732 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3733 AFS_TRACE_LEVEL_VERBOSE,
3734 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3736 pCurrentDirEntry->DirOpenReferenceCount));
3738 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3739 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3742 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3743 AFS_TRACE_LEVEL_VERBOSE,
3744 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3745 &pCurrentDirEntry->NameInformation.FileName,
3746 ObjectInfo->FileId.Cell,
3747 ObjectInfo->FileId.Volume,
3748 ObjectInfo->FileId.Vnode,
3749 ObjectInfo->FileId.Unique));
3751 AFSDeleteDirEntry( ObjectInfo,
3757 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3758 AFS_TRACE_LEVEL_VERBOSE,
3759 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3761 &pCurrentDirEntry->NameInformation.FileName,
3762 ObjectInfo->FileId.Cell,
3763 ObjectInfo->FileId.Volume,
3764 ObjectInfo->FileId.Vnode,
3765 ObjectInfo->FileId.Unique));
3767 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3769 AFSRemoveNameEntry( ObjectInfo,
3773 pCurrentDirEntry = pNextDirEntry;
3777 if( !AFSValidateDirList( ObjectInfo))
3780 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3789 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3797 AFSIsVolumeFID( IN AFSFileID *FileID)
3800 BOOLEAN bIsVolume = FALSE;
3802 if( FileID->Vnode == 1 &&
3803 FileID->Unique == 1)
3813 AFSIsFinalNode( IN AFSFcb *Fcb)
3816 BOOLEAN bIsFinalNode = FALSE;
3818 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3819 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3820 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3821 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3822 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3825 bIsFinalNode = TRUE;
3830 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3831 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3834 return bIsFinalNode;
3838 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3839 IN AFSDirEnumEntry *DirEnumEntry)
3842 NTSTATUS ntStatus = STATUS_SUCCESS;
3843 UNICODE_STRING uniTargetName;
3844 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3849 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3851 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3853 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3855 pObjectInfo->FileType = DirEnumEntry->FileType;
3857 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3859 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3861 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3863 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3865 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3867 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3869 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3871 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3872 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3875 pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3878 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
3881 if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
3884 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3889 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3893 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3895 pObjectInfo->Links = DirEnumEntry->Links;
3897 if( DirEnumEntry->TargetNameLength > 0 &&
3898 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3899 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3903 // Update the target name information if needed
3906 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3908 uniTargetName.MaximumLength = uniTargetName.Length;
3910 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3912 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3915 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3916 RtlCompareUnicodeString( &uniTargetName,
3917 &DirEntry->NameInformation.TargetName,
3922 // Update the target name
3925 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3927 uniTargetName.Buffer,
3928 uniTargetName.Length);
3930 if( !NT_SUCCESS( ntStatus))
3933 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3935 try_return( ntStatus);
3939 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3941 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3942 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3945 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3948 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3949 DirEntry->NameInformation.TargetName.Buffer != NULL)
3951 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3954 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3956 DirEntry->NameInformation.TargetName.Length = 0;
3957 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3958 DirEntry->NameInformation.TargetName.Buffer = NULL;
3960 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3972 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3974 IN BOOLEAN FastCall,
3975 IN BOOLEAN bSafeToPurge)
3978 NTSTATUS ntStatus = STATUS_SUCCESS;
3979 LARGE_INTEGER liSystemTime;
3980 AFSDirEnumEntry *pDirEnumEntry = NULL;
3981 AFSFcb *pCurrentFcb = NULL;
3982 BOOLEAN bReleaseFcb = FALSE;
3983 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3989 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3993 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3994 AFS_TRACE_LEVEL_VERBOSE_2,
3995 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3996 &DirEntry->NameInformation.FileName,
3997 pObjectInfo->FileId.Cell,
3998 pObjectInfo->FileId.Volume,
3999 pObjectInfo->FileId.Vnode,
4000 pObjectInfo->FileId.Unique,
4004 // If this is a fake node then bail since the service knows nothing about it
4007 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
4010 try_return( ntStatus);
4014 // This routine ensures that the current entry is valid by:
4016 // 1) Checking that the expiration time is non-zero and after where we
4020 KeQuerySystemTime( &liSystemTime);
4022 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
4023 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
4024 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
4025 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
4028 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4029 AFS_TRACE_LEVEL_VERBOSE_2,
4030 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
4031 &DirEntry->NameInformation.FileName,
4032 pObjectInfo->FileId.Cell,
4033 pObjectInfo->FileId.Volume,
4034 pObjectInfo->FileId.Vnode,
4035 pObjectInfo->FileId.Unique));
4037 try_return( ntStatus);
4041 // This node requires updating
4044 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
4049 if( !NT_SUCCESS( ntStatus))
4052 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4053 AFS_TRACE_LEVEL_ERROR,
4054 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4056 &DirEntry->NameInformation.FileName,
4057 pObjectInfo->FileId.Cell,
4058 pObjectInfo->FileId.Volume,
4059 pObjectInfo->FileId.Vnode,
4060 pObjectInfo->FileId.Unique,
4064 // Failed validation of node so return access-denied
4067 try_return( ntStatus);
4070 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4071 AFS_TRACE_LEVEL_VERBOSE,
4072 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
4074 &DirEntry->NameInformation.FileName,
4075 pObjectInfo->FileId.Cell,
4076 pObjectInfo->FileId.Volume,
4077 pObjectInfo->FileId.Vnode,
4078 pObjectInfo->FileId.Unique,
4079 pObjectInfo->DataVersion.QuadPart,
4080 pDirEnumEntry->DataVersion.QuadPart,
4081 pDirEnumEntry->FileType));
4085 // Based on the file type, process the node
4088 switch( pDirEnumEntry->FileType)
4091 case AFS_FILE_TYPE_MOUNTPOINT:
4095 // Update the metadata for the entry
4098 ntStatus = AFSUpdateMetaData( DirEntry,
4101 if( NT_SUCCESS( ntStatus))
4104 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4110 case AFS_FILE_TYPE_SYMLINK:
4111 case AFS_FILE_TYPE_DFSLINK:
4115 // Update the metadata for the entry
4118 ntStatus = AFSUpdateMetaData( DirEntry,
4121 if( NT_SUCCESS( ntStatus))
4124 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4130 case AFS_FILE_TYPE_FILE:
4133 BOOLEAN bPurgeExtents = FALSE;
4136 // For a file where the data version has become invalid we need to
4137 // fail any current extent requests and purge the cache for the file
4138 // Can't hold the Fcb resource while doing this
4141 if( pObjectInfo->Fcb != NULL &&
4142 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4143 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4146 pCurrentFcb = pObjectInfo->Fcb;
4148 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4151 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4152 AFS_TRACE_LEVEL_VERBOSE,
4153 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4154 &pCurrentFcb->NPFcb->Resource,
4155 PsGetCurrentThread()));
4157 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4163 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4164 AFS_TRACE_LEVEL_VERBOSE_2,
4165 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4166 &DirEntry->NameInformation.FileName,
4167 pObjectInfo->FileId.Cell,
4168 pObjectInfo->FileId.Volume,
4169 pObjectInfo->FileId.Vnode,
4170 pObjectInfo->FileId.Unique));
4172 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4175 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4176 AFS_TRACE_LEVEL_VERBOSE,
4177 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4178 &DirEntry->NameInformation.FileName,
4179 pObjectInfo->FileId.Cell,
4180 pObjectInfo->FileId.Volume,
4181 pObjectInfo->FileId.Vnode,
4182 pObjectInfo->FileId.Unique,
4183 pObjectInfo->DataVersion.LowPart,
4184 pDirEnumEntry->DataVersion.LowPart));
4186 bPurgeExtents = TRUE;
4192 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4194 bPurgeExtents = TRUE;
4196 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4197 AFS_TRACE_LEVEL_VERBOSE,
4198 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4199 &DirEntry->NameInformation.FileName,
4200 pObjectInfo->FileId.Cell,
4201 pObjectInfo->FileId.Volume,
4202 pObjectInfo->FileId.Vnode,
4203 pObjectInfo->FileId.Unique));
4205 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4208 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4209 AFS_TRACE_LEVEL_VERBOSE,
4210 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4211 &pCurrentFcb->NPFcb->SectionObjectResource,
4212 PsGetCurrentThread()));
4214 AFSAcquireExcl( &pCurrentFcb->NPFcb->SectionObjectResource,
4218 // Release Fcb->Resource to avoid Trend Micro deadlock
4221 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4223 bReleaseFcb = FALSE;
4228 IO_STATUS_BLOCK stIoStatus;
4230 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4235 if( !NT_SUCCESS( stIoStatus.Status))
4238 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4239 AFS_TRACE_LEVEL_ERROR,
4240 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4241 &DirEntry->NameInformation.FileName,
4242 pObjectInfo->FileId.Cell,
4243 pObjectInfo->FileId.Volume,
4244 pObjectInfo->FileId.Vnode,
4245 pObjectInfo->FileId.Unique,
4247 stIoStatus.Information));
4249 ntStatus = stIoStatus.Status;
4252 if ( bPurgeExtents &&
4253 pCurrentFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4256 if ( !CcPurgeCacheSection( &pCurrentFcb->NPFcb->SectionObjectPointers,
4262 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4263 AFS_TRACE_LEVEL_WARNING,
4264 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4265 &DirEntry->NameInformation.FileName,
4266 pObjectInfo->FileId.Cell,
4267 pObjectInfo->FileId.Volume,
4268 pObjectInfo->FileId.Vnode,
4269 pObjectInfo->FileId.Unique));
4271 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4275 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
4277 ntStatus = GetExceptionCode();
4281 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4282 &DirEntry->NameInformation.FileName,
4283 pObjectInfo->FileId.Cell,
4284 pObjectInfo->FileId.Volume,
4285 pObjectInfo->FileId.Vnode,
4286 pObjectInfo->FileId.Unique,
4289 SetFlag( pCurrentFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4292 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4293 AFS_TRACE_LEVEL_VERBOSE,
4294 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4295 &pCurrentFcb->NPFcb->SectionObjectResource,
4296 PsGetCurrentThread()));
4298 AFSReleaseResource( &pCurrentFcb->NPFcb->SectionObjectResource);
4306 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4309 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4311 bReleaseFcb = FALSE;
4314 if ( bPurgeExtents &&
4317 AFSFlushExtents( pCurrentFcb,
4323 // Update the metadata for the entry but only if it is safe to do so.
4324 // If it was determined that a data version change has occurred or
4325 // that a pending data verification was required, do not update the
4326 // ObjectInfo meta data or the FileObject size information. That
4327 // way it is consistent for the next time that the data is verified
4331 if ( !(bPurgeExtents && bSafeToPurge))
4334 ntStatus = AFSUpdateMetaData( DirEntry,
4337 if( !NT_SUCCESS( ntStatus))
4340 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4341 AFS_TRACE_LEVEL_ERROR,
4342 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4343 &DirEntry->NameInformation.FileName,
4344 pObjectInfo->FileId.Cell,
4345 pObjectInfo->FileId.Volume,
4346 pObjectInfo->FileId.Vnode,
4347 pObjectInfo->FileId.Unique,
4353 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4356 // Update file sizes
4359 if( pObjectInfo->Fcb != NULL)
4361 FILE_OBJECT *pCCFileObject;
4363 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4364 AFS_TRACE_LEVEL_VERBOSE,
4365 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4366 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4367 PsGetCurrentThread()));
4369 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4375 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4377 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4378 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4379 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4381 if ( pCCFileObject != NULL)
4383 CcSetFileSizes( pCCFileObject,
4384 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4387 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
4390 ntStatus = GetExceptionCode();
4394 "EXCEPTION - AFSValidateEntry CcSetFileSizes failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4395 pObjectInfo->FileId.Cell,
4396 pObjectInfo->FileId.Volume,
4397 pObjectInfo->FileId.Vnode,
4398 pObjectInfo->FileId.Unique,
4402 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4403 AFS_TRACE_LEVEL_VERBOSE,
4404 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4405 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4406 PsGetCurrentThread()));
4408 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4414 case AFS_FILE_TYPE_DIRECTORY:
4417 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4421 // For a directory or root entry flush the content of
4422 // the directory enumeration.
4425 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4426 AFS_TRACE_LEVEL_VERBOSE,
4427 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4428 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4429 PsGetCurrentThread()));
4431 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4434 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4435 AFS_TRACE_LEVEL_VERBOSE_2,
4436 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4437 &DirEntry->NameInformation.FileName,
4438 pObjectInfo->FileId.Cell,
4439 pObjectInfo->FileId.Volume,
4440 pObjectInfo->FileId.Vnode,
4441 pObjectInfo->FileId.Unique));
4443 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4446 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4449 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4452 if( !NT_SUCCESS( ntStatus))
4455 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4456 AFS_TRACE_LEVEL_ERROR,
4457 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4458 &DirEntry->NameInformation.FileName,
4459 pObjectInfo->FileId.Cell,
4460 pObjectInfo->FileId.Volume,
4461 pObjectInfo->FileId.Vnode,
4462 pObjectInfo->FileId.Unique,
4470 // Update the metadata for the entry
4473 ntStatus = AFSUpdateMetaData( DirEntry,
4476 if( NT_SUCCESS( ntStatus))
4479 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4487 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4488 AFS_TRACE_LEVEL_WARNING,
4489 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4490 pObjectInfo->FileType,
4492 &DirEntry->NameInformation.FileName,
4493 pObjectInfo->FileId.Cell,
4494 pObjectInfo->FileId.Volume,
4495 pObjectInfo->FileId.Vnode,
4496 pObjectInfo->FileId.Unique));
4506 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4509 if( pDirEnumEntry != NULL)
4512 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4520 AFSInitializeSpecialShareNameList()
4523 NTSTATUS ntStatus = STATUS_SUCCESS;
4524 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4525 AFSObjectInfoCB *pObjectInfoCB = NULL;
4526 UNICODE_STRING uniShareName;
4527 ULONG ulEntryLength = 0;
4528 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4534 RtlInitUnicodeString( &uniShareName,
4537 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4540 if( pObjectInfoCB == NULL)
4543 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4546 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4547 AFS_OBJECT_REFERENCE_GLOBAL);
4549 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4550 AFS_TRACE_LEVEL_VERBOSE,
4551 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4555 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4557 ulEntryLength = sizeof( AFSDirectoryCB) +
4558 uniShareName.Length;
4560 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4564 if( pDirNode == NULL)
4567 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4568 AFS_OBJECT_REFERENCE_GLOBAL);
4570 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4571 AFS_TRACE_LEVEL_VERBOSE,
4572 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4579 AFSDeleteObjectInfo( &pObjectInfoCB);
4582 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4585 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4586 AFS_TRACE_LEVEL_VERBOSE,
4587 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4590 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4591 sizeof( AFSNonPagedDirectoryCB),
4592 AFS_DIR_ENTRY_NP_TAG);
4594 if( pNonPagedDirEntry == NULL)
4597 AFSLibExFreePoolWithTag( pDirNode,
4600 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4601 AFS_OBJECT_REFERENCE_GLOBAL);
4603 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4604 AFS_TRACE_LEVEL_VERBOSE,
4605 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4612 AFSDeleteObjectInfo( &pObjectInfoCB);
4615 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4618 RtlZeroMemory( pDirNode,
4621 RtlZeroMemory( pNonPagedDirEntry,
4622 sizeof( AFSNonPagedDirectoryCB));
4624 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4626 pDirNode->NonPaged = pNonPagedDirEntry;
4628 pDirNode->ObjectInformation = pObjectInfoCB;
4634 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4636 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4638 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4640 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4642 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4643 uniShareName.Buffer,
4644 pDirNode->NameInformation.FileName.Length);
4646 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4649 AFSSpecialShareNames = pDirNode;
4651 pLastDirNode = pDirNode;
4654 RtlInitUnicodeString( &uniShareName,
4657 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4660 if( pObjectInfoCB == NULL)
4663 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4666 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4667 AFS_OBJECT_REFERENCE_GLOBAL);
4669 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4670 AFS_TRACE_LEVEL_VERBOSE,
4671 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4675 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4677 ulEntryLength = sizeof( AFSDirectoryCB) +
4678 uniShareName.Length;
4680 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4684 if( pDirNode == NULL)
4687 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4688 AFS_OBJECT_REFERENCE_GLOBAL);
4690 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4691 AFS_TRACE_LEVEL_VERBOSE,
4692 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4699 AFSDeleteObjectInfo( &pObjectInfoCB);
4702 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4705 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4706 AFS_TRACE_LEVEL_VERBOSE,
4707 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4710 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4711 sizeof( AFSNonPagedDirectoryCB),
4712 AFS_DIR_ENTRY_NP_TAG);
4714 if( pNonPagedDirEntry == NULL)
4717 AFSLibExFreePoolWithTag( pDirNode,
4720 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4721 AFS_OBJECT_REFERENCE_GLOBAL);
4723 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4724 AFS_TRACE_LEVEL_VERBOSE,
4725 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4732 AFSDeleteObjectInfo( &pObjectInfoCB);
4735 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4738 RtlZeroMemory( pDirNode,
4741 RtlZeroMemory( pNonPagedDirEntry,
4742 sizeof( AFSNonPagedDirectoryCB));
4744 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4746 pDirNode->NonPaged = pNonPagedDirEntry;
4748 pDirNode->ObjectInformation = pObjectInfoCB;
4754 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4756 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4758 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4760 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4762 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4763 uniShareName.Buffer,
4764 pDirNode->NameInformation.FileName.Length);
4766 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4769 pLastDirNode->ListEntry.fLink = pDirNode;
4771 pDirNode->ListEntry.bLink = pLastDirNode;
4775 if( !NT_SUCCESS( ntStatus))
4778 if( AFSSpecialShareNames != NULL)
4781 pDirNode = AFSSpecialShareNames;
4783 while( pDirNode != NULL)
4786 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4788 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
4789 AFS_OBJECT_REFERENCE_GLOBAL);
4791 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4792 AFS_TRACE_LEVEL_VERBOSE,
4793 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4794 pDirNode->ObjectInformation,
4800 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4803 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4805 AFSLibExFreePoolWithTag( pDirNode->NonPaged,
4806 AFS_DIR_ENTRY_NP_TAG);
4808 AFSLibExFreePoolWithTag( pDirNode,
4811 pDirNode = pLastDirNode;
4814 AFSSpecialShareNames = NULL;
4823 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4824 IN UNICODE_STRING *SecondaryName)
4827 AFSDirectoryCB *pDirectoryCB = NULL;
4828 ULONGLONG ullHash = 0;
4829 UNICODE_STRING uniFullShareName;
4835 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4836 AFS_TRACE_LEVEL_VERBOSE_2,
4837 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4841 uniFullShareName = *ShareName;
4844 // Generate our hash value
4847 ullHash = AFSGenerateCRC( &uniFullShareName,
4851 // Loop through our special share names to see if this is one of them
4854 pDirectoryCB = AFSSpecialShareNames;
4856 while( pDirectoryCB != NULL)
4859 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4865 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4869 return pDirectoryCB;
4873 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4877 // Block on the queue flush event
4880 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4890 AFSWaitOnQueuedReleases()
4893 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4896 // Block on the queue flush event
4899 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4909 AFSIsEqualFID( IN AFSFileID *FileId1,
4910 IN AFSFileID *FileId2)
4913 BOOLEAN bIsEqual = FALSE;
4915 if( FileId1->Hash == FileId2->Hash &&
4916 FileId1->Unique == FileId2->Unique &&
4917 FileId1->Vnode == FileId2->Vnode &&
4918 FileId1->Volume == FileId2->Volume &&
4919 FileId1->Cell == FileId2->Cell)
4929 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4932 NTSTATUS ntStatus = STATUS_SUCCESS;
4933 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4938 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4941 // Reset the directory list information
4944 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4946 while( pCurrentDirEntry != NULL)
4949 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4951 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
4952 pCurrentDirEntry->NameArrayReferenceCount <= 0)
4955 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4956 AFS_TRACE_LEVEL_VERBOSE,
4957 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4959 &pCurrentDirEntry->NameInformation.FileName));
4961 AFSDeleteDirEntry( ObjectInfoCB,
4967 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4968 AFS_TRACE_LEVEL_VERBOSE,
4969 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4971 &pCurrentDirEntry->NameInformation.FileName));
4973 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4975 AFSRemoveNameEntry( ObjectInfoCB,
4979 pCurrentDirEntry = pNextDirEntry;
4982 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4984 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4986 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4988 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4990 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4992 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4994 AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4995 AFS_TRACE_LEVEL_VERBOSE,
4996 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4997 ObjectInfoCB->FileId.Cell,
4998 ObjectInfoCB->FileId.Volume,
4999 ObjectInfoCB->FileId.Vnode,
5000 ObjectInfoCB->FileId.Unique));
5007 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
5010 NTSTATUS ntStatus = STATUS_SUCCESS;
5011 AFSDirectoryCB *pDirGlobalDirNode = NULL;
5012 UNICODE_STRING uniFullName;
5017 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
5018 AFS_TRACE_LEVEL_VERBOSE,
5019 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
5020 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
5021 PsGetCurrentThread()));
5023 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
5026 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
5029 try_return( ntStatus);
5033 // Initialize the root information
5036 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
5039 // Enumerate the shares in the volume
5042 ntStatus = AFSEnumerateDirectory( AuthGroup,
5043 &AFSGlobalRoot->ObjectInformation,
5046 if( !NT_SUCCESS( ntStatus))
5049 try_return( ntStatus);
5052 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
5054 uniFullName.MaximumLength = PAGE_SIZE;
5055 uniFullName.Length = 0;
5057 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
5058 uniFullName.MaximumLength,
5059 AFS_GENERIC_MEMORY_12_TAG);
5061 if( uniFullName.Buffer == NULL)
5065 // Reset the directory content
5068 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
5070 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
5072 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5076 // Populate our list of entries in the NP enumeration list
5079 while( pDirGlobalDirNode != NULL)
5082 uniFullName.Buffer[ 0] = L'\\';
5083 uniFullName.Buffer[ 1] = L'\\';
5085 uniFullName.Length = 2 * sizeof( WCHAR);
5087 RtlCopyMemory( &uniFullName.Buffer[ 2],
5088 AFSServerName.Buffer,
5089 AFSServerName.Length);
5091 uniFullName.Length += AFSServerName.Length;
5093 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
5095 uniFullName.Length += sizeof( WCHAR);
5097 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
5098 pDirGlobalDirNode->NameInformation.FileName.Buffer,
5099 pDirGlobalDirNode->NameInformation.FileName.Length);
5101 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
5103 AFSAddConnectionEx( &uniFullName,
5104 RESOURCEDISPLAYTYPE_SHARE,
5107 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
5110 AFSLibExFreePoolWithTag( uniFullName.Buffer,
5111 AFS_GENERIC_MEMORY_12_TAG);
5115 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
5122 AFSIsRelativeName( IN UNICODE_STRING *Name)
5125 BOOLEAN bIsRelative = FALSE;
5127 if( Name->Length > 0 &&
5128 Name->Buffer[ 0] != L'\\')
5138 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
5140 UNICODE_STRING uniTempName;
5141 BOOLEAN bIsAbsolute = FALSE;
5144 // An absolute AFS path must begin with \afs\... or equivalent
5147 if ( Name->Length == 0 ||
5148 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
5149 Name->Buffer[ 0] != L'\\' ||
5150 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
5156 uniTempName.Length = AFSMountRootName.Length;
5157 uniTempName.MaximumLength = AFSMountRootName.Length;
5159 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5160 uniTempName.MaximumLength,
5161 AFS_NAME_BUFFER_TWO_TAG);
5163 if( uniTempName.Buffer == NULL)
5169 RtlCopyMemory( uniTempName.Buffer,
5171 AFSMountRootName.Length);
5173 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
5177 AFSExFreePoolWithTag( uniTempName.Buffer,
5178 AFS_NAME_BUFFER_TWO_TAG);
5185 AFSUpdateName( IN UNICODE_STRING *Name)
5190 while( usIndex < Name->Length/sizeof( WCHAR))
5193 if( Name->Buffer[ usIndex] == L'/')
5196 Name->Buffer[ usIndex] = L'\\';
5206 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
5207 IN OUT ULONG *Flags,
5208 IN WCHAR *NameBuffer,
5209 IN USHORT NameLength)
5212 NTSTATUS ntStatus = STATUS_SUCCESS;
5213 WCHAR *pTmpBuffer = NULL;
5219 // If we have enough space then just move in the name otherwise
5220 // allocate a new buffer
5223 if( TargetName->Length < NameLength)
5226 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5228 AFS_NAME_BUFFER_FIVE_TAG);
5230 if( pTmpBuffer == NULL)
5233 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5236 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5239 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5242 TargetName->MaximumLength = NameLength;
5244 TargetName->Buffer = pTmpBuffer;
5246 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5249 TargetName->Length = NameLength;
5251 RtlCopyMemory( TargetName->Buffer,
5253 TargetName->Length);
5256 // Update the name in the buffer
5259 AFSUpdateName( TargetName);
5270 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5275 // Depending on the type of node, set the event
5278 switch( Fcb->Header.NodeTypeCode)
5281 case AFS_DIRECTORY_FCB:
5286 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5296 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5302 // Depending on the type of node, set the event
5305 switch( Fcb->Header.NodeTypeCode)
5308 case AFS_DIRECTORY_FCB:
5313 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5315 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5325 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5328 BOOLEAN bIsInProcess = FALSE;
5333 if( ObjectInfo->Fcb == NULL)
5336 try_return( bIsInProcess);
5339 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5342 case AFS_DIRECTORY_FCB:
5347 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5350 bIsInProcess = TRUE;
5362 return bIsInProcess;
5366 AFSVerifyVolume( IN ULONGLONG ProcessId,
5367 IN AFSVolumeCB *VolumeCB)
5370 UNREFERENCED_PARAMETER(ProcessId);
5371 UNREFERENCED_PARAMETER(VolumeCB);
5372 NTSTATUS ntStatus = STATUS_SUCCESS;
5379 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5382 NTSTATUS ntStatus = STATUS_SUCCESS;
5383 AFSObjectInfoCB *pObjectInfoCB = NULL;
5384 AFSDirectoryCB *pDirNode = NULL;
5385 ULONG ulEntryLength = 0;
5386 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5392 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
5395 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5398 if( pObjectInfoCB == NULL)
5401 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5403 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5406 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5407 AFS_OBJECT_REFERENCE_PIOCTL);
5409 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5410 AFS_TRACE_LEVEL_VERBOSE,
5411 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5415 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5417 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5419 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5421 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5423 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5427 if( pDirNode == NULL)
5430 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5433 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5434 AFS_TRACE_LEVEL_VERBOSE,
5435 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5438 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5439 sizeof( AFSNonPagedDirectoryCB),
5440 AFS_DIR_ENTRY_NP_TAG);
5442 if( pNonPagedDirEntry == NULL)
5445 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5448 RtlZeroMemory( pDirNode,
5451 RtlZeroMemory( pNonPagedDirEntry,
5452 sizeof( AFSNonPagedDirectoryCB));
5454 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5456 pDirNode->NonPaged = pNonPagedDirEntry;
5458 pDirNode->ObjectInformation = pObjectInfoCB;
5460 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5466 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5468 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5470 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5472 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5474 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5475 AFSPIOCtlName.Buffer,
5476 pDirNode->NameInformation.FileName.Length);
5478 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5481 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5484 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5485 AFS_TRACE_LEVEL_WARNING,
5486 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5487 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5490 try_return( ntStatus = STATUS_REPARSE);
5495 if ( ntStatus != STATUS_SUCCESS)
5498 if ( pDirNode != NULL)
5501 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5502 AFS_TRACE_LEVEL_VERBOSE,
5503 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
5506 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5509 if( pNonPagedDirEntry != NULL)
5512 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5514 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5517 if ( pObjectInfoCB != NULL)
5520 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
5521 AFS_OBJECT_REFERENCE_PIOCTL);
5523 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5524 AFS_TRACE_LEVEL_VERBOSE,
5525 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
5532 AFSDeleteObjectInfo( &pObjectInfoCB);
5542 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5543 IN AFSDirectoryCB *DirectoryCB,
5544 IN UNICODE_STRING *ParentPathName,
5545 IN AFSNameArrayHdr *RelatedNameArray,
5547 OUT AFSFileInfoCB *FileInfo)
5550 NTSTATUS ntStatus = STATUS_SUCCESS;
5551 AFSDirEnumEntry *pDirEntry = NULL;
5552 UNICODE_STRING uniFullPathName = {0};
5553 AFSNameArrayHdr *pNameArray = NULL;
5554 AFSVolumeCB *pVolumeCB = NULL;
5555 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5556 AFSVolumeCB *pNewVolumeCB = NULL;
5557 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5558 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5559 AFSDirectoryCB *pNewParentDirEntry = NULL;
5560 WCHAR *pwchBuffer = NULL;
5561 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5562 ULONG ulNameDifference = 0;
5569 // Retrieve a target name for the entry
5572 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5575 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5578 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5580 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5585 if( !NT_SUCCESS( ntStatus) ||
5586 pDirEntry->TargetNameLength == 0)
5589 if( pDirEntry != NULL)
5592 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5595 try_return( ntStatus);
5598 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5601 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5605 // Update the target name
5608 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5609 &DirectoryCB->Flags,
5610 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5611 (USHORT)pDirEntry->TargetNameLength);
5613 if( !NT_SUCCESS( ntStatus))
5616 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5618 try_return( ntStatus);
5622 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5626 // Need to pass the full path in for parsing.
5629 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5632 uniFullPathName.Length = 0;
5633 uniFullPathName.MaximumLength = ParentPathName->Length +
5635 DirectoryCB->NameInformation.TargetName.Length;
5637 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5638 uniFullPathName.MaximumLength,
5639 AFS_NAME_BUFFER_SIX_TAG);
5641 if( uniFullPathName.Buffer == NULL)
5644 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5646 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5649 pwchBuffer = uniFullPathName.Buffer;
5651 RtlZeroMemory( uniFullPathName.Buffer,
5652 uniFullPathName.MaximumLength);
5654 RtlCopyMemory( uniFullPathName.Buffer,
5655 ParentPathName->Buffer,
5656 ParentPathName->Length);
5658 uniFullPathName.Length = ParentPathName->Length;
5660 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5661 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5664 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5666 uniFullPathName.Length += sizeof( WCHAR);
5669 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5670 DirectoryCB->NameInformation.TargetName.Buffer,
5671 DirectoryCB->NameInformation.TargetName.Length);
5673 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5675 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5676 uniParsedName.MaximumLength = uniParsedName.Length;
5678 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5680 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5683 // We populate up to the current parent
5686 if( RelatedNameArray != NULL)
5689 pNameArray = AFSInitNameArray( NULL,
5690 RelatedNameArray->MaxElementCount);
5692 if( pNameArray == NULL)
5695 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5698 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5705 pNameArray = AFSInitNameArray( NULL,
5708 if( pNameArray == NULL)
5711 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5714 ntStatus = AFSPopulateNameArray( pNameArray,
5719 if( !NT_SUCCESS( ntStatus))
5722 try_return( ntStatus);
5725 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5727 pParentDirEntry = ParentDirectoryCB;
5732 uniFullPathName.Length = 0;
5733 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5735 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5736 uniFullPathName.MaximumLength,
5737 AFS_NAME_BUFFER_SEVEN_TAG);
5739 if( uniFullPathName.Buffer == NULL)
5742 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5744 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5747 pwchBuffer = uniFullPathName.Buffer;
5749 RtlZeroMemory( uniFullPathName.Buffer,
5750 uniFullPathName.MaximumLength);
5752 RtlCopyMemory( uniFullPathName.Buffer,
5753 DirectoryCB->NameInformation.TargetName.Buffer,
5754 DirectoryCB->NameInformation.TargetName.Length);
5756 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5759 // This name should begin with the \afs server so parse it off and check it
5762 FsRtlDissectName( uniFullPathName,
5766 if( RtlCompareUnicodeString( &uniComponentName,
5771 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5773 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5774 AFS_TRACE_LEVEL_ERROR,
5775 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5778 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5781 uniFullPathName = uniRemainingPath;
5783 uniParsedName = uniFullPathName;
5785 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5787 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5793 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5796 if( pNameArray == NULL)
5799 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5802 pVolumeCB = AFSGlobalRoot;
5804 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5808 // Increment the ref count on the volume and dir entry for correct processing below
5811 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
5813 lCount = AFSVolumeIncrement( pVolumeCB,
5814 VolumeReferenceReason);
5816 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5817 AFS_TRACE_LEVEL_VERBOSE,
5818 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
5820 VolumeReferenceReason,
5823 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
5825 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5826 AFS_TRACE_LEVEL_VERBOSE,
5827 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5828 &pParentDirEntry->NameInformation.FileName,
5833 ntStatus = AFSLocateNameEntry( NULL,
5838 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5842 &NewVolumeReferenceReason,
5843 &pNewParentDirEntry,
5847 if ( pNewVolumeCB != NULL)
5850 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
5851 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
5852 // the reference on pVolumeCB that was held prior to the call.
5853 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
5854 // will be released second.
5857 lCount = AFSVolumeDecrement( pVolumeCB,
5858 VolumeReferenceReason);
5860 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5861 AFS_TRACE_LEVEL_VERBOSE,
5862 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
5864 VolumeReferenceReason,
5867 pVolumeCB = pNewVolumeCB;
5869 pNewVolumeCB = NULL;
5871 VolumeReferenceReason = NewVolumeReferenceReason;
5873 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5877 // AFSLocateNameEntry does not alter the reference count of
5878 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
5879 // a reference held.
5882 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5884 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5885 AFS_TRACE_LEVEL_VERBOSE,
5886 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
5887 &pParentDirEntry->NameInformation.FileName,
5891 pParentDirEntry = pNewParentDirEntry;
5893 pNewParentDirEntry = NULL;
5895 if( !NT_SUCCESS( ntStatus) ||
5896 ntStatus == STATUS_REPARSE)
5899 try_return( ntStatus);
5903 // Store off the information
5906 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5909 // Check for the mount point being returned
5912 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
5913 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5916 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5918 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
5921 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
5924 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
5929 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5933 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5935 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5937 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5939 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5941 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5943 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5947 if( pDirEntry != NULL)
5950 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
5953 if( pDirectoryEntry != NULL)
5956 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
5958 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5959 AFS_TRACE_LEVEL_VERBOSE,
5960 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5961 &pDirectoryEntry->NameInformation.FileName,
5966 ASSERT( lCount >= 0);
5969 if ( pParentDirEntry != NULL)
5972 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5974 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5975 AFS_TRACE_LEVEL_VERBOSE,
5976 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5977 &pParentDirEntry->NameInformation.FileName,
5982 ASSERT( lCount >= 0);
5985 if( pVolumeCB != NULL)
5988 lCount = AFSVolumeDecrement( pVolumeCB,
5989 VolumeReferenceReason);
5991 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5992 AFS_TRACE_LEVEL_VERBOSE,
5993 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
5995 VolumeReferenceReason,
5999 if( pNameArray != NULL)
6002 AFSFreeNameArray( pNameArray);
6005 if( pwchBuffer != NULL)
6009 // Always free the buffer that we allocated as AFSLocateNameEntry
6010 // will not free it. If uniFullPathName.Buffer was allocated by
6011 // AFSLocateNameEntry, then we must free that as well.
6012 // Check that the uniFullPathName.Buffer in the string is not the same
6013 // offset by the length of the server name
6016 if( uniFullPathName.Length > 0 &&
6017 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6020 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6023 AFSExFreePoolWithTag( pwchBuffer, 0);
6031 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6032 IN ULONGLONG HashIndex)
6035 NTSTATUS ntStatus = STATUS_SUCCESS;
6036 AFSObjectInfoCB *pObjectInfo = NULL;
6042 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6043 sizeof( AFSObjectInfoCB),
6044 AFS_OBJECT_INFO_TAG);
6046 if( pObjectInfo == NULL)
6049 try_return( pObjectInfo);
6052 RtlZeroMemory( pObjectInfo,
6053 sizeof( AFSObjectInfoCB));
6055 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6056 sizeof( AFSNonPagedObjectInfoCB),
6057 AFS_NP_OBJECT_INFO_TAG);
6059 if( pObjectInfo->NonPagedInfo == NULL)
6062 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6064 try_return( pObjectInfo = NULL);
6067 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6069 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6071 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6073 if( ParentObjectInfo != NULL)
6076 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6078 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6080 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6082 AFSAcquireShared( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6085 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6086 AFS_OBJECT_REFERENCE_CHILD);
6088 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6089 AFS_TRACE_LEVEL_VERBOSE,
6090 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6094 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6098 // Initialize the access time
6101 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6106 ASSERT( ParentObjectInfo);
6109 // Insert the entry into the object tree and list
6112 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6114 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6117 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6122 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6123 &pObjectInfo->TreeEntry);
6125 ASSERT( NT_SUCCESS( ntStatus));
6129 // And the object list in the volume
6132 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6135 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6140 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6142 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6145 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6148 // Indicate the object is in the hash tree and linked list in the volume
6151 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6163 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6169 if ( ObjectInfo->ObjectReferenceCount == 0)
6172 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6175 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6180 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6183 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6188 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6190 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6195 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6197 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6203 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6207 LONG lCount, lCount2;
6209 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6212 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6217 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6219 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6221 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6224 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6227 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6229 ASSERT( lCount2 >= 0);
6231 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6237 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6238 IN AFSFileID *FileId,
6239 IN BOOLEAN bUpdateLastUse)
6241 DWORD ntStatus = STATUS_SUCCESS;
6243 AFSObjectInfoCB *pObjectInfo = NULL;
6246 ullIndex = AFSCreateLowIndex( FileId);
6248 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
6251 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6254 pObjectInfo = &VolumeCB->ObjectInformation;
6259 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6261 (AFSBTreeEntry **)&pObjectInfo);
6264 if ( NT_SUCCESS( ntStatus)) {
6266 lCount = AFSObjectInfoIncrement( pObjectInfo,
6267 AFS_OBJECT_REFERENCE_FIND);
6269 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6270 AFS_TRACE_LEVEL_VERBOSE,
6271 "AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
6275 if ( bUpdateLastUse)
6278 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6282 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6288 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6292 lCount = AFSObjectInfoDecrement( *ppObjectInfo,
6293 AFS_OBJECT_REFERENCE_FIND);
6295 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6296 AFS_TRACE_LEVEL_VERBOSE,
6297 "AFSReleaseObjectInfo Decrement count on object %p Cnt %d\n",
6301 *ppObjectInfo = NULL;
6305 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6307 BOOLEAN bAcquiredTreeLock = FALSE;
6308 AFSObjectInfoCB *pObjectInfo = NULL;
6309 AFSVolumeCB * pVolume = NULL;
6310 BOOLEAN bHeldInService;
6311 AFSObjectInfoCB * pParentObjectInfo = NULL;
6317 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
6321 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6322 // embedded in the VolumeCB.
6330 pVolume = (*ppObjectInfo)->VolumeCB;
6332 if( !ExIsResourceAcquiredExclusiveLite( pVolume->ObjectInfoTree.TreeLock))
6335 ASSERT( !ExIsResourceAcquiredLite( pVolume->ObjectInfoTree.TreeLock));
6337 AFSAcquireExcl( pVolume->ObjectInfoTree.TreeLock,
6340 bAcquiredTreeLock = TRUE;
6343 for ( lCount = 0; lCount < AFS_OBJECT_REFERENCE_MAX; lCount++)
6346 ASSERT( (*ppObjectInfo)->ObjectReferences[ lCount] >= 0);
6349 ASSERT( (*ppObjectInfo)->ObjectReferenceCount == 0);
6351 pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
6355 if ( pObjectInfo == NULL)
6358 try_return( NOTHING);
6361 ASSERT( *ppObjectInfo == NULL);
6363 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6366 pParentObjectInfo = AFSFindObjectInfo( pVolume,
6367 &pObjectInfo->ParentFileId,
6370 if( pParentObjectInfo != NULL)
6373 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6375 AFSAcquireShared( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6378 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6379 AFS_OBJECT_REFERENCE_CHILD);
6381 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6382 AFS_TRACE_LEVEL_VERBOSE,
6383 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6387 AFSReleaseResource( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6389 AFSReleaseObjectInfo( &pParentObjectInfo);
6394 // Remove it from the tree and list if it was inserted
6397 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6400 AFSRemoveHashEntry( &pVolume->ObjectInfoTree.TreeHead,
6401 &pObjectInfo->TreeEntry);
6404 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6407 if( pObjectInfo->ListEntry.fLink == NULL)
6410 pVolume->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6412 if( pVolume->ObjectInfoListTail != NULL)
6415 pVolume->ObjectInfoListTail->ListEntry.fLink = NULL;
6421 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6424 if( pObjectInfo->ListEntry.bLink == NULL)
6427 pVolume->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6429 if( pVolume->ObjectInfoListHead != NULL)
6432 pVolume->ObjectInfoListHead->ListEntry.bLink = NULL;
6438 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6442 bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6447 FileId = pObjectInfo->FileId;
6450 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6452 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6454 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6456 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6458 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6462 if( bAcquiredTreeLock)
6465 AFSReleaseResource( pVolume->ObjectInfoTree.TreeLock);
6469 // Release the fid in the service
6475 AFSReleaseFid( &FileId);
6483 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6484 OUT AFSDirectoryCB **TargetDirEntry)
6487 NTSTATUS ntStatus = STATUS_SUCCESS;
6488 AFSDirEnumEntry *pDirEntry = NULL;
6489 UNICODE_STRING uniFullPathName = {0};
6490 AFSNameArrayHdr *pNameArray = NULL;
6491 AFSVolumeCB *pVolumeCB = NULL;
6492 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6493 AFSVolumeCB *pNewVolumeCB = NULL;
6494 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6495 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6496 AFSDirectoryCB *pNewParentDirEntry = NULL;
6497 WCHAR *pwchBuffer = NULL;
6498 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6499 ULONG ulNameDifference = 0;
6506 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6507 DirectoryCB->ObjectInformation,
6511 if( !NT_SUCCESS( ntStatus))
6513 try_return( ntStatus);
6517 // Retrieve a target name for the entry
6520 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6523 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6526 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6528 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6533 if( !NT_SUCCESS( ntStatus) ||
6534 pDirEntry->TargetNameLength == 0)
6537 if( pDirEntry != NULL)
6540 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6543 try_return( ntStatus);
6546 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6549 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6553 // Update the target name
6556 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6557 &DirectoryCB->Flags,
6558 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6559 (USHORT)pDirEntry->TargetNameLength);
6561 if( !NT_SUCCESS( ntStatus))
6564 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6566 try_return( ntStatus);
6570 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6574 // Need to pass the full path in for parsing.
6577 uniFullPathName.Length = 0;
6578 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6580 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6581 uniFullPathName.MaximumLength,
6582 AFS_NAME_BUFFER_EIGHT_TAG);
6584 if( uniFullPathName.Buffer == NULL)
6587 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6589 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6592 pwchBuffer = uniFullPathName.Buffer;
6594 RtlZeroMemory( uniFullPathName.Buffer,
6595 uniFullPathName.MaximumLength);
6597 RtlCopyMemory( uniFullPathName.Buffer,
6598 DirectoryCB->NameInformation.TargetName.Buffer,
6599 DirectoryCB->NameInformation.TargetName.Length);
6601 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6604 // This name should begin with the \afs server so parse it off and chech it
6607 FsRtlDissectName( uniFullPathName,
6611 if( RtlCompareUnicodeString( &uniComponentName,
6617 // Try evaluating the full path
6620 uniFullPathName.Buffer = pwchBuffer;
6622 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6624 uniFullPathName.MaximumLength = uniFullPathName.Length;
6629 uniFullPathName = uniRemainingPath;
6632 uniParsedName = uniFullPathName;
6634 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6636 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6642 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6645 if( pNameArray == NULL)
6648 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6651 pVolumeCB = AFSGlobalRoot;
6653 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6655 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
6657 lCount = AFSVolumeIncrement( pVolumeCB,
6658 VolumeReferenceReason);
6660 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6661 AFS_TRACE_LEVEL_VERBOSE,
6662 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
6664 VolumeReferenceReason,
6667 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6669 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6670 AFS_TRACE_LEVEL_VERBOSE,
6671 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6672 &pParentDirEntry->NameInformation.FileName,
6677 ntStatus = AFSLocateNameEntry( NULL,
6686 &VolumeReferenceReason,
6687 &pNewParentDirEntry,
6691 if ( pNewVolumeCB != NULL)
6694 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6695 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6696 // the reference on pVolumeCB that was held prior to the call.
6697 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6698 // will be released second.
6701 lCount = AFSVolumeDecrement( pVolumeCB,
6702 VolumeReferenceReason);
6704 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6705 AFS_TRACE_LEVEL_VERBOSE,
6706 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
6708 VolumeReferenceReason,
6711 pVolumeCB = pNewVolumeCB;
6713 pNewVolumeCB = NULL;
6715 VolumeReferenceReason = NewVolumeReferenceReason;
6717 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6721 // AFSLocateNameEntry does not alter the reference count of
6722 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6723 // a reference held.
6726 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6728 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6729 AFS_TRACE_LEVEL_VERBOSE,
6730 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
6731 &pParentDirEntry->NameInformation.FileName,
6735 pParentDirEntry = pNewParentDirEntry;
6737 pNewParentDirEntry = NULL;
6739 if( !NT_SUCCESS( ntStatus) ||
6740 ntStatus == STATUS_REPARSE)
6745 try_return( ntStatus);
6749 // Pass back the target dir entry for this request
6750 // The caller must release the DirOpenReferenceCount
6753 *TargetDirEntry = pDirectoryEntry;
6755 pDirectoryEntry = NULL;
6759 if( pDirectoryEntry != NULL)
6762 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6764 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6765 AFS_TRACE_LEVEL_VERBOSE,
6766 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6767 &pDirectoryEntry->NameInformation.FileName,
6772 ASSERT( lCount >= 0);
6775 if ( pParentDirEntry != NULL)
6778 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6780 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6781 AFS_TRACE_LEVEL_VERBOSE,
6782 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6783 &pParentDirEntry->NameInformation.FileName,
6788 ASSERT( lCount >= 0);
6791 if( pDirEntry != NULL)
6794 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6797 if( pVolumeCB != NULL)
6800 lCount = AFSVolumeDecrement( pVolumeCB,
6801 VolumeReferenceReason);
6803 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6804 AFS_TRACE_LEVEL_VERBOSE,
6805 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
6807 VolumeReferenceReason,
6811 if( pNameArray != NULL)
6814 AFSFreeNameArray( pNameArray);
6817 if( pwchBuffer != NULL)
6821 // Always free the buffer that we allocated as AFSLocateNameEntry
6822 // will not free it. If uniFullPathName.Buffer was allocated by
6823 // AFSLocateNameEntry, then we must free that as well.
6824 // Check that the uniFullPathName.Buffer in the string is not the same
6825 // offset by the length of the server name
6828 if( uniFullPathName.Length > 0 &&
6829 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6832 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6835 AFSExFreePoolWithTag( pwchBuffer, 0);
6843 AFSCleanupFcb( IN AFSFcb *Fcb,
6844 IN BOOLEAN ForceFlush)
6847 NTSTATUS ntStatus = STATUS_SUCCESS;
6848 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6849 LARGE_INTEGER liTime;
6850 IO_STATUS_BLOCK stIoStatus;
6855 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6857 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6859 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6862 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6863 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6866 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6867 AFS_TRACE_LEVEL_VERBOSE,
6868 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
6869 &Fcb->NPFcb->Resource,
6870 PsGetCurrentThread()));
6872 AFSAcquireShared( &Fcb->NPFcb->Resource,
6875 if( Fcb->OpenReferenceCount > 0)
6878 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
6879 AFS_TRACE_LEVEL_VERBOSE,
6880 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
6881 &Fcb->NPFcb->SectionObjectResource,
6882 PsGetCurrentThread()));
6884 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
6890 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6895 if( !NT_SUCCESS( stIoStatus.Status))
6898 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6899 AFS_TRACE_LEVEL_ERROR,
6900 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6901 Fcb->ObjectInformation->FileId.Cell,
6902 Fcb->ObjectInformation->FileId.Volume,
6903 Fcb->ObjectInformation->FileId.Vnode,
6904 Fcb->ObjectInformation->FileId.Unique,
6906 stIoStatus.Information));
6908 ntStatus = stIoStatus.Status;
6911 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
6914 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6920 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6921 AFS_TRACE_LEVEL_WARNING,
6922 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
6923 Fcb->ObjectInformation->FileId.Cell,
6924 Fcb->ObjectInformation->FileId.Volume,
6925 Fcb->ObjectInformation->FileId.Vnode,
6926 Fcb->ObjectInformation->FileId.Unique));
6928 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6932 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
6935 ntStatus = GetExceptionCode();
6939 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
6940 Fcb->ObjectInformation->FileId.Cell,
6941 Fcb->ObjectInformation->FileId.Volume,
6942 Fcb->ObjectInformation->FileId.Vnode,
6943 Fcb->ObjectInformation->FileId.Unique,
6946 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6949 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
6950 AFS_TRACE_LEVEL_VERBOSE,
6951 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
6952 &Fcb->NPFcb->SectionObjectResource,
6953 PsGetCurrentThread()));
6955 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
6958 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6959 AFS_TRACE_LEVEL_VERBOSE,
6960 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
6961 &Fcb->NPFcb->Resource,
6962 PsGetCurrentThread()));
6964 AFSReleaseResource( &Fcb->NPFcb->Resource);
6967 // Wait for any currently running flush or release requests to complete
6970 AFSWaitOnQueuedFlushes( Fcb);
6973 // Now perform another flush on the file
6976 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6980 AFSReleaseExtentsWithFlush( Fcb,
6986 if( Fcb->OpenReferenceCount == 0 ||
6987 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6988 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6991 AFSTearDownFcbExtents( Fcb,
6995 try_return( ntStatus);
6998 KeQueryTickCount( &liTime);
7001 // First up are there dirty extents in the cache to flush?
7004 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7005 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7009 // The file has been marked as invalid. Dump it
7012 AFSTearDownFcbExtents( Fcb,
7015 else if( ForceFlush ||
7016 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7017 Fcb->Specific.File.ExtentCount) &&
7018 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7019 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7021 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7023 Fcb->OpenReferenceCount == 0)
7026 AFSReleaseExtentsWithFlush( Fcb,
7033 // If there are extents and they haven't been used recently *and*
7034 // are not being used
7038 ( 0 != Fcb->Specific.File.ExtentCount &&
7039 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7040 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7041 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7044 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7045 AFS_TRACE_LEVEL_VERBOSE,
7046 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7047 &Fcb->NPFcb->SectionObjectResource,
7048 PsGetCurrentThread()));
7050 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7056 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7061 if( !NT_SUCCESS( stIoStatus.Status))
7064 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7065 AFS_TRACE_LEVEL_ERROR,
7066 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7067 Fcb->ObjectInformation->FileId.Cell,
7068 Fcb->ObjectInformation->FileId.Volume,
7069 Fcb->ObjectInformation->FileId.Vnode,
7070 Fcb->ObjectInformation->FileId.Unique,
7072 stIoStatus.Information));
7074 ntStatus = stIoStatus.Status;
7078 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7081 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7087 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7088 AFS_TRACE_LEVEL_WARNING,
7089 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7090 Fcb->ObjectInformation->FileId.Cell,
7091 Fcb->ObjectInformation->FileId.Volume,
7092 Fcb->ObjectInformation->FileId.Vnode,
7093 Fcb->ObjectInformation->FileId.Unique));
7095 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7099 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
7102 ntStatus = GetExceptionCode();
7106 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7107 Fcb->ObjectInformation->FileId.Cell,
7108 Fcb->ObjectInformation->FileId.Volume,
7109 Fcb->ObjectInformation->FileId.Vnode,
7110 Fcb->ObjectInformation->FileId.Unique,
7114 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7115 AFS_TRACE_LEVEL_VERBOSE,
7116 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7117 &Fcb->NPFcb->SectionObjectResource,
7118 PsGetCurrentThread()));
7120 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7122 if( Fcb->OpenReferenceCount <= 0)
7126 // Tear em down we'll not be needing them again
7129 AFSTearDownFcbExtents( Fcb,
7136 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7137 AFS_TRACE_LEVEL_VERBOSE,
7138 "AFSCleanupFcb Failed to Acquire Fcb SectionObject lock %p EXCL %08lX\n",
7139 &Fcb->NPFcb->SectionObjectResource,
7140 PsGetCurrentThread()));
7142 ntStatus = STATUS_RETRY;
7155 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7156 IN UNICODE_STRING *NewFileName)
7159 NTSTATUS ntStatus = STATUS_SUCCESS;
7160 WCHAR *pTmpBuffer = NULL;
7165 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7168 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7171 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7173 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7175 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7179 // OK, we need to allocate a new name buffer
7182 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7183 NewFileName->Length,
7184 AFS_NAME_BUFFER_NINE_TAG);
7186 if( pTmpBuffer == NULL)
7189 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7192 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7194 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7196 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7199 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7201 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7202 NewFileName->Buffer,
7203 NewFileName->Length);
7214 AFSReadCacheFile( IN void *ReadBuffer,
7215 IN LARGE_INTEGER *ReadOffset,
7216 IN ULONG RequestedDataLength,
7217 IN OUT PULONG BytesRead)
7220 NTSTATUS ntStatus = STATUS_SUCCESS;
7223 PIO_STACK_LOCATION pIoStackLocation = NULL;
7224 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7225 FILE_OBJECT *pCacheFileObject = NULL;
7230 pCacheFileObject = AFSReferenceCacheFileObject();
7232 if( pCacheFileObject == NULL)
7234 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7237 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7240 // Initialize the event
7243 KeInitializeEvent( &kEvent,
7244 SynchronizationEvent,
7248 // Allocate an irp for this request. This could also come from a
7249 // private pool, for instance.
7252 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7258 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7262 // Build the IRP's main body
7265 pIrp->UserBuffer = ReadBuffer;
7267 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7268 pIrp->RequestorMode = KernelMode;
7269 pIrp->Flags |= IRP_READ_OPERATION;
7272 // Set up the I/O stack location.
7275 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7276 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7277 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7278 pIoStackLocation->FileObject = pCacheFileObject;
7279 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7281 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7284 // Set the completion routine.
7287 IoSetCompletionRoutine( pIrp,
7295 // Send it to the FSD
7298 ntStatus = IoCallDriver( pTargetDeviceObject,
7301 if( NT_SUCCESS( ntStatus))
7308 ntStatus = KeWaitForSingleObject( &kEvent,
7314 if( NT_SUCCESS( ntStatus))
7317 ntStatus = pIrp->IoStatus.Status;
7319 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7325 if( pCacheFileObject != NULL)
7327 AFSReleaseCacheFileObject( pCacheFileObject);
7333 if( pIrp->MdlAddress != NULL)
7336 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7339 MmUnlockPages( pIrp->MdlAddress);
7342 IoFreeMdl( pIrp->MdlAddress);
7345 pIrp->MdlAddress = NULL;
7359 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7364 UNREFERENCED_PARAMETER(Irp);
7365 UNREFERENCED_PARAMETER(DeviceObject);
7366 KEVENT *pEvent = (KEVENT *)Context;
7372 return STATUS_MORE_PROCESSING_REQUIRED;
7376 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7379 BOOLEAN bIsEmpty = FALSE;
7380 AFSDirectoryCB *pDirEntry = NULL;
7385 ASSERT( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY);
7387 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7392 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7395 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7397 while( pDirEntry != NULL)
7400 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7401 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7409 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7414 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7421 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7422 IN AFSDirectoryCB *DirEntry)
7425 NTSTATUS ntStatus = STATUS_SUCCESS;
7430 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7433 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7434 AFS_TRACE_LEVEL_VERBOSE,
7435 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7437 &DirEntry->NameInformation.FileName));
7439 try_return( ntStatus);
7442 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7445 // Remove the entry from the parent tree
7448 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7449 AFS_TRACE_LEVEL_VERBOSE,
7450 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7452 &DirEntry->NameInformation.FileName));
7454 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7457 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7458 AFS_TRACE_LEVEL_VERBOSE,
7459 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7461 &DirEntry->NameInformation.FileName));
7463 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7466 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7470 // From the short name tree
7473 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7474 AFS_TRACE_LEVEL_VERBOSE,
7475 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7477 &DirEntry->NameInformation.FileName));
7479 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7482 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7485 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7486 AFS_TRACE_LEVEL_VERBOSE,
7487 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7489 &DirEntry->NameInformation.FileName));
7491 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7493 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7504 AFSGetAuthenticationId()
7507 LARGE_INTEGER liAuthId = {0,0};
7508 NTSTATUS ntStatus = STATUS_SUCCESS;
7509 PACCESS_TOKEN hToken = NULL;
7510 PTOKEN_STATISTICS pTokenInfo = NULL;
7511 BOOLEAN bCopyOnOpen = FALSE;
7512 BOOLEAN bEffectiveOnly = FALSE;
7513 BOOLEAN bPrimaryToken = FALSE;
7514 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7519 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7522 &stImpersonationLevel);
7527 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7532 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7533 AFS_TRACE_LEVEL_ERROR,
7534 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
7536 try_return( ntStatus);
7539 bPrimaryToken = TRUE;
7542 ntStatus = SeQueryInformationToken( hToken,
7544 (PVOID *)&pTokenInfo);
7546 if( !NT_SUCCESS( ntStatus))
7549 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7550 AFS_TRACE_LEVEL_ERROR,
7551 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
7554 try_return( ntStatus);
7557 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7558 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7560 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7561 AFS_TRACE_LEVEL_VERBOSE,
7562 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7563 liAuthId.QuadPart));
7573 PsDereferenceImpersonationToken( hToken);
7578 PsDereferencePrimaryToken( hToken);
7582 if( pTokenInfo != NULL)
7585 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7593 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7597 UNREFERENCED_PARAMETER(Fcb);
7598 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7600 Fcb->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7603 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7605 Fcb->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7608 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7610 Fcb->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7613 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7615 Fcb->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7618 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7620 Fcb->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7627 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7630 BOOLEAN bIsValid = TRUE;
7632 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7634 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7636 while( pCurrentDirEntry != NULL)
7639 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7643 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7648 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7649 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7652 if( pDirEntry == NULL)
7659 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7662 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
7665 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7667 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7669 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7678 AFSReferenceCacheFileObject()
7681 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7682 FILE_OBJECT *pCacheFileObject = NULL;
7684 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7687 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7689 if( pCacheFileObject != NULL)
7691 ObReferenceObject( pCacheFileObject);
7694 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7696 return pCacheFileObject;
7700 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7703 ASSERT( CacheFileObject != NULL);
7705 ObDereferenceObject( CacheFileObject);
7711 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7714 NTSTATUS ntStatus = STATUS_SUCCESS;
7715 AFSDeviceExt *pControlDevExt = NULL;
7716 ULONG ulTimeIncrement = 0;
7722 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7724 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7726 AFSServerName = LibraryInit->AFSServerName;
7728 AFSMountRootName = LibraryInit->AFSMountRootName;
7730 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7733 // Callbacks in the framework
7736 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7738 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7740 AFSDebugTraceFnc = AFSDbgLogMsg;
7742 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7744 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7746 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
7748 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7750 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7752 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7754 if( LibraryInit->AFSCacheBaseAddress != NULL)
7757 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7759 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7761 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7765 // Initialize some flush parameters
7768 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7770 ulTimeIncrement = KeQueryTimeIncrement();
7772 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7773 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7774 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7775 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7776 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7779 // Initialize the global root entry
7782 ntStatus = AFSInitVolume( NULL,
7783 &LibraryInit->GlobalRootFid,
7784 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
7787 if( !NT_SUCCESS( ntStatus))
7790 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7791 AFS_TRACE_LEVEL_ERROR,
7792 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7795 try_return( ntStatus);
7798 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7801 if( !NT_SUCCESS( ntStatus))
7804 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7805 AFS_TRACE_LEVEL_ERROR,
7806 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7809 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7810 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7812 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7813 AFS_TRACE_LEVEL_VERBOSE,
7814 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7818 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7820 try_return( ntStatus);
7824 // Update the node type code to AFS_ROOT_ALL
7827 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7829 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7832 // Invalidate all known volumes since contact with the service and therefore
7833 // the file server was lost.
7836 AFSInvalidateAllVolumes();
7839 // Drop the locks acquired above
7842 AFSInitVolumeWorker( AFSGlobalRoot);
7844 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7845 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7847 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7848 AFS_TRACE_LEVEL_VERBOSE,
7849 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7853 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7855 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7869 NTSTATUS ntStatus = STATUS_SUCCESS;
7870 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7876 if( AFSGlobalDotDirEntry != NULL)
7879 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
7880 AFS_OBJECT_REFERENCE_GLOBAL);
7882 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7883 AFS_TRACE_LEVEL_VERBOSE,
7884 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7885 AFSGlobalDotDirEntry->ObjectInformation,
7891 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
7894 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7896 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry->NonPaged,
7897 AFS_DIR_ENTRY_NP_TAG);
7899 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry,
7902 AFSGlobalDotDirEntry = NULL;
7905 if( AFSGlobalDotDotDirEntry != NULL)
7908 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
7909 AFS_OBJECT_REFERENCE_GLOBAL);
7911 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7912 AFS_TRACE_LEVEL_VERBOSE,
7913 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7914 AFSGlobalDotDotDirEntry->ObjectInformation,
7920 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
7923 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7925 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry->NonPaged,
7926 AFS_DIR_ENTRY_NP_TAG);
7928 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry,
7931 AFSGlobalDotDotDirEntry = NULL;
7934 if( AFSSpecialShareNames != NULL)
7937 pDirNode = AFSSpecialShareNames;
7939 while( pDirNode != NULL)
7942 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7944 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
7945 AFS_OBJECT_REFERENCE_GLOBAL);
7947 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7948 AFS_TRACE_LEVEL_VERBOSE,
7949 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7950 pDirNode->ObjectInformation,
7956 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
7959 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7961 AFSLibExFreePoolWithTag( pDirNode->NonPaged,
7962 AFS_DIR_ENTRY_NP_TAG);
7964 AFSLibExFreePoolWithTag( pDirNode,
7967 pDirNode = pLastDirNode;
7970 AFSSpecialShareNames = NULL;
7978 AFSDefaultLogMsg( IN ULONG Subsystem,
7984 UNREFERENCED_PARAMETER(Subsystem);
7985 UNREFERENCED_PARAMETER(Level);
7986 NTSTATUS ntStatus = STATUS_SUCCESS;
7988 char chDebugBuffer[ 256];
7993 va_start( va_args, Format);
7995 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8000 if( NT_SUCCESS( ntStatus))
8002 DbgPrint( chDebugBuffer);
8012 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8013 IN ULONG InputBufferLength,
8014 IN AFSStatusInfoCB *StatusInfo,
8015 OUT ULONG *ReturnLength)
8018 NTSTATUS ntStatus = STATUS_SUCCESS;
8019 AFSVolumeCB *pVolumeCB = NULL;
8020 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8021 AFSVolumeCB *pNewVolumeCB = NULL;
8022 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8023 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8024 AFSObjectInfoCB *pObjectInfo = NULL;
8025 ULONGLONG ullIndex = 0;
8026 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8027 AFSNameArrayHdr *pNameArray = NULL;
8028 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8029 AFSDirectoryCB *pNewParentDirEntry = NULL;
8036 // If we are given a FID then look up the entry by that, otherwise
8040 if( GetStatusInfo->FileID.Cell != 0 &&
8041 GetStatusInfo->FileID.Volume != 0 &&
8042 GetStatusInfo->FileID.Vnode != 0 &&
8043 GetStatusInfo->FileID.Unique != 0)
8046 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8049 // Locate the volume node
8052 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8054 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8056 (AFSBTreeEntry **)&pVolumeCB);
8058 if( pVolumeCB != NULL)
8061 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8063 lCount = AFSVolumeIncrement( pVolumeCB,
8064 VolumeReferenceReason);
8066 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8067 AFS_TRACE_LEVEL_VERBOSE,
8068 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
8070 VolumeReferenceReason,
8074 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8076 if( !NT_SUCCESS( ntStatus) ||
8079 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8082 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8085 pObjectInfo = &pVolumeCB->ObjectInformation;
8087 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8090 lCount = AFSObjectInfoIncrement( pObjectInfo,
8091 AFS_OBJECT_REFERENCE_STATUS);
8093 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8094 AFS_TRACE_LEVEL_VERBOSE,
8095 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8099 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8104 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
8107 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8109 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8111 (AFSBTreeEntry **)&pObjectInfo);
8113 if( pObjectInfo != NULL)
8117 // Reference the node so it won't be torn down
8120 lCount = AFSObjectInfoIncrement( pObjectInfo,
8121 AFS_OBJECT_REFERENCE_STATUS);
8123 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8124 AFS_TRACE_LEVEL_VERBOSE,
8125 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8129 KeQueryTickCount( &pObjectInfo->LastAccessCount);
8132 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8134 if( !NT_SUCCESS( ntStatus) ||
8135 pObjectInfo == NULL)
8137 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8144 if( GetStatusInfo->FileNameLength == 0 ||
8145 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8147 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8150 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8151 uniFullPathName.MaximumLength = uniFullPathName.Length;
8153 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8156 // This name should begin with the \afs server so parse it off and check it
8159 FsRtlDissectName( uniFullPathName,
8163 if( RtlCompareUnicodeString( &uniComponentName,
8167 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8168 AFS_TRACE_LEVEL_ERROR,
8169 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8172 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8175 uniFullPathName = uniRemainingPath;
8177 uniParsedName = uniFullPathName;
8183 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8186 if( pNameArray == NULL)
8188 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8191 pVolumeCB = AFSGlobalRoot;
8193 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8196 // Increment the ref count on the volume and dir entry for correct processing below
8199 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8201 lCount = AFSVolumeIncrement( pVolumeCB,
8202 VolumeReferenceReason);
8204 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8205 AFS_TRACE_LEVEL_VERBOSE,
8206 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8208 VolumeReferenceReason,
8211 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8213 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8214 AFS_TRACE_LEVEL_VERBOSE,
8215 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8216 &pParentDirEntry->NameInformation.FileName,
8221 ntStatus = AFSLocateNameEntry( NULL,
8226 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8227 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8231 &NewVolumeReferenceReason,
8232 &pNewParentDirEntry,
8236 if ( pNewVolumeCB != NULL)
8240 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8241 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8242 // the reference on pVolumeCB that was held prior to the call.
8243 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8244 // will be released second.
8247 lCount = AFSVolumeDecrement( pVolumeCB,
8248 VolumeReferenceReason);
8250 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8251 AFS_TRACE_LEVEL_VERBOSE,
8252 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8254 VolumeReferenceReason,
8257 pVolumeCB = pNewVolumeCB;
8259 pNewVolumeCB = NULL;
8261 VolumeReferenceReason = NewVolumeReferenceReason;
8263 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8267 // AFSLocateNameEntry does not alter the reference count of
8268 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8269 // a reference held.
8272 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8274 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8275 AFS_TRACE_LEVEL_VERBOSE,
8276 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8277 &pParentDirEntry->NameInformation.FileName,
8281 pParentDirEntry = pNewParentDirEntry;
8283 pNewParentDirEntry = NULL;
8285 if( !NT_SUCCESS( ntStatus) ||
8286 ntStatus == STATUS_REPARSE)
8291 try_return( ntStatus);
8294 pObjectInfo = pDirectoryEntry->ObjectInformation;
8296 AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
8299 lCount = AFSObjectInfoIncrement( pObjectInfo,
8300 AFS_OBJECT_REFERENCE_STATUS);
8302 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8303 AFS_TRACE_LEVEL_VERBOSE,
8304 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8308 AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
8312 // At this point we have an object info block, return the information
8315 StatusInfo->FileId = pObjectInfo->FileId;
8317 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8319 StatusInfo->Expiration = pObjectInfo->Expiration;
8321 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8323 StatusInfo->FileType = pObjectInfo->FileType;
8325 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8327 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8329 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8331 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8333 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8335 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8337 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8339 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8341 StatusInfo->EaSize = pObjectInfo->EaSize;
8343 StatusInfo->Links = pObjectInfo->Links;
8346 // Return the information length
8349 *ReturnLength = sizeof( AFSStatusInfoCB);
8353 if( pDirectoryEntry != NULL)
8356 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8358 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8359 AFS_TRACE_LEVEL_VERBOSE,
8360 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8361 &pDirectoryEntry->NameInformation.FileName,
8366 ASSERT( lCount >= 0);
8369 if ( pParentDirEntry != NULL)
8372 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8374 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8375 AFS_TRACE_LEVEL_VERBOSE,
8376 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8377 &pParentDirEntry->NameInformation.FileName,
8382 ASSERT( lCount >= 0);
8385 if( pVolumeCB != NULL)
8388 if( pObjectInfo != NULL)
8391 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8394 lCount = AFSObjectInfoDecrement( pObjectInfo,
8395 AFS_OBJECT_REFERENCE_STATUS);
8397 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8398 AFS_TRACE_LEVEL_VERBOSE,
8399 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8403 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8406 lCount = AFSVolumeDecrement( pVolumeCB,
8407 VolumeReferenceReason);
8409 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8410 AFS_TRACE_LEVEL_VERBOSE,
8411 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8413 VolumeReferenceReason,
8417 if( pNameArray != NULL)
8420 AFSFreeNameArray( pNameArray);
8428 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8429 IN UNICODE_STRING *ComponentName)
8432 NTSTATUS ntStatus = STATUS_SUCCESS;
8433 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8434 AFSDirectoryCB *pDirEntry = NULL;
8442 // Search for the entry in the parent
8445 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8446 AFS_TRACE_LEVEL_VERBOSE_2,
8447 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8450 ulCRC = AFSGenerateCRC( ComponentName,
8453 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8456 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8460 if( pDirEntry == NULL)
8464 // Missed so perform a case insensitive lookup
8467 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8468 AFS_TRACE_LEVEL_VERBOSE_2,
8469 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8472 ulCRC = AFSGenerateCRC( ComponentName,
8475 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8479 if( pDirEntry == NULL)
8483 // OK, if this component is a valid short name then try
8484 // a lookup in the short name tree
8487 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8488 RtlIsNameLegalDOS8Dot3( ComponentName,
8493 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8494 AFS_TRACE_LEVEL_VERBOSE_2,
8495 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8498 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8505 if( pDirEntry != NULL)
8507 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8509 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8510 AFS_TRACE_LEVEL_VERBOSE,
8511 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8512 &pDirEntry->NameInformation.FileName,
8517 ASSERT( lCount >= 0);
8520 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8522 if( pDirEntry == NULL)
8525 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8526 AFS_TRACE_LEVEL_VERBOSE_2,
8527 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8529 STATUS_OBJECT_NAME_NOT_FOUND));
8531 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8535 // We have the symlink object but previously failed to process it so return access
8539 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8540 AFS_TRACE_LEVEL_VERBOSE_2,
8541 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8544 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8546 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8548 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8549 AFS_TRACE_LEVEL_VERBOSE,
8550 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8551 &pDirEntry->NameInformation.FileName,
8556 ASSERT( lCount >= 0);
8567 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8568 OUT UNICODE_STRING *ComponentName)
8571 NTSTATUS ntStatus = STATUS_SUCCESS;
8572 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8574 uniFullPathName = *FullPathName;
8579 FsRtlDissectName( uniFullPathName,
8583 if( uniRemainingPath.Length == 0)
8588 uniFullPathName = uniRemainingPath;
8591 if( uniComponentName.Length > 0)
8593 *ComponentName = uniComponentName;
8600 AFSDumpTraceFiles_Default()
8606 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8609 BOOLEAN bIsValidName = TRUE;
8615 while( usIndex < FileName->Length/sizeof( WCHAR))
8618 if( FileName->Buffer[ usIndex] == L':' ||
8619 FileName->Buffer[ usIndex] == L'*' ||
8620 FileName->Buffer[ usIndex] == L'?' ||
8621 FileName->Buffer[ usIndex] == L'"' ||
8622 FileName->Buffer[ usIndex] == L'<' ||
8623 FileName->Buffer[ usIndex] == L'>')
8625 bIsValidName = FALSE;
8633 return bIsValidName;
8637 AFSCreateDefaultSecurityDescriptor()
8640 NTSTATUS ntStatus = STATUS_SUCCESS;
8642 ULONG ulSACLSize = 0;
8643 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8644 ULONG ulACESize = 0;
8645 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8646 ULONG ulSDLength = 0;
8647 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8648 PSID pWorldSID = NULL;
8649 ULONG *pulSubAuthority = NULL;
8650 ULONG ulWorldSIDLEngth = 0;
8655 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8657 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8659 AFS_GENERIC_MEMORY_29_TAG);
8661 if( pWorldSID == NULL)
8663 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8665 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8668 RtlZeroMemory( pWorldSID,
8671 RtlInitializeSid( pWorldSID,
8672 &SeWorldSidAuthority,
8675 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8676 *pulSubAuthority = SECURITY_WORLD_RID;
8678 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8681 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8686 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8688 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8690 AFS_GENERIC_MEMORY_29_TAG);
8695 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8697 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8700 RtlZeroMemory( pACE,
8703 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8704 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8705 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8706 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8708 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8710 SeExports->SeLowMandatorySid);
8712 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8713 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8715 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8717 AFS_GENERIC_MEMORY_29_TAG);
8722 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8724 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8727 ntStatus = RtlCreateAcl( pSACL,
8731 if( !NT_SUCCESS( ntStatus))
8734 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8737 try_return( ntStatus);
8740 ntStatus = RtlAddAce( pSACL,
8744 pACE->Header.AceSize);
8746 if( !NT_SUCCESS( ntStatus))
8749 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8752 try_return( ntStatus);
8756 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8757 sizeof( SECURITY_DESCRIPTOR),
8758 AFS_GENERIC_MEMORY_27_TAG);
8760 if( pSecurityDescr == NULL)
8763 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8765 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8768 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8769 SECURITY_DESCRIPTOR_REVISION);
8771 if( !NT_SUCCESS( ntStatus))
8774 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8777 try_return( ntStatus);
8780 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8782 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8787 if( !NT_SUCCESS( ntStatus))
8790 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8793 try_return( ntStatus);
8798 // Add in the group and owner to the SD
8801 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8803 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8807 if( !NT_SUCCESS( ntStatus))
8810 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8813 try_return( ntStatus);
8817 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8821 if( !NT_SUCCESS( ntStatus))
8824 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8827 try_return( ntStatus);
8830 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8833 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8835 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8838 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)AFSLibExAllocatePoolWithTag( NonPagedPool,
8840 AFS_GENERIC_MEMORY_27_TAG);
8842 if( pRelativeSecurityDescr == NULL)
8845 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8847 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8850 ulSDLength = PAGE_SIZE;
8852 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8853 pRelativeSecurityDescr,
8856 if( !NT_SUCCESS( ntStatus))
8859 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8862 try_return( ntStatus);
8865 AFSDefaultSD = pRelativeSecurityDescr;
8869 if( !NT_SUCCESS( ntStatus))
8872 if( pRelativeSecurityDescr != NULL)
8875 AFSLibExFreePoolWithTag( pRelativeSecurityDescr,
8876 AFS_GENERIC_MEMORY_27_TAG);
8880 if( pSecurityDescr != NULL)
8883 AFSLibExFreePoolWithTag( pSecurityDescr,
8884 AFS_GENERIC_MEMORY_27_TAG);
8890 AFSLibExFreePoolWithTag( pSACL,
8891 AFS_GENERIC_MEMORY_29_TAG);
8897 AFSLibExFreePoolWithTag( pACE,
8898 AFS_GENERIC_MEMORY_29_TAG);
8901 if( pWorldSID != NULL)
8904 AFSLibExFreePoolWithTag( pWorldSID,
8905 AFS_GENERIC_MEMORY_29_TAG);
8913 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8914 OUT UNICODE_STRING *ParentPath)
8917 *ParentPath = *FullFileName;
8920 // If the final character is a \, jump over it
8923 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8925 ParentPath->Length -= sizeof( WCHAR);
8928 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8930 ParentPath->Length -= sizeof( WCHAR);
8934 // And the separator
8937 ParentPath->Length -= sizeof( WCHAR);
8943 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8944 IN AFSObjectInfoCB *ObjectInfo,
8945 IN BOOLEAN WriteAccess,
8946 OUT GUID *AuthGroup)
8949 NTSTATUS ntStatus = STATUS_SUCCESS;
8950 GUID stAuthGroup, stZeroAuthGroup;
8951 BOOLEAN bFoundAuthGroup = FALSE;
8952 AFSCcb *pCcb = NULL;
8958 RtlZeroMemory( &stAuthGroup,
8961 RtlZeroMemory( &stZeroAuthGroup,
8967 if( ObjectInfo != NULL &&
8968 ObjectInfo->Fcb != NULL)
8970 pFcb = ObjectInfo->Fcb;
8977 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8980 pCcb = Fcb->CcbListHead;
8982 while( pCcb != NULL)
8986 pCcb->GrantedAccess & FILE_WRITE_DATA)
8988 RtlCopyMemory( &stAuthGroup,
8992 bFoundAuthGroup = TRUE;
8996 else if( pCcb->GrantedAccess & FILE_READ_DATA)
8999 // At least get the read-only access
9002 RtlCopyMemory( &stAuthGroup,
9006 bFoundAuthGroup = TRUE;
9009 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9012 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9015 if( !bFoundAuthGroup)
9018 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9019 (ULONGLONG)PsGetCurrentThreadId(),
9022 if( RtlCompareMemory( &stZeroAuthGroup,
9024 sizeof( GUID)) == sizeof( GUID))
9027 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9029 try_return( ntStatus = STATUS_ACCESS_DENIED);
9033 RtlCopyMemory( AuthGroup,
9046 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9047 IN ULONG InvalidateReason)
9050 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
9051 NTSTATUS ntStatus = STATUS_SUCCESS;
9054 ULONG ulProcessCount = 0;
9061 switch( InvalidateReason)
9064 case AFS_INVALIDATE_DELETED:
9067 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9068 ObjectInfo->Fcb != NULL)
9071 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9074 ObjectInfo->Links = 0;
9076 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9078 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9083 // Clear out the extents
9084 // And get rid of them (note this involves waiting
9085 // for any writes or reads to the cache to complete)
9088 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9091 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9097 case AFS_INVALIDATE_DATA_VERSION:
9100 LARGE_INTEGER liCurrentOffset = {0,0};
9101 LARGE_INTEGER liFlushLength = {0,0};
9102 ULONG ulFlushLength = 0;
9103 BOOLEAN bLocked = FALSE;
9104 BOOLEAN bExtentsLocked = FALSE;
9105 BOOLEAN bCleanExtents = FALSE;
9107 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9108 ObjectInfo->Fcb != NULL)
9111 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9116 if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
9119 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9120 AFS_TRACE_LEVEL_VERBOSE,
9121 "AFSPerformObjectInvalidation DirectIO Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9122 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9123 PsGetCurrentThread()));
9125 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9128 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9135 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9136 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9142 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9143 AFS_TRACE_LEVEL_WARNING,
9144 "AFSPerformObjectInvalidation DirectIO CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9145 ObjectInfo->FileId.Cell,
9146 ObjectInfo->FileId.Volume,
9147 ObjectInfo->FileId.Vnode,
9148 ObjectInfo->FileId.Unique));
9150 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9155 bCleanExtents = TRUE;
9158 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9161 ntStatus = GetExceptionCode();
9165 "EXCEPTION - AFSPerformObjectInvalidation DirectIO FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9166 ObjectInfo->FileId.Cell,
9167 ObjectInfo->FileId.Volume,
9168 ObjectInfo->FileId.Vnode,
9169 ObjectInfo->FileId.Unique,
9172 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9175 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9176 AFS_TRACE_LEVEL_VERBOSE,
9177 "AFSPerformObjectInvalidation DirectIO Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9178 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9179 PsGetCurrentThread()));
9181 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9186 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9187 AFS_TRACE_LEVEL_VERBOSE,
9188 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9189 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9190 PsGetCurrentThread()));
9192 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9195 bExtentsLocked = TRUE;
9198 // There are several possibilities here:
9200 // 0. If there are no extents or all of the extents are dirty, do nothing.
9202 // 1. There could be nothing dirty and an open reference count of zero
9203 // in which case we can just tear down all of the extents without
9204 // holding any resources.
9206 // 2. There could be nothing dirty and a non-zero open reference count
9207 // in which case we can issue a CcPurge against the entire file
9208 // while holding just the Fcb Resource.
9210 // 3. There can be dirty extents in which case we need to identify
9211 // the non-dirty ranges and then perform a CcPurge on just the
9212 // non-dirty ranges while holding just the Fcb Resource.
9215 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9218 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9221 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9223 bExtentsLocked = FALSE;
9225 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9228 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9232 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9238 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9239 AFS_TRACE_LEVEL_VERBOSE,
9240 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9241 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9242 PsGetCurrentThread()));
9244 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9247 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9254 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9255 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9261 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9262 AFS_TRACE_LEVEL_WARNING,
9263 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9264 ObjectInfo->FileId.Cell,
9265 ObjectInfo->FileId.Volume,
9266 ObjectInfo->FileId.Vnode,
9267 ObjectInfo->FileId.Unique));
9269 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9274 bCleanExtents = TRUE;
9277 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9280 ntStatus = GetExceptionCode();
9284 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9285 ObjectInfo->FileId.Cell,
9286 ObjectInfo->FileId.Volume,
9287 ObjectInfo->FileId.Vnode,
9288 ObjectInfo->FileId.Unique,
9291 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9294 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9295 AFS_TRACE_LEVEL_VERBOSE,
9296 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9297 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9298 PsGetCurrentThread()));
9300 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9306 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9308 bExtentsLocked = FALSE;
9310 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9311 AFS_TRACE_LEVEL_VERBOSE,
9312 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9313 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9314 PsGetCurrentThread()));
9316 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9319 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9324 // Must build a list of non-dirty ranges from the beginning of the file
9325 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9326 // ranges. In all but the most extreme random data write scenario there will
9327 // be significantly fewer.
9329 // For each range we need offset and size.
9332 AFSByteRange * ByteRangeList = NULL;
9333 ULONG ulByteRangeCount = 0;
9335 BOOLEAN bPurgeOnClose = FALSE;
9340 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9343 if ( ByteRangeList != NULL ||
9344 ulByteRangeCount == 0)
9347 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9354 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9356 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9357 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9358 &ByteRangeList[ulIndex].FileOffset,
9363 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9364 AFS_TRACE_LEVEL_WARNING,
9365 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9366 ObjectInfo->FileId.Cell,
9367 ObjectInfo->FileId.Volume,
9368 ObjectInfo->FileId.Vnode,
9369 ObjectInfo->FileId.Unique));
9371 bPurgeOnClose = TRUE;
9376 bCleanExtents = TRUE;
9379 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9381 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9383 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9390 // We couldn't allocate the memory to build the purge list
9391 // so just walk the extent list while holding the ExtentsList Resource.
9392 // This could deadlock but we do not have much choice.
9395 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9397 bExtentsLocked = TRUE;
9399 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9403 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9407 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9409 while( ulProcessCount < ulCount)
9411 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9413 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9415 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9416 &pEntry->FileOffset,
9421 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9422 AFS_TRACE_LEVEL_WARNING,
9423 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9424 ObjectInfo->FileId.Cell,
9425 ObjectInfo->FileId.Volume,
9426 ObjectInfo->FileId.Vnode,
9427 ObjectInfo->FileId.Unique));
9429 bPurgeOnClose = TRUE;
9434 bCleanExtents = TRUE;
9438 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9441 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9443 while( liFlushLength.QuadPart > 0)
9446 if( liFlushLength.QuadPart > 512 * 1024000)
9448 ulFlushLength = 512 * 1024000;
9452 ulFlushLength = liFlushLength.LowPart;
9455 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9461 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9462 AFS_TRACE_LEVEL_WARNING,
9463 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9464 ObjectInfo->FileId.Cell,
9465 ObjectInfo->FileId.Volume,
9466 ObjectInfo->FileId.Vnode,
9467 ObjectInfo->FileId.Unique));
9469 bPurgeOnClose = TRUE;
9474 bCleanExtents = TRUE;
9477 liFlushLength.QuadPart -= ulFlushLength;
9481 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9489 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9495 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9496 AFS_TRACE_LEVEL_WARNING,
9497 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9498 ObjectInfo->FileId.Cell,
9499 ObjectInfo->FileId.Volume,
9500 ObjectInfo->FileId.Vnode,
9501 ObjectInfo->FileId.Unique));
9503 bPurgeOnClose = TRUE;
9508 bCleanExtents = TRUE;
9515 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9519 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9522 ntStatus = GetExceptionCode();
9526 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9527 ObjectInfo->FileId.Cell,
9528 ObjectInfo->FileId.Volume,
9529 ObjectInfo->FileId.Vnode,
9530 ObjectInfo->FileId.Unique,
9534 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9535 AFS_TRACE_LEVEL_VERBOSE,
9536 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9537 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9538 PsGetCurrentThread()));
9540 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9544 if ( bExtentsLocked)
9547 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9554 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9560 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9570 // Destroy the reference passed in by the caller to AFSInvalidateObject
9571 // or AFSQueueInvalidateObject
9574 AFSAcquireShared( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
9577 lCount = AFSObjectInfoDecrement( ObjectInfo,
9578 AFS_OBJECT_REFERENCE_INVALIDATION);
9580 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9581 AFS_TRACE_LEVEL_VERBOSE,
9582 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",
9586 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
9593 AFSIgnoreReparsePointToFile( void)
9595 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
9596 BOOLEAN bIgnoreReparsePoint;
9600 bIgnoreReparsePoint = BooleanFlagOn( pDeviceExt->Specific.RDR.ReparsePointPolicy,
9601 AFS_REPARSE_POINT_TO_FILE_AS_FILE);
9604 return bIgnoreReparsePoint;