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 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1879 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1884 if( !NT_SUCCESS( stIoStatus.Status))
1887 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1888 AFS_TRACE_LEVEL_ERROR,
1889 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1890 (*ppObjectInfo)->FileId.Cell,
1891 (*ppObjectInfo)->FileId.Volume,
1892 (*ppObjectInfo)->FileId.Vnode,
1893 (*ppObjectInfo)->FileId.Unique,
1895 stIoStatus.Information));
1897 ntStatus = stIoStatus.Status;
1901 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1904 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1910 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1911 AFS_TRACE_LEVEL_WARNING,
1912 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1913 (*ppObjectInfo)->FileId.Cell,
1914 (*ppObjectInfo)->FileId.Volume,
1915 (*ppObjectInfo)->FileId.Vnode,
1916 (*ppObjectInfo)->FileId.Unique));
1918 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1922 __except( EXCEPTION_EXECUTE_HANDLER)
1925 ntStatus = GetExceptionCode();
1929 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1930 (*ppObjectInfo)->FileId.Cell,
1931 (*ppObjectInfo)->FileId.Volume,
1932 (*ppObjectInfo)->FileId.Vnode,
1933 (*ppObjectInfo)->FileId.Unique,
1936 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1939 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1942 // Clear out the extents
1943 // Get rid of them (note this involves waiting
1944 // for any writes or reads to the cache to complete)
1947 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1951 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1954 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1957 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1958 AFS_TRACE_LEVEL_VERBOSE,
1959 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1960 (*ppObjectInfo)->FileId.Cell,
1961 (*ppObjectInfo)->FileId.Volume,
1962 (*ppObjectInfo)->FileId.Vnode,
1963 (*ppObjectInfo)->FileId.Unique));
1965 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1968 // Fall through to the default processing
1974 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1976 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1980 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1983 if( Reason == AFS_INVALIDATE_CREDS)
1985 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1988 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1990 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1994 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1997 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
2000 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
2003 FILE_ACTION_MODIFIED);
2005 else if ( pParentObjectInfo != NULL)
2008 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2011 FILE_ACTION_MODIFIED);
2015 // Indicate this node requires re-evaluation for the remaining reasons
2018 (*ppObjectInfo)->Expiration.QuadPart = 0;
2020 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2021 AFS_TRACE_LEVEL_VERBOSE,
2022 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2023 (*ppObjectInfo)->FileId.Cell,
2024 (*ppObjectInfo)->FileId.Volume,
2025 (*ppObjectInfo)->FileId.Vnode,
2026 (*ppObjectInfo)->FileId.Unique));
2028 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
2030 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2031 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
2032 ( Reason == AFS_INVALIDATE_CALLBACK ||
2033 Reason == AFS_INVALIDATE_EXPIRED))
2035 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
2036 AFS_INVALIDATE_DATA_VERSION)))
2039 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
2049 if ( pParentObjectInfo != NULL)
2052 AFSReleaseObjectInfo( &pParentObjectInfo);
2059 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
2062 NTSTATUS ntStatus = STATUS_SUCCESS;
2063 AFSVolumeCB *pVolumeCB = NULL;
2064 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2065 ULONGLONG ullIndex = 0;
2066 AFSObjectInfoCB *pObjectInfo = NULL;
2072 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2073 AFS_TRACE_LEVEL_VERBOSE,
2074 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
2075 InvalidateCB->FileID.Cell,
2076 InvalidateCB->FileID.Volume,
2077 InvalidateCB->FileID.Vnode,
2078 InvalidateCB->FileID.Unique,
2079 InvalidateCB->FileType,
2080 InvalidateCB->WholeVolume,
2081 InvalidateCB->Reason));
2084 // Need to locate the Fcb for the directory to purge
2087 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2088 AFS_TRACE_LEVEL_VERBOSE,
2089 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2090 &pDevExt->Specific.RDR.VolumeTreeLock,
2091 PsGetCurrentThread()));
2094 // Starve any exclusive waiters on this paticular call
2097 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2100 // Locate the volume node
2103 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2105 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2107 (AFSBTreeEntry **)&pVolumeCB);
2109 if( pVolumeCB != NULL)
2112 lCount = AFSVolumeIncrement( pVolumeCB,
2113 AFS_VOLUME_REFERENCE_INVALIDATE);
2115 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2116 AFS_TRACE_LEVEL_VERBOSE,
2117 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2122 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2124 if( !NT_SUCCESS( ntStatus) ||
2128 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2129 AFS_TRACE_LEVEL_WARNING,
2130 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2131 InvalidateCB->FileID.Cell,
2132 InvalidateCB->FileID.Volume,
2133 InvalidateCB->FileID.Vnode,
2134 InvalidateCB->FileID.Unique,
2137 try_return( ntStatus = STATUS_SUCCESS);
2141 // If this is a whole volume invalidation then go do it now
2144 if( InvalidateCB->WholeVolume)
2147 ntStatus = AFSInvalidateVolume( pVolumeCB,
2148 InvalidateCB->Reason);
2150 try_return( ntStatus);
2153 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
2156 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2159 pObjectInfo = &pVolumeCB->ObjectInformation;
2164 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2166 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2168 (AFSBTreeEntry **)&pObjectInfo);
2171 if( pObjectInfo != NULL)
2175 // Reference the node so it won't be torn down
2178 lCount = AFSObjectInfoIncrement( pObjectInfo,
2179 AFS_OBJECT_REFERENCE_INVALIDATION);
2181 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2182 AFS_TRACE_LEVEL_VERBOSE,
2183 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2188 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2190 if( !NT_SUCCESS( ntStatus) ||
2191 pObjectInfo == NULL)
2194 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2195 AFS_TRACE_LEVEL_VERBOSE,
2196 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2197 InvalidateCB->FileID.Cell,
2198 InvalidateCB->FileID.Volume,
2199 InvalidateCB->FileID.Vnode,
2200 InvalidateCB->FileID.Unique,
2203 try_return( ntStatus = STATUS_SUCCESS);
2206 AFSInvalidateObject( &pObjectInfo,
2207 InvalidateCB->Reason);
2211 if( pObjectInfo != NULL)
2214 lCount = AFSObjectInfoDecrement( pObjectInfo,
2215 AFS_OBJECT_REFERENCE_INVALIDATION);
2217 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2218 AFS_TRACE_LEVEL_VERBOSE,
2219 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2224 if ( pVolumeCB != NULL)
2227 lCount = AFSVolumeDecrement( pVolumeCB,
2228 AFS_VOLUME_REFERENCE_INVALIDATE);
2230 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2231 AFS_TRACE_LEVEL_VERBOSE,
2232 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2242 AFSIsChildOfParent( IN AFSFcb *Dcb,
2246 BOOLEAN bIsChild = FALSE;
2247 AFSFcb *pCurrentFcb = Fcb;
2248 AFSObjectInfoCB * pParentObjectInfo = NULL;
2250 while( pCurrentFcb != NULL)
2253 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2254 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2262 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2263 &pCurrentFcb->ObjectInformation->ParentFileId,
2266 if ( pParentObjectInfo != NULL)
2269 pCurrentFcb = pParentObjectInfo->Fcb;
2271 AFSReleaseObjectInfo( &pParentObjectInfo);
2285 AFSCreateHighIndex( IN AFSFileID *FileID)
2288 ULONGLONG ullIndex = 0;
2290 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2297 AFSCreateLowIndex( IN AFSFileID *FileID)
2300 ULONGLONG ullIndex = 0;
2302 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2308 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2309 IN ACCESS_MASK GrantedAccess,
2310 IN BOOLEAN DirectoryEntry)
2313 BOOLEAN bAccessGranted = TRUE;
2316 // Check if we are asking for read/write and granted only read only
2317 // NOTE: There will be more checks here
2320 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2322 AFSCheckForReadOnlyAccess( GrantedAccess,
2326 bAccessGranted = FALSE;
2329 return bAccessGranted;
2333 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2336 NTSTATUS ntStatus = STATUS_SUCCESS;
2337 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2343 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2345 if( AFSGlobalRoot == NULL)
2352 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2355 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2362 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2369 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2370 IN UNICODE_STRING *SubstituteName,
2371 IN ULONG StringIndex)
2374 NTSTATUS ntStatus = STATUS_SUCCESS;
2375 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2376 AFSSysNameCB *pSysName = NULL;
2377 ERESOURCE *pSysNameLock = NULL;
2380 UNICODE_STRING uniSysName;
2387 if( IoIs32bitProcess( NULL))
2390 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2392 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2397 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2399 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2403 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2405 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2409 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2410 AFS_TRACE_LEVEL_VERBOSE,
2411 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2413 PsGetCurrentThread()));
2415 AFSAcquireShared( pSysNameLock,
2419 // Find where we are in the list
2422 while( pSysName != NULL &&
2423 ulIndex < StringIndex)
2426 pSysName = pSysName->fLink;
2431 if( pSysName == NULL)
2434 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2435 AFS_TRACE_LEVEL_VERBOSE_2,
2436 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2438 STATUS_OBJECT_NAME_NOT_FOUND));
2440 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2443 RtlInitUnicodeString( &uniSysName,
2446 // If it is a full component of @SYS then just substitue the
2450 if( RtlCompareUnicodeString( &uniSysName,
2455 SubstituteName->Length = pSysName->SysName.Length;
2456 SubstituteName->MaximumLength = SubstituteName->Length;
2458 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2459 SubstituteName->Length,
2460 AFS_SUBST_BUFFER_TAG);
2462 if( SubstituteName->Buffer == NULL)
2465 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2468 RtlCopyMemory( SubstituteName->Buffer,
2469 pSysName->SysName.Buffer,
2470 pSysName->SysName.Length);
2477 while( ComponentName->Buffer[ usIndex] != L'@')
2483 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2484 SubstituteName->MaximumLength = SubstituteName->Length;
2486 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2487 SubstituteName->Length,
2488 AFS_SUBST_BUFFER_TAG);
2490 if( SubstituteName->Buffer == NULL)
2493 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2496 RtlCopyMemory( SubstituteName->Buffer,
2497 ComponentName->Buffer,
2498 usIndex * sizeof( WCHAR));
2500 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2501 pSysName->SysName.Buffer,
2502 pSysName->SysName.Length);
2507 AFSReleaseResource( pSysNameLock);
2514 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2515 IN OUT UNICODE_STRING *ComponentName,
2516 IN UNICODE_STRING *SubstituteName,
2517 IN OUT UNICODE_STRING *RemainingPath,
2518 IN BOOLEAN FreePathName)
2521 NTSTATUS ntStatus = STATUS_SUCCESS;
2522 UNICODE_STRING uniPathName;
2523 USHORT usPrefixNameLen = 0;
2524 SHORT sNameLenDelta = 0;
2530 // If the passed in name can handle the additional length
2531 // then just moves things around
2534 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2536 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2538 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2541 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2544 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2545 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2546 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2549 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2550 SubstituteName->Buffer,
2551 SubstituteName->Length);
2553 FullPathName->Length += sNameLenDelta;
2555 ComponentName->Length += sNameLenDelta;
2557 ComponentName->MaximumLength = ComponentName->Length;
2559 if ( RemainingPath->Buffer)
2562 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2565 try_return( ntStatus);
2569 // Need to re-allocate the buffer
2572 uniPathName.Length = FullPathName->Length -
2573 ComponentName->Length +
2574 SubstituteName->Length;
2576 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2578 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2579 uniPathName.MaximumLength,
2580 AFS_NAME_BUFFER_FOUR_TAG);
2582 if( uniPathName.Buffer == NULL)
2585 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2588 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2590 usPrefixNameLen *= sizeof( WCHAR);
2592 RtlZeroMemory( uniPathName.Buffer,
2593 uniPathName.MaximumLength);
2595 RtlCopyMemory( uniPathName.Buffer,
2596 FullPathName->Buffer,
2599 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2600 SubstituteName->Buffer,
2601 SubstituteName->Length);
2603 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2606 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2607 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2608 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2611 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2613 ComponentName->Length += sNameLenDelta;
2615 ComponentName->MaximumLength = ComponentName->Length;
2617 if ( RemainingPath->Buffer)
2620 RemainingPath->Buffer = uniPathName.Buffer
2621 + (RemainingPath->Buffer - FullPathName->Buffer)
2622 + sNameLenDelta/sizeof( WCHAR);
2627 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2630 *FullPathName = uniPathName;
2641 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2645 NTSTATUS ntStatus = STATUS_SUCCESS;
2646 AFSObjectInfoCB *pCurrentObject = NULL;
2647 AFSObjectInfoCB *pNextObject = NULL;
2653 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2654 AFS_TRACE_LEVEL_VERBOSE,
2655 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2656 VolumeCB->ObjectInformation.FileId.Cell,
2657 VolumeCB->ObjectInformation.FileId.Volume,
2658 VolumeCB->ObjectInformation.FileId.Vnode,
2659 VolumeCB->ObjectInformation.FileId.Unique,
2663 // Depending on the reason for invalidation then perform work on the node
2669 case AFS_INVALIDATE_DELETED:
2673 // Mark this volume as invalid
2676 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2678 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2684 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2688 // Invalidate the volume root directory
2691 pCurrentObject = &VolumeCB->ObjectInformation;
2693 if ( pCurrentObject )
2696 lCount = AFSObjectInfoIncrement( pCurrentObject,
2697 AFS_OBJECT_REFERENCE_INVALIDATION);
2699 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2700 AFS_TRACE_LEVEL_VERBOSE,
2701 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2705 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2707 AFSInvalidateObject( &pCurrentObject,
2710 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2713 if ( pCurrentObject)
2716 lCount = AFSObjectInfoDecrement( pCurrentObject,
2717 AFS_OBJECT_REFERENCE_INVALIDATION);
2719 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2720 AFS_TRACE_LEVEL_VERBOSE,
2721 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2728 // Apply invalidation to all other volume objects
2731 pCurrentObject = VolumeCB->ObjectInfoListHead;
2733 if ( pCurrentObject)
2737 // Reference the node so it won't be torn down
2740 lCount = AFSObjectInfoIncrement( pCurrentObject,
2741 AFS_OBJECT_REFERENCE_INVALIDATION);
2743 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2744 AFS_TRACE_LEVEL_VERBOSE,
2745 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2750 while( pCurrentObject != NULL)
2753 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2759 // Reference the node so it won't be torn down
2762 lCount = AFSObjectInfoIncrement( pNextObject,
2763 AFS_OBJECT_REFERENCE_INVALIDATION);
2765 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2766 AFS_TRACE_LEVEL_VERBOSE,
2767 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2772 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2774 AFSInvalidateObject( &pCurrentObject,
2777 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2780 if ( pCurrentObject )
2783 lCount = AFSObjectInfoDecrement( pCurrentObject,
2784 AFS_OBJECT_REFERENCE_INVALIDATION);
2786 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2787 AFS_TRACE_LEVEL_VERBOSE,
2788 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2793 pCurrentObject = pNextObject;
2796 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2803 AFSInvalidateAllVolumes( VOID)
2805 AFSVolumeCB *pVolumeCB = NULL;
2806 AFSVolumeCB *pNextVolumeCB = NULL;
2807 AFSDeviceExt *pRDRDeviceExt = NULL;
2810 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2812 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2813 AFS_TRACE_LEVEL_VERBOSE,
2814 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2815 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2816 PsGetCurrentThread()));
2818 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2821 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2826 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2827 AFS_TRACE_LEVEL_VERBOSE,
2828 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2829 pVolumeCB->ObjectInfoTree.TreeLock,
2830 PsGetCurrentThread()));
2832 lCount = AFSVolumeIncrement( pVolumeCB,
2833 AFS_VOLUME_REFERENCE_INVALIDATE);
2835 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2836 AFS_TRACE_LEVEL_VERBOSE,
2837 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2842 while( pVolumeCB != NULL)
2845 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2850 lCount = AFSVolumeIncrement( pNextVolumeCB,
2851 AFS_VOLUME_REFERENCE_INVALIDATE);
2853 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2854 AFS_TRACE_LEVEL_VERBOSE,
2855 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2860 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2862 // do I need to hold the volume lock here?
2864 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2866 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2869 lCount = AFSVolumeDecrement( pVolumeCB,
2870 AFS_VOLUME_REFERENCE_INVALIDATE);
2872 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2873 AFS_TRACE_LEVEL_VERBOSE,
2874 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2878 pVolumeCB = pNextVolumeCB;
2881 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2885 AFSVerifyEntry( IN GUID *AuthGroup,
2886 IN AFSDirectoryCB *DirEntry,
2887 IN BOOLEAN bFollowMountPoint)
2890 NTSTATUS ntStatus = STATUS_SUCCESS;
2891 AFSDirEnumEntry *pDirEnumEntry = NULL;
2892 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2893 IO_STATUS_BLOCK stIoStatus;
2898 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2899 AFS_TRACE_LEVEL_VERBOSE_2,
2900 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2901 &DirEntry->NameInformation.FileName,
2902 pObjectInfo->FileId.Cell,
2903 pObjectInfo->FileId.Volume,
2904 pObjectInfo->FileId.Vnode,
2905 pObjectInfo->FileId.Unique));
2907 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2909 bFollowMountPoint ? FALSE : TRUE,
2912 if( !NT_SUCCESS( ntStatus))
2915 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2916 AFS_TRACE_LEVEL_ERROR,
2917 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2918 &DirEntry->NameInformation.FileName,
2919 pObjectInfo->FileId.Cell,
2920 pObjectInfo->FileId.Volume,
2921 pObjectInfo->FileId.Vnode,
2922 pObjectInfo->FileId.Unique,
2925 try_return( ntStatus);
2929 // Check the data version of the file
2932 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2934 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2937 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2938 AFS_TRACE_LEVEL_VERBOSE,
2939 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2940 pObjectInfo->DataVersion.QuadPart,
2941 &DirEntry->NameInformation.FileName,
2942 pObjectInfo->FileId.Cell,
2943 pObjectInfo->FileId.Volume,
2944 pObjectInfo->FileId.Vnode,
2945 pObjectInfo->FileId.Unique));
2948 // We are ok, just get out
2951 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2953 try_return( ntStatus = STATUS_SUCCESS);
2958 // New data version so we will need to process the node based on the type
2961 switch( pDirEnumEntry->FileType)
2964 case AFS_FILE_TYPE_MOUNTPOINT:
2968 // For a mount point we need to ensure the target is the same
2971 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2972 &pDirEnumEntry->TargetFileId))
2978 // Update the metadata for the entry
2981 ntStatus = AFSUpdateMetaData( DirEntry,
2984 if( NT_SUCCESS( ntStatus))
2987 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2993 case AFS_FILE_TYPE_SYMLINK:
2997 // Update the metadata for the entry
3000 ntStatus = AFSUpdateMetaData( DirEntry,
3003 if( NT_SUCCESS( ntStatus))
3006 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3012 case AFS_FILE_TYPE_FILE:
3014 FILE_OBJECT * pCCFileObject = NULL;
3015 BOOLEAN bPurgeExtents = FALSE;
3017 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3020 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3021 AFS_TRACE_LEVEL_VERBOSE,
3022 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
3023 &DirEntry->NameInformation.FileName,
3024 pObjectInfo->FileId.Cell,
3025 pObjectInfo->FileId.Volume,
3026 pObjectInfo->FileId.Vnode,
3027 pObjectInfo->FileId.Unique,
3028 pObjectInfo->DataVersion.LowPart,
3029 pDirEnumEntry->DataVersion.LowPart));
3031 bPurgeExtents = TRUE;
3034 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3037 bPurgeExtents = TRUE;
3039 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3040 AFS_TRACE_LEVEL_VERBOSE,
3041 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3042 &DirEntry->NameInformation.FileName,
3043 pObjectInfo->FileId.Cell,
3044 pObjectInfo->FileId.Volume,
3045 pObjectInfo->FileId.Vnode,
3046 pObjectInfo->FileId.Unique));
3048 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3051 if( pObjectInfo->Fcb != NULL)
3054 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3055 AFS_TRACE_LEVEL_VERBOSE,
3056 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3057 &DirEntry->NameInformation.FileName,
3058 pObjectInfo->FileId.Cell,
3059 pObjectInfo->FileId.Volume,
3060 pObjectInfo->FileId.Vnode,
3061 pObjectInfo->FileId.Unique));
3063 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3069 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3074 if( !NT_SUCCESS( stIoStatus.Status))
3077 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3078 AFS_TRACE_LEVEL_ERROR,
3079 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3080 &DirEntry->NameInformation.FileName,
3081 pObjectInfo->FileId.Cell,
3082 pObjectInfo->FileId.Volume,
3083 pObjectInfo->FileId.Vnode,
3084 pObjectInfo->FileId.Unique,
3086 stIoStatus.Information));
3088 ntStatus = stIoStatus.Status;
3091 if ( bPurgeExtents &&
3092 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3095 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3101 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3102 AFS_TRACE_LEVEL_WARNING,
3103 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3104 &DirEntry->NameInformation.FileName,
3105 pObjectInfo->FileId.Cell,
3106 pObjectInfo->FileId.Volume,
3107 pObjectInfo->FileId.Vnode,
3108 pObjectInfo->FileId.Unique));
3110 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3114 __except( EXCEPTION_EXECUTE_HANDLER)
3116 ntStatus = GetExceptionCode();
3120 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3121 &DirEntry->NameInformation.FileName,
3122 pObjectInfo->FileId.Cell,
3123 pObjectInfo->FileId.Volume,
3124 pObjectInfo->FileId.Vnode,
3125 pObjectInfo->FileId.Unique,
3128 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3131 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3135 AFSFlushExtents( pObjectInfo->Fcb,
3140 // Reacquire the Fcb to purge the cache
3143 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3144 AFS_TRACE_LEVEL_VERBOSE,
3145 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3146 &pObjectInfo->Fcb->NPFcb->Resource,
3147 PsGetCurrentThread()));
3149 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3153 // Update the metadata for the entry
3156 ntStatus = AFSUpdateMetaData( DirEntry,
3159 if( !NT_SUCCESS( ntStatus))
3162 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3163 AFS_TRACE_LEVEL_ERROR,
3164 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3165 &DirEntry->NameInformation.FileName,
3166 pObjectInfo->FileId.Cell,
3167 pObjectInfo->FileId.Volume,
3168 pObjectInfo->FileId.Vnode,
3169 pObjectInfo->FileId.Unique,
3176 // Update file sizes
3179 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3180 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3181 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3183 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3184 AFS_TRACE_LEVEL_VERBOSE,
3185 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3186 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3187 PsGetCurrentThread()));
3189 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3195 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3197 if ( pCCFileObject != NULL)
3199 CcSetFileSizes( pCCFileObject,
3200 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3203 __except( EXCEPTION_EXECUTE_HANDLER)
3206 ntStatus = GetExceptionCode();
3210 "EXCEPTION - AFSVerifyEntry CcSetFileSized failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3211 pObjectInfo->FileId.Cell,
3212 pObjectInfo->FileId.Volume,
3213 pObjectInfo->FileId.Vnode,
3214 pObjectInfo->FileId.Unique,
3218 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3219 AFS_TRACE_LEVEL_VERBOSE,
3220 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3221 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3222 PsGetCurrentThread()));
3224 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3226 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3232 // Update the metadata for the entry
3235 ntStatus = AFSUpdateMetaData( DirEntry,
3238 if( !NT_SUCCESS( ntStatus))
3241 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3242 AFS_TRACE_LEVEL_ERROR,
3243 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3244 &DirEntry->NameInformation.FileName,
3245 pObjectInfo->FileId.Cell,
3246 pObjectInfo->FileId.Volume,
3247 pObjectInfo->FileId.Vnode,
3248 pObjectInfo->FileId.Unique,
3254 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3255 AFS_TRACE_LEVEL_WARNING,
3256 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3257 &DirEntry->NameInformation.FileName,
3258 pObjectInfo->FileId.Cell,
3259 pObjectInfo->FileId.Volume,
3260 pObjectInfo->FileId.Vnode,
3261 pObjectInfo->FileId.Unique));
3264 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3269 case AFS_FILE_TYPE_DIRECTORY:
3273 // For a directory or root entry flush the content of
3274 // the directory enumeration.
3277 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3280 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3281 AFS_TRACE_LEVEL_VERBOSE_2,
3282 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3283 &DirEntry->NameInformation.FileName,
3284 pObjectInfo->FileId.Cell,
3285 pObjectInfo->FileId.Volume,
3286 pObjectInfo->FileId.Vnode,
3287 pObjectInfo->FileId.Unique));
3289 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3292 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3295 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3297 if ( !NT_SUCCESS( ntStatus))
3300 try_return( ntStatus);
3305 // Update the metadata for the entry
3308 ntStatus = AFSUpdateMetaData( DirEntry,
3311 if( NT_SUCCESS( ntStatus))
3314 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3320 case AFS_FILE_TYPE_DFSLINK:
3323 UNICODE_STRING uniTargetName;
3326 // For a DFS link need to check the target name has not changed
3329 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3331 uniTargetName.MaximumLength = uniTargetName.Length;
3333 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3335 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3338 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3339 RtlCompareUnicodeString( &uniTargetName,
3340 &DirEntry->NameInformation.TargetName,
3345 // Update the target name
3348 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3350 uniTargetName.Buffer,
3351 uniTargetName.Length);
3353 if( !NT_SUCCESS( ntStatus))
3356 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3362 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3365 // Update the metadata for the entry
3368 ntStatus = AFSUpdateMetaData( DirEntry,
3371 if( NT_SUCCESS( ntStatus))
3374 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3382 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3383 AFS_TRACE_LEVEL_WARNING,
3384 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3385 pObjectInfo->FileType,
3386 &DirEntry->NameInformation.FileName,
3387 pObjectInfo->FileId.Cell,
3388 pObjectInfo->FileId.Volume,
3389 pObjectInfo->FileId.Vnode,
3390 pObjectInfo->FileId.Unique));
3397 if( pDirEnumEntry != NULL)
3400 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3408 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3411 NTSTATUS ntStatus = STATUS_SUCCESS;
3412 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3413 ULONGLONG ullIndex = 0;
3414 AFSVolumeCB *pVolumeCB = NULL;
3420 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3421 AFS_TRACE_LEVEL_VERBOSE,
3422 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3423 VolumeStatus->Online,
3424 VolumeStatus->FileID.Cell,
3425 VolumeStatus->FileID.Volume));
3428 // Need to locate the Fcb for the directory to purge
3431 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3432 AFS_TRACE_LEVEL_VERBOSE,
3433 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3434 &pDevExt->Specific.RDR.VolumeTreeLock,
3435 PsGetCurrentThread()));
3437 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3440 // Locate the volume node
3443 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3445 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3447 (AFSBTreeEntry **)&pVolumeCB);
3449 if( pVolumeCB != NULL)
3452 lCount = AFSVolumeIncrement( pVolumeCB,
3453 AFS_VOLUME_REFERENCE_INVALIDATE);
3455 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3456 AFS_TRACE_LEVEL_VERBOSE,
3457 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3461 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3464 // Set the volume state accordingly
3467 if( VolumeStatus->Online)
3470 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3475 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3484 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3487 NTSTATUS ntStatus = STATUS_SUCCESS;
3492 if( AFSGlobalRoot == NULL)
3495 try_return( ntStatus);
3498 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3502 // Set the network state according to the information
3505 if( NetworkStatus->Online)
3508 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3513 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3516 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3527 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3531 NTSTATUS ntStatus = STATUS_SUCCESS;
3532 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3533 BOOLEAN bAcquiredLock = FALSE;
3534 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3539 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3540 AFS_TRACE_LEVEL_VERBOSE,
3541 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3542 ObjectInfo->FileId.Cell,
3543 ObjectInfo->FileId.Volume,
3544 ObjectInfo->FileId.Vnode,
3545 ObjectInfo->FileId.Unique));
3547 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3550 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3551 AFS_TRACE_LEVEL_VERBOSE,
3552 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3553 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3554 PsGetCurrentThread()));
3556 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3559 bAcquiredLock = TRUE;
3563 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3566 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3567 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3570 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3571 AFS_TRACE_LEVEL_ERROR,
3572 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3573 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3574 ObjectInfo->FileId.Cell,
3575 ObjectInfo->FileId.Volume,
3576 ObjectInfo->FileId.Vnode,
3577 ObjectInfo->FileId.Unique));
3581 // Reset the directory list information by clearing all valid entries
3584 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3586 while( pCurrentDirEntry != NULL)
3589 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3591 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3595 // If this entry has been deleted then process it here
3598 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3599 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3600 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3603 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3604 AFS_TRACE_LEVEL_VERBOSE,
3605 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3607 &pCurrentDirEntry->NameInformation.FileName));
3609 AFSDeleteDirEntry( ObjectInfo,
3615 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3617 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3618 AFS_TRACE_LEVEL_VERBOSE,
3619 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3621 pCurrentDirEntry->DirOpenReferenceCount));
3624 // We pull the short name from the parent tree since it could change below
3627 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3630 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3631 AFS_TRACE_LEVEL_VERBOSE,
3632 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3634 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3635 &pCurrentDirEntry->NameInformation.FileName));
3637 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3640 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3645 pCurrentDirEntry = pNextDirEntry;
3649 // Reget the directory contents
3652 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3655 if ( !NT_SUCCESS( ntStatus))
3657 try_return( ntStatus);
3661 // Now start again and tear down any entries not valid
3664 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3666 while( pCurrentDirEntry != NULL)
3669 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3671 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3674 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3675 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3676 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3679 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3682 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3684 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3685 AFS_TRACE_LEVEL_VERBOSE,
3686 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3688 &pCurrentDirEntry->NameInformation.FileName));
3690 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3695 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3698 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3699 AFS_TRACE_LEVEL_VERBOSE,
3700 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3702 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3703 &pCurrentDirEntry->NameInformation.FileName));
3707 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3709 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3710 AFS_TRACE_LEVEL_VERBOSE,
3711 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3713 &pCurrentDirEntry->NameInformation.FileName));
3718 pCurrentDirEntry = pNextDirEntry;
3723 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3724 AFS_TRACE_LEVEL_VERBOSE,
3725 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3727 pCurrentDirEntry->DirOpenReferenceCount));
3729 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3730 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3733 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3734 AFS_TRACE_LEVEL_VERBOSE,
3735 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3736 &pCurrentDirEntry->NameInformation.FileName,
3737 ObjectInfo->FileId.Cell,
3738 ObjectInfo->FileId.Volume,
3739 ObjectInfo->FileId.Vnode,
3740 ObjectInfo->FileId.Unique));
3742 AFSDeleteDirEntry( ObjectInfo,
3748 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3749 AFS_TRACE_LEVEL_VERBOSE,
3750 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3752 &pCurrentDirEntry->NameInformation.FileName,
3753 ObjectInfo->FileId.Cell,
3754 ObjectInfo->FileId.Volume,
3755 ObjectInfo->FileId.Vnode,
3756 ObjectInfo->FileId.Unique));
3758 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3760 AFSRemoveNameEntry( ObjectInfo,
3764 pCurrentDirEntry = pNextDirEntry;
3768 if( !AFSValidateDirList( ObjectInfo))
3771 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3780 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3788 AFSIsVolumeFID( IN AFSFileID *FileID)
3791 BOOLEAN bIsVolume = FALSE;
3793 if( FileID->Vnode == 1 &&
3794 FileID->Unique == 1)
3804 AFSIsFinalNode( IN AFSFcb *Fcb)
3807 BOOLEAN bIsFinalNode = FALSE;
3809 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3810 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3811 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3812 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3813 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3816 bIsFinalNode = TRUE;
3821 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3822 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3825 return bIsFinalNode;
3829 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3830 IN AFSDirEnumEntry *DirEnumEntry)
3833 NTSTATUS ntStatus = STATUS_SUCCESS;
3834 UNICODE_STRING uniTargetName;
3835 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3840 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3842 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3844 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3846 pObjectInfo->FileType = DirEnumEntry->FileType;
3848 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3850 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3852 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3854 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3856 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3858 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3860 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3862 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3863 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3866 pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3869 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
3872 if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
3875 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3880 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3884 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3886 pObjectInfo->Links = DirEnumEntry->Links;
3888 if( DirEnumEntry->TargetNameLength > 0 &&
3889 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3890 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3894 // Update the target name information if needed
3897 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3899 uniTargetName.MaximumLength = uniTargetName.Length;
3901 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3903 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3906 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3907 RtlCompareUnicodeString( &uniTargetName,
3908 &DirEntry->NameInformation.TargetName,
3913 // Update the target name
3916 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3918 uniTargetName.Buffer,
3919 uniTargetName.Length);
3921 if( !NT_SUCCESS( ntStatus))
3924 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3926 try_return( ntStatus);
3930 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3932 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3933 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3936 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3939 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3940 DirEntry->NameInformation.TargetName.Buffer != NULL)
3942 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3945 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3947 DirEntry->NameInformation.TargetName.Length = 0;
3948 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3949 DirEntry->NameInformation.TargetName.Buffer = NULL;
3951 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3963 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3965 IN BOOLEAN FastCall,
3966 IN BOOLEAN bSafeToPurge)
3969 NTSTATUS ntStatus = STATUS_SUCCESS;
3970 LARGE_INTEGER liSystemTime;
3971 AFSDirEnumEntry *pDirEnumEntry = NULL;
3972 AFSFcb *pCurrentFcb = NULL;
3973 BOOLEAN bReleaseFcb = FALSE;
3974 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3980 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3984 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3985 AFS_TRACE_LEVEL_VERBOSE_2,
3986 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
3987 &DirEntry->NameInformation.FileName,
3988 pObjectInfo->FileId.Cell,
3989 pObjectInfo->FileId.Volume,
3990 pObjectInfo->FileId.Vnode,
3991 pObjectInfo->FileId.Unique,
3995 // If this is a fake node then bail since the service knows nothing about it
3998 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
4001 try_return( ntStatus);
4005 // This routine ensures that the current entry is valid by:
4007 // 1) Checking that the expiration time is non-zero and after where we
4011 KeQuerySystemTime( &liSystemTime);
4013 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
4014 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
4015 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
4016 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
4019 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4020 AFS_TRACE_LEVEL_VERBOSE_2,
4021 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
4022 &DirEntry->NameInformation.FileName,
4023 pObjectInfo->FileId.Cell,
4024 pObjectInfo->FileId.Volume,
4025 pObjectInfo->FileId.Vnode,
4026 pObjectInfo->FileId.Unique));
4028 try_return( ntStatus);
4032 // This node requires updating
4035 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
4040 if( !NT_SUCCESS( ntStatus))
4043 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4044 AFS_TRACE_LEVEL_ERROR,
4045 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4047 &DirEntry->NameInformation.FileName,
4048 pObjectInfo->FileId.Cell,
4049 pObjectInfo->FileId.Volume,
4050 pObjectInfo->FileId.Vnode,
4051 pObjectInfo->FileId.Unique,
4055 // Failed validation of node so return access-denied
4058 try_return( ntStatus);
4061 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4062 AFS_TRACE_LEVEL_VERBOSE,
4063 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
4065 &DirEntry->NameInformation.FileName,
4066 pObjectInfo->FileId.Cell,
4067 pObjectInfo->FileId.Volume,
4068 pObjectInfo->FileId.Vnode,
4069 pObjectInfo->FileId.Unique,
4070 pObjectInfo->DataVersion.QuadPart,
4071 pDirEnumEntry->DataVersion.QuadPart,
4072 pDirEnumEntry->FileType));
4076 // Based on the file type, process the node
4079 switch( pDirEnumEntry->FileType)
4082 case AFS_FILE_TYPE_MOUNTPOINT:
4086 // Update the metadata for the entry
4089 ntStatus = AFSUpdateMetaData( DirEntry,
4092 if( NT_SUCCESS( ntStatus))
4095 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4101 case AFS_FILE_TYPE_SYMLINK:
4102 case AFS_FILE_TYPE_DFSLINK:
4106 // Update the metadata for the entry
4109 ntStatus = AFSUpdateMetaData( DirEntry,
4112 if( NT_SUCCESS( ntStatus))
4115 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4121 case AFS_FILE_TYPE_FILE:
4124 BOOLEAN bPurgeExtents = FALSE;
4127 // For a file where the data version has become invalid we need to
4128 // fail any current extent requests and purge the cache for the file
4129 // Can't hold the Fcb resource while doing this
4132 if( pObjectInfo->Fcb != NULL &&
4133 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4134 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4137 pCurrentFcb = pObjectInfo->Fcb;
4139 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4142 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4143 AFS_TRACE_LEVEL_VERBOSE,
4144 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4145 &pCurrentFcb->NPFcb->Resource,
4146 PsGetCurrentThread()));
4148 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4154 if( pCurrentFcb != NULL)
4157 IO_STATUS_BLOCK stIoStatus;
4159 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4160 AFS_TRACE_LEVEL_VERBOSE_2,
4161 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4162 &DirEntry->NameInformation.FileName,
4163 pObjectInfo->FileId.Cell,
4164 pObjectInfo->FileId.Volume,
4165 pObjectInfo->FileId.Vnode,
4166 pObjectInfo->FileId.Unique));
4168 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4171 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4172 AFS_TRACE_LEVEL_VERBOSE,
4173 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4174 &DirEntry->NameInformation.FileName,
4175 pObjectInfo->FileId.Cell,
4176 pObjectInfo->FileId.Volume,
4177 pObjectInfo->FileId.Vnode,
4178 pObjectInfo->FileId.Unique,
4179 pObjectInfo->DataVersion.LowPart,
4180 pDirEnumEntry->DataVersion.LowPart));
4182 bPurgeExtents = TRUE;
4188 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4190 bPurgeExtents = TRUE;
4192 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4193 AFS_TRACE_LEVEL_VERBOSE,
4194 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4195 &DirEntry->NameInformation.FileName,
4196 pObjectInfo->FileId.Cell,
4197 pObjectInfo->FileId.Volume,
4198 pObjectInfo->FileId.Vnode,
4199 pObjectInfo->FileId.Unique));
4201 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4204 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4205 AFS_TRACE_LEVEL_VERBOSE,
4206 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4207 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4208 PsGetCurrentThread()));
4210 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4214 // Release Fcb->Resource to avoid Trend Micro deadlock
4217 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
4222 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4227 if( !NT_SUCCESS( stIoStatus.Status))
4230 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4231 AFS_TRACE_LEVEL_ERROR,
4232 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4233 &DirEntry->NameInformation.FileName,
4234 pObjectInfo->FileId.Cell,
4235 pObjectInfo->FileId.Volume,
4236 pObjectInfo->FileId.Vnode,
4237 pObjectInfo->FileId.Unique,
4239 stIoStatus.Information));
4241 ntStatus = stIoStatus.Status;
4244 if ( bPurgeExtents &&
4245 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4248 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4254 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4255 AFS_TRACE_LEVEL_WARNING,
4256 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4257 &DirEntry->NameInformation.FileName,
4258 pObjectInfo->FileId.Cell,
4259 pObjectInfo->FileId.Volume,
4260 pObjectInfo->FileId.Vnode,
4261 pObjectInfo->FileId.Unique));
4263 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4267 __except( EXCEPTION_EXECUTE_HANDLER)
4269 ntStatus = GetExceptionCode();
4273 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4274 &DirEntry->NameInformation.FileName,
4275 pObjectInfo->FileId.Cell,
4276 pObjectInfo->FileId.Volume,
4277 pObjectInfo->FileId.Vnode,
4278 pObjectInfo->FileId.Unique,
4281 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4284 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4285 AFS_TRACE_LEVEL_VERBOSE,
4286 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4287 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4288 PsGetCurrentThread()));
4290 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4292 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4301 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4306 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4308 bReleaseFcb = FALSE;
4310 if ( bPurgeExtents &&
4313 AFSFlushExtents( pCurrentFcb,
4320 // Update the metadata for the entry but only if it is safe to do so.
4321 // If it was determined that a data version change has occurred or
4322 // that a pending data verification was required, do not update the
4323 // ObjectInfo meta data or the FileObject size information. That
4324 // way it is consistent for the next time that the data is verified
4328 if ( !(bPurgeExtents && bSafeToPurge))
4331 ntStatus = AFSUpdateMetaData( DirEntry,
4334 if( !NT_SUCCESS( ntStatus))
4337 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4338 AFS_TRACE_LEVEL_ERROR,
4339 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4340 &DirEntry->NameInformation.FileName,
4341 pObjectInfo->FileId.Cell,
4342 pObjectInfo->FileId.Volume,
4343 pObjectInfo->FileId.Vnode,
4344 pObjectInfo->FileId.Unique,
4350 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4353 // Update file sizes
4356 if( pObjectInfo->Fcb != NULL)
4358 FILE_OBJECT *pCCFileObject;
4360 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4361 AFS_TRACE_LEVEL_VERBOSE,
4362 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4363 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4364 PsGetCurrentThread()));
4366 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4372 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4374 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4375 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4376 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4378 if ( pCCFileObject != NULL)
4380 CcSetFileSizes( pCCFileObject,
4381 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4384 __except( EXCEPTION_EXECUTE_HANDLER)
4387 ntStatus = GetExceptionCode();
4391 "EXCEPTION - AFSValidateEntry CcSetFileSizes failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4392 pObjectInfo->FileId.Cell,
4393 pObjectInfo->FileId.Volume,
4394 pObjectInfo->FileId.Vnode,
4395 pObjectInfo->FileId.Unique,
4399 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4400 AFS_TRACE_LEVEL_VERBOSE,
4401 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4402 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4403 PsGetCurrentThread()));
4405 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4411 case AFS_FILE_TYPE_DIRECTORY:
4414 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4418 // For a directory or root entry flush the content of
4419 // the directory enumeration.
4422 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4423 AFS_TRACE_LEVEL_VERBOSE,
4424 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4425 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4426 PsGetCurrentThread()));
4428 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4431 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4432 AFS_TRACE_LEVEL_VERBOSE_2,
4433 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4434 &DirEntry->NameInformation.FileName,
4435 pObjectInfo->FileId.Cell,
4436 pObjectInfo->FileId.Volume,
4437 pObjectInfo->FileId.Vnode,
4438 pObjectInfo->FileId.Unique));
4440 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4443 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4446 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4449 if( !NT_SUCCESS( ntStatus))
4452 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4453 AFS_TRACE_LEVEL_ERROR,
4454 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4455 &DirEntry->NameInformation.FileName,
4456 pObjectInfo->FileId.Cell,
4457 pObjectInfo->FileId.Volume,
4458 pObjectInfo->FileId.Vnode,
4459 pObjectInfo->FileId.Unique,
4467 // Update the metadata for the entry
4470 ntStatus = AFSUpdateMetaData( DirEntry,
4473 if( NT_SUCCESS( ntStatus))
4476 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4484 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4485 AFS_TRACE_LEVEL_WARNING,
4486 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4487 pObjectInfo->FileType,
4489 &DirEntry->NameInformation.FileName,
4490 pObjectInfo->FileId.Cell,
4491 pObjectInfo->FileId.Volume,
4492 pObjectInfo->FileId.Vnode,
4493 pObjectInfo->FileId.Unique));
4503 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4506 if( pDirEnumEntry != NULL)
4509 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4517 AFSInitializeSpecialShareNameList()
4520 NTSTATUS ntStatus = STATUS_SUCCESS;
4521 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4522 AFSObjectInfoCB *pObjectInfoCB = NULL;
4523 UNICODE_STRING uniShareName;
4524 ULONG ulEntryLength = 0;
4525 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4531 RtlInitUnicodeString( &uniShareName,
4534 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4537 if( pObjectInfoCB == NULL)
4540 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4543 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4544 AFS_OBJECT_REFERENCE_GLOBAL);
4546 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4547 AFS_TRACE_LEVEL_VERBOSE,
4548 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4552 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4554 ulEntryLength = sizeof( AFSDirectoryCB) +
4555 uniShareName.Length;
4557 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4561 if( pDirNode == NULL)
4564 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4565 AFS_OBJECT_REFERENCE_GLOBAL);
4567 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4568 AFS_TRACE_LEVEL_VERBOSE,
4569 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4576 AFSDeleteObjectInfo( &pObjectInfoCB);
4579 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4582 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4583 AFS_TRACE_LEVEL_VERBOSE,
4584 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4587 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4588 sizeof( AFSNonPagedDirectoryCB),
4589 AFS_DIR_ENTRY_NP_TAG);
4591 if( pNonPagedDirEntry == NULL)
4594 AFSLibExFreePoolWithTag( pDirNode,
4597 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4598 AFS_OBJECT_REFERENCE_GLOBAL);
4600 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4601 AFS_TRACE_LEVEL_VERBOSE,
4602 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4609 AFSDeleteObjectInfo( &pObjectInfoCB);
4612 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4615 RtlZeroMemory( pDirNode,
4618 RtlZeroMemory( pNonPagedDirEntry,
4619 sizeof( AFSNonPagedDirectoryCB));
4621 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4623 pDirNode->NonPaged = pNonPagedDirEntry;
4625 pDirNode->ObjectInformation = pObjectInfoCB;
4631 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4633 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4635 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4637 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4639 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4640 uniShareName.Buffer,
4641 pDirNode->NameInformation.FileName.Length);
4643 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4646 AFSSpecialShareNames = pDirNode;
4648 pLastDirNode = pDirNode;
4651 RtlInitUnicodeString( &uniShareName,
4654 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4657 if( pObjectInfoCB == NULL)
4660 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4663 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4664 AFS_OBJECT_REFERENCE_GLOBAL);
4666 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4667 AFS_TRACE_LEVEL_VERBOSE,
4668 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4672 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4674 ulEntryLength = sizeof( AFSDirectoryCB) +
4675 uniShareName.Length;
4677 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4681 if( pDirNode == NULL)
4684 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4685 AFS_OBJECT_REFERENCE_GLOBAL);
4687 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4688 AFS_TRACE_LEVEL_VERBOSE,
4689 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4696 AFSDeleteObjectInfo( &pObjectInfoCB);
4699 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4702 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4703 AFS_TRACE_LEVEL_VERBOSE,
4704 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4707 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4708 sizeof( AFSNonPagedDirectoryCB),
4709 AFS_DIR_ENTRY_NP_TAG);
4711 if( pNonPagedDirEntry == NULL)
4714 AFSLibExFreePoolWithTag( pDirNode,
4717 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4718 AFS_OBJECT_REFERENCE_GLOBAL);
4720 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4721 AFS_TRACE_LEVEL_VERBOSE,
4722 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4729 AFSDeleteObjectInfo( &pObjectInfoCB);
4732 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4735 RtlZeroMemory( pDirNode,
4738 RtlZeroMemory( pNonPagedDirEntry,
4739 sizeof( AFSNonPagedDirectoryCB));
4741 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4743 pDirNode->NonPaged = pNonPagedDirEntry;
4745 pDirNode->ObjectInformation = pObjectInfoCB;
4751 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4753 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4755 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4757 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4759 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4760 uniShareName.Buffer,
4761 pDirNode->NameInformation.FileName.Length);
4763 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4766 pLastDirNode->ListEntry.fLink = pDirNode;
4768 pDirNode->ListEntry.bLink = pLastDirNode;
4772 if( !NT_SUCCESS( ntStatus))
4775 if( AFSSpecialShareNames != NULL)
4778 pDirNode = AFSSpecialShareNames;
4780 while( pDirNode != NULL)
4783 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4785 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
4786 AFS_OBJECT_REFERENCE_GLOBAL);
4788 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4789 AFS_TRACE_LEVEL_VERBOSE,
4790 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4791 pDirNode->ObjectInformation,
4797 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4800 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4802 AFSLibExFreePoolWithTag( pDirNode->NonPaged,
4803 AFS_DIR_ENTRY_NP_TAG);
4805 AFSLibExFreePoolWithTag( pDirNode,
4808 pDirNode = pLastDirNode;
4811 AFSSpecialShareNames = NULL;
4820 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4821 IN UNICODE_STRING *SecondaryName)
4824 AFSDirectoryCB *pDirectoryCB = NULL;
4825 ULONGLONG ullHash = 0;
4826 UNICODE_STRING uniFullShareName;
4832 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4833 AFS_TRACE_LEVEL_VERBOSE_2,
4834 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4838 uniFullShareName = *ShareName;
4841 // Generate our hash value
4844 ullHash = AFSGenerateCRC( &uniFullShareName,
4848 // Loop through our special share names to see if this is one of them
4851 pDirectoryCB = AFSSpecialShareNames;
4853 while( pDirectoryCB != NULL)
4856 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4862 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4866 return pDirectoryCB;
4870 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4874 // Block on the queue flush event
4877 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4887 AFSWaitOnQueuedReleases()
4890 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4893 // Block on the queue flush event
4896 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4906 AFSIsEqualFID( IN AFSFileID *FileId1,
4907 IN AFSFileID *FileId2)
4910 BOOLEAN bIsEqual = FALSE;
4912 if( FileId1->Hash == FileId2->Hash &&
4913 FileId1->Unique == FileId2->Unique &&
4914 FileId1->Vnode == FileId2->Vnode &&
4915 FileId1->Volume == FileId2->Volume &&
4916 FileId1->Cell == FileId2->Cell)
4926 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4929 NTSTATUS ntStatus = STATUS_SUCCESS;
4930 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4935 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4938 // Reset the directory list information
4941 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4943 while( pCurrentDirEntry != NULL)
4946 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4948 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
4949 pCurrentDirEntry->NameArrayReferenceCount <= 0)
4952 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4953 AFS_TRACE_LEVEL_VERBOSE,
4954 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4956 &pCurrentDirEntry->NameInformation.FileName));
4958 AFSDeleteDirEntry( ObjectInfoCB,
4964 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4965 AFS_TRACE_LEVEL_VERBOSE,
4966 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4968 &pCurrentDirEntry->NameInformation.FileName));
4970 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4972 AFSRemoveNameEntry( ObjectInfoCB,
4976 pCurrentDirEntry = pNextDirEntry;
4979 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4981 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4983 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4985 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4987 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4989 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4991 AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4992 AFS_TRACE_LEVEL_VERBOSE,
4993 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4994 ObjectInfoCB->FileId.Cell,
4995 ObjectInfoCB->FileId.Volume,
4996 ObjectInfoCB->FileId.Vnode,
4997 ObjectInfoCB->FileId.Unique));
5004 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
5007 NTSTATUS ntStatus = STATUS_SUCCESS;
5008 AFSDirectoryCB *pDirGlobalDirNode = NULL;
5009 UNICODE_STRING uniFullName;
5014 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
5015 AFS_TRACE_LEVEL_VERBOSE,
5016 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
5017 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
5018 PsGetCurrentThread()));
5020 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
5023 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
5026 try_return( ntStatus);
5030 // Initialize the root information
5033 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
5036 // Enumerate the shares in the volume
5039 ntStatus = AFSEnumerateDirectory( AuthGroup,
5040 &AFSGlobalRoot->ObjectInformation,
5043 if( !NT_SUCCESS( ntStatus))
5046 try_return( ntStatus);
5049 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
5051 uniFullName.MaximumLength = PAGE_SIZE;
5052 uniFullName.Length = 0;
5054 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
5055 uniFullName.MaximumLength,
5056 AFS_GENERIC_MEMORY_12_TAG);
5058 if( uniFullName.Buffer == NULL)
5062 // Reset the directory content
5065 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
5067 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
5069 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5073 // Populate our list of entries in the NP enumeration list
5076 while( pDirGlobalDirNode != NULL)
5079 uniFullName.Buffer[ 0] = L'\\';
5080 uniFullName.Buffer[ 1] = L'\\';
5082 uniFullName.Length = 2 * sizeof( WCHAR);
5084 RtlCopyMemory( &uniFullName.Buffer[ 2],
5085 AFSServerName.Buffer,
5086 AFSServerName.Length);
5088 uniFullName.Length += AFSServerName.Length;
5090 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
5092 uniFullName.Length += sizeof( WCHAR);
5094 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
5095 pDirGlobalDirNode->NameInformation.FileName.Buffer,
5096 pDirGlobalDirNode->NameInformation.FileName.Length);
5098 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
5100 AFSAddConnectionEx( &uniFullName,
5101 RESOURCEDISPLAYTYPE_SHARE,
5104 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
5107 AFSLibExFreePoolWithTag( uniFullName.Buffer,
5108 AFS_GENERIC_MEMORY_12_TAG);
5112 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
5119 AFSIsRelativeName( IN UNICODE_STRING *Name)
5122 BOOLEAN bIsRelative = FALSE;
5124 if( Name->Length > 0 &&
5125 Name->Buffer[ 0] != L'\\')
5135 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
5137 UNICODE_STRING uniTempName;
5138 BOOLEAN bIsAbsolute = FALSE;
5141 // An absolute AFS path must begin with \afs\... or equivalent
5144 if ( Name->Length == 0 ||
5145 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
5146 Name->Buffer[ 0] != L'\\' ||
5147 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
5153 uniTempName.Length = AFSMountRootName.Length;
5154 uniTempName.MaximumLength = AFSMountRootName.Length;
5156 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5157 uniTempName.MaximumLength,
5158 AFS_NAME_BUFFER_TWO_TAG);
5160 if( uniTempName.Buffer == NULL)
5166 RtlCopyMemory( uniTempName.Buffer,
5168 AFSMountRootName.Length);
5170 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
5174 AFSExFreePoolWithTag( uniTempName.Buffer,
5175 AFS_NAME_BUFFER_TWO_TAG);
5182 AFSUpdateName( IN UNICODE_STRING *Name)
5187 while( usIndex < Name->Length/sizeof( WCHAR))
5190 if( Name->Buffer[ usIndex] == L'/')
5193 Name->Buffer[ usIndex] = L'\\';
5203 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
5204 IN OUT ULONG *Flags,
5205 IN WCHAR *NameBuffer,
5206 IN USHORT NameLength)
5209 NTSTATUS ntStatus = STATUS_SUCCESS;
5210 WCHAR *pTmpBuffer = NULL;
5216 // If we have enough space then just move in the name otherwise
5217 // allocate a new buffer
5220 if( TargetName->Length < NameLength)
5223 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5225 AFS_NAME_BUFFER_FIVE_TAG);
5227 if( pTmpBuffer == NULL)
5230 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5233 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5236 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5239 TargetName->MaximumLength = NameLength;
5241 TargetName->Buffer = pTmpBuffer;
5243 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5246 TargetName->Length = NameLength;
5248 RtlCopyMemory( TargetName->Buffer,
5250 TargetName->Length);
5253 // Update the name in the buffer
5256 AFSUpdateName( TargetName);
5267 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5272 // Depending on the type of node, set the event
5275 switch( Fcb->Header.NodeTypeCode)
5278 case AFS_DIRECTORY_FCB:
5283 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5293 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5299 // Depending on the type of node, set the event
5302 switch( Fcb->Header.NodeTypeCode)
5305 case AFS_DIRECTORY_FCB:
5310 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5312 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5322 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5325 BOOLEAN bIsInProcess = FALSE;
5330 if( ObjectInfo->Fcb == NULL)
5333 try_return( bIsInProcess);
5336 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5339 case AFS_DIRECTORY_FCB:
5344 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5347 bIsInProcess = TRUE;
5359 return bIsInProcess;
5363 AFSVerifyVolume( IN ULONGLONG ProcessId,
5364 IN AFSVolumeCB *VolumeCB)
5367 UNREFERENCED_PARAMETER(ProcessId);
5368 UNREFERENCED_PARAMETER(VolumeCB);
5369 NTSTATUS ntStatus = STATUS_SUCCESS;
5376 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5379 NTSTATUS ntStatus = STATUS_SUCCESS;
5380 AFSObjectInfoCB *pObjectInfoCB = NULL;
5381 AFSDirectoryCB *pDirNode = NULL;
5382 ULONG ulEntryLength = 0;
5383 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5389 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
5392 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5395 if( pObjectInfoCB == NULL)
5398 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5400 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5403 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5404 AFS_OBJECT_REFERENCE_PIOCTL);
5406 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5407 AFS_TRACE_LEVEL_VERBOSE,
5408 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5412 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5414 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5416 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5418 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5420 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5424 if( pDirNode == NULL)
5427 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5430 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5431 AFS_TRACE_LEVEL_VERBOSE,
5432 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5435 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5436 sizeof( AFSNonPagedDirectoryCB),
5437 AFS_DIR_ENTRY_NP_TAG);
5439 if( pNonPagedDirEntry == NULL)
5442 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5445 RtlZeroMemory( pDirNode,
5448 RtlZeroMemory( pNonPagedDirEntry,
5449 sizeof( AFSNonPagedDirectoryCB));
5451 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5453 pDirNode->NonPaged = pNonPagedDirEntry;
5455 pDirNode->ObjectInformation = pObjectInfoCB;
5457 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5463 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5465 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5467 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5469 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5471 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5472 AFSPIOCtlName.Buffer,
5473 pDirNode->NameInformation.FileName.Length);
5475 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5478 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5481 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5482 AFS_TRACE_LEVEL_WARNING,
5483 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5484 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5487 try_return( ntStatus = STATUS_REPARSE);
5492 if ( ntStatus != STATUS_SUCCESS)
5495 if ( pDirNode != NULL)
5498 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5499 AFS_TRACE_LEVEL_VERBOSE,
5500 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
5503 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5506 if( pNonPagedDirEntry != NULL)
5509 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5511 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5514 if ( pObjectInfoCB != NULL)
5517 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
5518 AFS_OBJECT_REFERENCE_PIOCTL);
5520 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5521 AFS_TRACE_LEVEL_VERBOSE,
5522 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
5529 AFSDeleteObjectInfo( &pObjectInfoCB);
5539 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5540 IN AFSDirectoryCB *DirectoryCB,
5541 IN UNICODE_STRING *ParentPathName,
5542 IN AFSNameArrayHdr *RelatedNameArray,
5544 OUT AFSFileInfoCB *FileInfo)
5547 NTSTATUS ntStatus = STATUS_SUCCESS;
5548 AFSDirEnumEntry *pDirEntry = NULL;
5549 UNICODE_STRING uniFullPathName = {0};
5550 AFSNameArrayHdr *pNameArray = NULL;
5551 AFSVolumeCB *pVolumeCB = NULL;
5552 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5553 AFSVolumeCB *pNewVolumeCB = NULL;
5554 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5555 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5556 AFSDirectoryCB *pNewParentDirEntry = NULL;
5557 WCHAR *pwchBuffer = NULL;
5558 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5559 ULONG ulNameDifference = 0;
5566 // Retrieve a target name for the entry
5569 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5572 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5575 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5577 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5582 if( !NT_SUCCESS( ntStatus) ||
5583 pDirEntry->TargetNameLength == 0)
5586 if( pDirEntry != NULL)
5589 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5592 try_return( ntStatus);
5595 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5598 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5602 // Update the target name
5605 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5606 &DirectoryCB->Flags,
5607 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5608 (USHORT)pDirEntry->TargetNameLength);
5610 if( !NT_SUCCESS( ntStatus))
5613 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5615 try_return( ntStatus);
5619 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5623 // Need to pass the full path in for parsing.
5626 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5629 uniFullPathName.Length = 0;
5630 uniFullPathName.MaximumLength = ParentPathName->Length +
5632 DirectoryCB->NameInformation.TargetName.Length;
5634 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5635 uniFullPathName.MaximumLength,
5636 AFS_NAME_BUFFER_SIX_TAG);
5638 if( uniFullPathName.Buffer == NULL)
5641 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5643 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5646 pwchBuffer = uniFullPathName.Buffer;
5648 RtlZeroMemory( uniFullPathName.Buffer,
5649 uniFullPathName.MaximumLength);
5651 RtlCopyMemory( uniFullPathName.Buffer,
5652 ParentPathName->Buffer,
5653 ParentPathName->Length);
5655 uniFullPathName.Length = ParentPathName->Length;
5657 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5658 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5661 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5663 uniFullPathName.Length += sizeof( WCHAR);
5666 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5667 DirectoryCB->NameInformation.TargetName.Buffer,
5668 DirectoryCB->NameInformation.TargetName.Length);
5670 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5672 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5673 uniParsedName.MaximumLength = uniParsedName.Length;
5675 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5677 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5680 // We populate up to the current parent
5683 if( RelatedNameArray != NULL)
5686 pNameArray = AFSInitNameArray( NULL,
5687 RelatedNameArray->MaxElementCount);
5689 if( pNameArray == NULL)
5692 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5695 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5702 pNameArray = AFSInitNameArray( NULL,
5705 if( pNameArray == NULL)
5708 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5711 ntStatus = AFSPopulateNameArray( pNameArray,
5716 if( !NT_SUCCESS( ntStatus))
5719 try_return( ntStatus);
5722 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5724 pParentDirEntry = ParentDirectoryCB;
5729 uniFullPathName.Length = 0;
5730 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5732 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5733 uniFullPathName.MaximumLength,
5734 AFS_NAME_BUFFER_SEVEN_TAG);
5736 if( uniFullPathName.Buffer == NULL)
5739 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5741 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5744 pwchBuffer = uniFullPathName.Buffer;
5746 RtlZeroMemory( uniFullPathName.Buffer,
5747 uniFullPathName.MaximumLength);
5749 RtlCopyMemory( uniFullPathName.Buffer,
5750 DirectoryCB->NameInformation.TargetName.Buffer,
5751 DirectoryCB->NameInformation.TargetName.Length);
5753 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5756 // This name should begin with the \afs server so parse it off and check it
5759 FsRtlDissectName( uniFullPathName,
5763 if( RtlCompareUnicodeString( &uniComponentName,
5768 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5770 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5771 AFS_TRACE_LEVEL_ERROR,
5772 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5775 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5778 uniFullPathName = uniRemainingPath;
5780 uniParsedName = uniFullPathName;
5782 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5784 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5790 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5793 if( pNameArray == NULL)
5796 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5799 pVolumeCB = AFSGlobalRoot;
5801 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5805 // Increment the ref count on the volume and dir entry for correct processing below
5808 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
5810 lCount = AFSVolumeIncrement( pVolumeCB,
5811 VolumeReferenceReason);
5813 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5814 AFS_TRACE_LEVEL_VERBOSE,
5815 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
5817 VolumeReferenceReason,
5820 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
5822 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5823 AFS_TRACE_LEVEL_VERBOSE,
5824 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5825 &pParentDirEntry->NameInformation.FileName,
5830 ntStatus = AFSLocateNameEntry( NULL,
5835 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5839 &NewVolumeReferenceReason,
5840 &pNewParentDirEntry,
5844 if ( pNewVolumeCB != NULL)
5847 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
5848 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
5849 // the reference on pVolumeCB that was held prior to the call.
5850 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
5851 // will be released second.
5854 lCount = AFSVolumeDecrement( pVolumeCB,
5855 VolumeReferenceReason);
5857 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5858 AFS_TRACE_LEVEL_VERBOSE,
5859 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
5861 VolumeReferenceReason,
5864 pVolumeCB = pNewVolumeCB;
5866 pNewVolumeCB = NULL;
5868 VolumeReferenceReason = NewVolumeReferenceReason;
5870 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5874 // AFSLocateNameEntry does not alter the reference count of
5875 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
5876 // a reference held.
5879 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5881 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5882 AFS_TRACE_LEVEL_VERBOSE,
5883 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
5884 &pParentDirEntry->NameInformation.FileName,
5888 pParentDirEntry = pNewParentDirEntry;
5890 pNewParentDirEntry = NULL;
5892 if( !NT_SUCCESS( ntStatus) ||
5893 ntStatus == STATUS_REPARSE)
5896 try_return( ntStatus);
5900 // Store off the information
5903 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5906 // Check for the mount point being returned
5909 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
5910 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5913 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5915 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
5918 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
5921 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
5926 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5930 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5932 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5934 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5936 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5938 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5940 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5944 if( pDirEntry != NULL)
5947 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
5950 if( pDirectoryEntry != NULL)
5953 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
5955 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5956 AFS_TRACE_LEVEL_VERBOSE,
5957 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5958 &pDirectoryEntry->NameInformation.FileName,
5963 ASSERT( lCount >= 0);
5966 if ( pParentDirEntry != NULL)
5969 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5971 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5972 AFS_TRACE_LEVEL_VERBOSE,
5973 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5974 &pParentDirEntry->NameInformation.FileName,
5979 ASSERT( lCount >= 0);
5982 if( pVolumeCB != NULL)
5985 lCount = AFSVolumeDecrement( pVolumeCB,
5986 VolumeReferenceReason);
5988 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5989 AFS_TRACE_LEVEL_VERBOSE,
5990 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
5992 VolumeReferenceReason,
5996 if( pNameArray != NULL)
5999 AFSFreeNameArray( pNameArray);
6002 if( pwchBuffer != NULL)
6006 // Always free the buffer that we allocated as AFSLocateNameEntry
6007 // will not free it. If uniFullPathName.Buffer was allocated by
6008 // AFSLocateNameEntry, then we must free that as well.
6009 // Check that the uniFullPathName.Buffer in the string is not the same
6010 // offset by the length of the server name
6013 if( uniFullPathName.Length > 0 &&
6014 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6017 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6020 AFSExFreePoolWithTag( pwchBuffer, 0);
6028 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6029 IN ULONGLONG HashIndex)
6032 NTSTATUS ntStatus = STATUS_SUCCESS;
6033 AFSObjectInfoCB *pObjectInfo = NULL;
6039 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6040 sizeof( AFSObjectInfoCB),
6041 AFS_OBJECT_INFO_TAG);
6043 if( pObjectInfo == NULL)
6046 try_return( pObjectInfo);
6049 RtlZeroMemory( pObjectInfo,
6050 sizeof( AFSObjectInfoCB));
6052 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6053 sizeof( AFSNonPagedObjectInfoCB),
6054 AFS_NP_OBJECT_INFO_TAG);
6056 if( pObjectInfo->NonPagedInfo == NULL)
6059 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6061 try_return( pObjectInfo = NULL);
6064 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6066 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6068 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6070 if( ParentObjectInfo != NULL)
6073 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6075 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6077 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6079 AFSAcquireShared( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6082 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6083 AFS_OBJECT_REFERENCE_CHILD);
6085 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6086 AFS_TRACE_LEVEL_VERBOSE,
6087 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6091 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6095 // Initialize the access time
6098 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6103 ASSERT( ParentObjectInfo);
6106 // Insert the entry into the object tree and list
6109 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6111 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6114 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6119 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6120 &pObjectInfo->TreeEntry);
6122 ASSERT( NT_SUCCESS( ntStatus));
6126 // And the object list in the volume
6129 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6132 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6137 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6139 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6142 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6145 // Indicate the object is in the hash tree and linked list in the volume
6148 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6160 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6166 if ( ObjectInfo->ObjectReferenceCount == 0)
6169 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6172 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6177 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6180 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6185 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6187 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6192 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6194 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6200 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6204 LONG lCount, lCount2;
6206 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6209 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6214 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6216 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6218 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6221 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6224 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6226 ASSERT( lCount2 >= 0);
6228 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6234 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6235 IN AFSFileID *FileId,
6236 IN BOOLEAN bUpdateLastUse)
6238 DWORD ntStatus = STATUS_SUCCESS;
6240 AFSObjectInfoCB *pObjectInfo = NULL;
6243 ullIndex = AFSCreateLowIndex( FileId);
6245 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
6248 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6251 pObjectInfo = &VolumeCB->ObjectInformation;
6256 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6258 (AFSBTreeEntry **)&pObjectInfo);
6261 if ( NT_SUCCESS( ntStatus)) {
6263 lCount = AFSObjectInfoIncrement( pObjectInfo,
6264 AFS_OBJECT_REFERENCE_FIND);
6266 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6267 AFS_TRACE_LEVEL_VERBOSE,
6268 "AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
6272 if ( bUpdateLastUse)
6275 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6279 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6285 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6289 lCount = AFSObjectInfoDecrement( *ppObjectInfo,
6290 AFS_OBJECT_REFERENCE_FIND);
6292 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6293 AFS_TRACE_LEVEL_VERBOSE,
6294 "AFSReleaseObjectInfo Decrement count on object %p Cnt %d\n",
6298 *ppObjectInfo = NULL;
6302 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6304 BOOLEAN bAcquiredTreeLock = FALSE;
6305 AFSObjectInfoCB *pObjectInfo = NULL;
6306 AFSVolumeCB * pVolume = NULL;
6307 BOOLEAN bHeldInService;
6308 AFSObjectInfoCB * pParentObjectInfo = NULL;
6314 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
6318 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6319 // embedded in the VolumeCB.
6327 pVolume = (*ppObjectInfo)->VolumeCB;
6329 if( !ExIsResourceAcquiredExclusiveLite( pVolume->ObjectInfoTree.TreeLock))
6332 ASSERT( !ExIsResourceAcquiredLite( pVolume->ObjectInfoTree.TreeLock));
6334 AFSAcquireExcl( pVolume->ObjectInfoTree.TreeLock,
6337 bAcquiredTreeLock = TRUE;
6340 for ( lCount = 0; lCount < AFS_OBJECT_REFERENCE_MAX; lCount++)
6343 ASSERT( (*ppObjectInfo)->ObjectReferences[ lCount] >= 0);
6346 ASSERT( (*ppObjectInfo)->ObjectReferenceCount == 0);
6348 pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
6352 if ( pObjectInfo == NULL)
6355 try_return( NOTHING);
6358 ASSERT( *ppObjectInfo == NULL);
6360 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6363 pParentObjectInfo = AFSFindObjectInfo( pVolume,
6364 &pObjectInfo->ParentFileId,
6367 if( pParentObjectInfo != NULL)
6370 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6372 AFSAcquireShared( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6375 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6376 AFS_OBJECT_REFERENCE_CHILD);
6378 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6379 AFS_TRACE_LEVEL_VERBOSE,
6380 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6384 AFSReleaseResource( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6386 AFSReleaseObjectInfo( &pParentObjectInfo);
6391 // Remove it from the tree and list if it was inserted
6394 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6397 AFSRemoveHashEntry( &pVolume->ObjectInfoTree.TreeHead,
6398 &pObjectInfo->TreeEntry);
6401 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6404 if( pObjectInfo->ListEntry.fLink == NULL)
6407 pVolume->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6409 if( pVolume->ObjectInfoListTail != NULL)
6412 pVolume->ObjectInfoListTail->ListEntry.fLink = NULL;
6418 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6421 if( pObjectInfo->ListEntry.bLink == NULL)
6424 pVolume->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6426 if( pVolume->ObjectInfoListHead != NULL)
6429 pVolume->ObjectInfoListHead->ListEntry.bLink = NULL;
6435 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6439 bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6444 FileId = pObjectInfo->FileId;
6447 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6449 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6451 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6453 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6455 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6459 if( bAcquiredTreeLock)
6462 AFSReleaseResource( pVolume->ObjectInfoTree.TreeLock);
6466 // Release the fid in the service
6472 AFSReleaseFid( &FileId);
6480 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6481 OUT AFSDirectoryCB **TargetDirEntry)
6484 NTSTATUS ntStatus = STATUS_SUCCESS;
6485 AFSDirEnumEntry *pDirEntry = NULL;
6486 UNICODE_STRING uniFullPathName = {0};
6487 AFSNameArrayHdr *pNameArray = NULL;
6488 AFSVolumeCB *pVolumeCB = NULL;
6489 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6490 AFSVolumeCB *pNewVolumeCB = NULL;
6491 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6492 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6493 AFSDirectoryCB *pNewParentDirEntry = NULL;
6494 WCHAR *pwchBuffer = NULL;
6495 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6496 ULONG ulNameDifference = 0;
6503 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6504 DirectoryCB->ObjectInformation,
6508 if( !NT_SUCCESS( ntStatus))
6510 try_return( ntStatus);
6514 // Retrieve a target name for the entry
6517 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6520 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6523 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6525 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6530 if( !NT_SUCCESS( ntStatus) ||
6531 pDirEntry->TargetNameLength == 0)
6534 if( pDirEntry != NULL)
6537 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6540 try_return( ntStatus);
6543 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6546 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6550 // Update the target name
6553 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6554 &DirectoryCB->Flags,
6555 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6556 (USHORT)pDirEntry->TargetNameLength);
6558 if( !NT_SUCCESS( ntStatus))
6561 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6563 try_return( ntStatus);
6567 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6571 // Need to pass the full path in for parsing.
6574 uniFullPathName.Length = 0;
6575 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6577 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6578 uniFullPathName.MaximumLength,
6579 AFS_NAME_BUFFER_EIGHT_TAG);
6581 if( uniFullPathName.Buffer == NULL)
6584 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6586 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6589 pwchBuffer = uniFullPathName.Buffer;
6591 RtlZeroMemory( uniFullPathName.Buffer,
6592 uniFullPathName.MaximumLength);
6594 RtlCopyMemory( uniFullPathName.Buffer,
6595 DirectoryCB->NameInformation.TargetName.Buffer,
6596 DirectoryCB->NameInformation.TargetName.Length);
6598 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6601 // This name should begin with the \afs server so parse it off and chech it
6604 FsRtlDissectName( uniFullPathName,
6608 if( RtlCompareUnicodeString( &uniComponentName,
6614 // Try evaluating the full path
6617 uniFullPathName.Buffer = pwchBuffer;
6619 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6621 uniFullPathName.MaximumLength = uniFullPathName.Length;
6626 uniFullPathName = uniRemainingPath;
6629 uniParsedName = uniFullPathName;
6631 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6633 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6639 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6642 if( pNameArray == NULL)
6645 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6648 pVolumeCB = AFSGlobalRoot;
6650 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6652 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
6654 lCount = AFSVolumeIncrement( pVolumeCB,
6655 VolumeReferenceReason);
6657 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6658 AFS_TRACE_LEVEL_VERBOSE,
6659 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
6661 VolumeReferenceReason,
6664 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6666 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6667 AFS_TRACE_LEVEL_VERBOSE,
6668 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6669 &pParentDirEntry->NameInformation.FileName,
6674 ntStatus = AFSLocateNameEntry( NULL,
6683 &VolumeReferenceReason,
6684 &pNewParentDirEntry,
6688 if ( pNewVolumeCB != NULL)
6691 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6692 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6693 // the reference on pVolumeCB that was held prior to the call.
6694 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6695 // will be released second.
6698 lCount = AFSVolumeDecrement( pVolumeCB,
6699 VolumeReferenceReason);
6701 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6702 AFS_TRACE_LEVEL_VERBOSE,
6703 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
6705 VolumeReferenceReason,
6708 pVolumeCB = pNewVolumeCB;
6710 pNewVolumeCB = NULL;
6712 VolumeReferenceReason = NewVolumeReferenceReason;
6714 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6718 // AFSLocateNameEntry does not alter the reference count of
6719 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6720 // a reference held.
6723 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6725 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6726 AFS_TRACE_LEVEL_VERBOSE,
6727 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
6728 &pParentDirEntry->NameInformation.FileName,
6732 pParentDirEntry = pNewParentDirEntry;
6734 pNewParentDirEntry = NULL;
6736 if( !NT_SUCCESS( ntStatus) ||
6737 ntStatus == STATUS_REPARSE)
6742 try_return( ntStatus);
6746 // Pass back the target dir entry for this request
6747 // The caller must release the DirOpenReferenceCount
6750 *TargetDirEntry = pDirectoryEntry;
6752 pDirectoryEntry = NULL;
6756 if( pDirectoryEntry != NULL)
6759 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6761 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6762 AFS_TRACE_LEVEL_VERBOSE,
6763 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6764 &pDirectoryEntry->NameInformation.FileName,
6769 ASSERT( lCount >= 0);
6772 if ( pParentDirEntry != NULL)
6775 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6777 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6778 AFS_TRACE_LEVEL_VERBOSE,
6779 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6780 &pParentDirEntry->NameInformation.FileName,
6785 ASSERT( lCount >= 0);
6788 if( pDirEntry != NULL)
6791 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6794 if( pVolumeCB != NULL)
6797 lCount = AFSVolumeDecrement( pVolumeCB,
6798 VolumeReferenceReason);
6800 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6801 AFS_TRACE_LEVEL_VERBOSE,
6802 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
6804 VolumeReferenceReason,
6808 if( pNameArray != NULL)
6811 AFSFreeNameArray( pNameArray);
6814 if( pwchBuffer != NULL)
6818 // Always free the buffer that we allocated as AFSLocateNameEntry
6819 // will not free it. If uniFullPathName.Buffer was allocated by
6820 // AFSLocateNameEntry, then we must free that as well.
6821 // Check that the uniFullPathName.Buffer in the string is not the same
6822 // offset by the length of the server name
6825 if( uniFullPathName.Length > 0 &&
6826 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6829 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6832 AFSExFreePoolWithTag( pwchBuffer, 0);
6840 AFSCleanupFcb( IN AFSFcb *Fcb,
6841 IN BOOLEAN ForceFlush)
6844 NTSTATUS ntStatus = STATUS_SUCCESS;
6845 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6846 LARGE_INTEGER liTime;
6847 IO_STATUS_BLOCK stIoStatus;
6852 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6854 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6856 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6859 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6860 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6863 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6864 AFS_TRACE_LEVEL_VERBOSE,
6865 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
6866 &Fcb->NPFcb->Resource,
6867 PsGetCurrentThread()));
6869 AFSAcquireShared( &Fcb->NPFcb->Resource,
6872 if( Fcb->OpenReferenceCount > 0)
6875 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6876 AFS_TRACE_LEVEL_VERBOSE,
6877 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
6878 &Fcb->NPFcb->SectionObjectResource,
6879 PsGetCurrentThread()));
6881 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
6887 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6892 if( !NT_SUCCESS( stIoStatus.Status))
6895 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6896 AFS_TRACE_LEVEL_ERROR,
6897 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6898 Fcb->ObjectInformation->FileId.Cell,
6899 Fcb->ObjectInformation->FileId.Volume,
6900 Fcb->ObjectInformation->FileId.Vnode,
6901 Fcb->ObjectInformation->FileId.Unique,
6903 stIoStatus.Information));
6905 ntStatus = stIoStatus.Status;
6908 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
6911 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6917 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6918 AFS_TRACE_LEVEL_WARNING,
6919 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
6920 Fcb->ObjectInformation->FileId.Cell,
6921 Fcb->ObjectInformation->FileId.Volume,
6922 Fcb->ObjectInformation->FileId.Vnode,
6923 Fcb->ObjectInformation->FileId.Unique));
6925 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6929 __except( EXCEPTION_EXECUTE_HANDLER)
6932 ntStatus = GetExceptionCode();
6936 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
6937 Fcb->ObjectInformation->FileId.Cell,
6938 Fcb->ObjectInformation->FileId.Volume,
6939 Fcb->ObjectInformation->FileId.Vnode,
6940 Fcb->ObjectInformation->FileId.Unique,
6943 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6946 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6947 AFS_TRACE_LEVEL_VERBOSE,
6948 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
6949 &Fcb->NPFcb->SectionObjectResource,
6950 PsGetCurrentThread()));
6952 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
6955 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6956 AFS_TRACE_LEVEL_VERBOSE,
6957 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
6958 &Fcb->NPFcb->Resource,
6959 PsGetCurrentThread()));
6961 AFSReleaseResource( &Fcb->NPFcb->Resource);
6964 // Wait for any currently running flush or release requests to complete
6967 AFSWaitOnQueuedFlushes( Fcb);
6970 // Now perform another flush on the file
6973 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6977 AFSReleaseExtentsWithFlush( Fcb,
6983 if( Fcb->OpenReferenceCount == 0 ||
6984 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6985 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6988 AFSTearDownFcbExtents( Fcb,
6992 try_return( ntStatus);
6995 KeQueryTickCount( &liTime);
6998 // First up are there dirty extents in the cache to flush?
7001 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7002 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7006 // The file has been marked as invalid. Dump it
7009 AFSTearDownFcbExtents( Fcb,
7012 else if( ForceFlush ||
7013 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7014 Fcb->Specific.File.ExtentCount) &&
7015 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7016 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7018 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7020 Fcb->OpenReferenceCount == 0)
7023 AFSReleaseExtentsWithFlush( Fcb,
7030 // If there are extents and they haven't been used recently *and*
7031 // are not being used
7035 ( 0 != Fcb->Specific.File.ExtentCount &&
7036 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7037 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7038 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7041 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7042 AFS_TRACE_LEVEL_VERBOSE,
7043 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7044 &Fcb->NPFcb->SectionObjectResource,
7045 PsGetCurrentThread()));
7047 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7053 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7058 if( !NT_SUCCESS( stIoStatus.Status))
7061 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7062 AFS_TRACE_LEVEL_ERROR,
7063 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7064 Fcb->ObjectInformation->FileId.Cell,
7065 Fcb->ObjectInformation->FileId.Volume,
7066 Fcb->ObjectInformation->FileId.Vnode,
7067 Fcb->ObjectInformation->FileId.Unique,
7069 stIoStatus.Information));
7071 ntStatus = stIoStatus.Status;
7075 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7078 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7084 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7085 AFS_TRACE_LEVEL_WARNING,
7086 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7087 Fcb->ObjectInformation->FileId.Cell,
7088 Fcb->ObjectInformation->FileId.Volume,
7089 Fcb->ObjectInformation->FileId.Vnode,
7090 Fcb->ObjectInformation->FileId.Unique));
7092 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7096 __except( EXCEPTION_EXECUTE_HANDLER)
7099 ntStatus = GetExceptionCode();
7103 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7104 Fcb->ObjectInformation->FileId.Cell,
7105 Fcb->ObjectInformation->FileId.Volume,
7106 Fcb->ObjectInformation->FileId.Vnode,
7107 Fcb->ObjectInformation->FileId.Unique,
7111 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7112 AFS_TRACE_LEVEL_VERBOSE,
7113 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7114 &Fcb->NPFcb->SectionObjectResource,
7115 PsGetCurrentThread()));
7117 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7119 if( Fcb->OpenReferenceCount <= 0)
7123 // Tear em down we'll not be needing them again
7126 AFSTearDownFcbExtents( Fcb,
7133 ntStatus = STATUS_RETRY;
7146 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7147 IN UNICODE_STRING *NewFileName)
7150 NTSTATUS ntStatus = STATUS_SUCCESS;
7151 WCHAR *pTmpBuffer = NULL;
7156 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7159 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7162 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7164 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7166 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7170 // OK, we need to allocate a new name buffer
7173 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7174 NewFileName->Length,
7175 AFS_NAME_BUFFER_NINE_TAG);
7177 if( pTmpBuffer == NULL)
7180 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7183 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7185 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7187 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7190 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7192 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7193 NewFileName->Buffer,
7194 NewFileName->Length);
7205 AFSReadCacheFile( IN void *ReadBuffer,
7206 IN LARGE_INTEGER *ReadOffset,
7207 IN ULONG RequestedDataLength,
7208 IN OUT PULONG BytesRead)
7211 NTSTATUS ntStatus = STATUS_SUCCESS;
7214 PIO_STACK_LOCATION pIoStackLocation = NULL;
7215 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7216 FILE_OBJECT *pCacheFileObject = NULL;
7221 pCacheFileObject = AFSReferenceCacheFileObject();
7223 if( pCacheFileObject == NULL)
7225 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7228 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7231 // Initialize the event
7234 KeInitializeEvent( &kEvent,
7235 SynchronizationEvent,
7239 // Allocate an irp for this request. This could also come from a
7240 // private pool, for instance.
7243 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7249 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7253 // Build the IRP's main body
7256 pIrp->UserBuffer = ReadBuffer;
7258 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7259 pIrp->RequestorMode = KernelMode;
7260 pIrp->Flags |= IRP_READ_OPERATION;
7263 // Set up the I/O stack location.
7266 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7267 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7268 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7269 pIoStackLocation->FileObject = pCacheFileObject;
7270 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7272 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7275 // Set the completion routine.
7278 IoSetCompletionRoutine( pIrp,
7286 // Send it to the FSD
7289 ntStatus = IoCallDriver( pTargetDeviceObject,
7292 if( NT_SUCCESS( ntStatus))
7299 ntStatus = KeWaitForSingleObject( &kEvent,
7305 if( NT_SUCCESS( ntStatus))
7308 ntStatus = pIrp->IoStatus.Status;
7310 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7316 if( pCacheFileObject != NULL)
7318 AFSReleaseCacheFileObject( pCacheFileObject);
7324 if( pIrp->MdlAddress != NULL)
7327 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7330 MmUnlockPages( pIrp->MdlAddress);
7333 IoFreeMdl( pIrp->MdlAddress);
7336 pIrp->MdlAddress = NULL;
7350 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7355 UNREFERENCED_PARAMETER(Irp);
7356 UNREFERENCED_PARAMETER(DeviceObject);
7357 KEVENT *pEvent = (KEVENT *)Context;
7363 return STATUS_MORE_PROCESSING_REQUIRED;
7367 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7370 BOOLEAN bIsEmpty = FALSE;
7371 AFSDirectoryCB *pDirEntry = NULL;
7376 ASSERT( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY);
7378 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7383 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7386 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7388 while( pDirEntry != NULL)
7391 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7392 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7400 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7405 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7412 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7413 IN AFSDirectoryCB *DirEntry)
7416 NTSTATUS ntStatus = STATUS_SUCCESS;
7421 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7424 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7425 AFS_TRACE_LEVEL_VERBOSE,
7426 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7428 &DirEntry->NameInformation.FileName));
7430 try_return( ntStatus);
7433 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7436 // Remove the entry from the parent tree
7439 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7440 AFS_TRACE_LEVEL_VERBOSE,
7441 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7443 &DirEntry->NameInformation.FileName));
7445 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7448 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7449 AFS_TRACE_LEVEL_VERBOSE,
7450 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7452 &DirEntry->NameInformation.FileName));
7454 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7457 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7461 // From the short name tree
7464 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7465 AFS_TRACE_LEVEL_VERBOSE,
7466 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7468 &DirEntry->NameInformation.FileName));
7470 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7473 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7476 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7477 AFS_TRACE_LEVEL_VERBOSE,
7478 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7480 &DirEntry->NameInformation.FileName));
7482 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7484 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7495 AFSGetAuthenticationId()
7498 LARGE_INTEGER liAuthId = {0,0};
7499 NTSTATUS ntStatus = STATUS_SUCCESS;
7500 PACCESS_TOKEN hToken = NULL;
7501 PTOKEN_STATISTICS pTokenInfo = NULL;
7502 BOOLEAN bCopyOnOpen = FALSE;
7503 BOOLEAN bEffectiveOnly = FALSE;
7504 BOOLEAN bPrimaryToken = FALSE;
7505 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7510 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7513 &stImpersonationLevel);
7518 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7523 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7524 AFS_TRACE_LEVEL_ERROR,
7525 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
7527 try_return( ntStatus);
7530 bPrimaryToken = TRUE;
7533 ntStatus = SeQueryInformationToken( hToken,
7535 (PVOID *)&pTokenInfo);
7537 if( !NT_SUCCESS( ntStatus))
7540 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7541 AFS_TRACE_LEVEL_ERROR,
7542 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
7545 try_return( ntStatus);
7548 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7549 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7551 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7552 AFS_TRACE_LEVEL_VERBOSE,
7553 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7554 liAuthId.QuadPart));
7564 PsDereferenceImpersonationToken( hToken);
7569 PsDereferencePrimaryToken( hToken);
7573 if( pTokenInfo != NULL)
7576 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7584 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7588 UNREFERENCED_PARAMETER(Fcb);
7589 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7591 Fcb->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7594 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7596 Fcb->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7599 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7601 Fcb->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7604 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7606 Fcb->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7609 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7611 Fcb->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7618 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7621 BOOLEAN bIsValid = TRUE;
7623 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7625 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7627 while( pCurrentDirEntry != NULL)
7630 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7634 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7639 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7640 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7643 if( pDirEntry == NULL)
7650 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7653 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
7656 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7658 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7660 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7669 AFSReferenceCacheFileObject()
7672 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7673 FILE_OBJECT *pCacheFileObject = NULL;
7675 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7678 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7680 if( pCacheFileObject != NULL)
7682 ObReferenceObject( pCacheFileObject);
7685 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7687 return pCacheFileObject;
7691 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7694 ASSERT( CacheFileObject != NULL);
7696 ObDereferenceObject( CacheFileObject);
7702 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7705 NTSTATUS ntStatus = STATUS_SUCCESS;
7706 AFSDeviceExt *pControlDevExt = NULL;
7707 ULONG ulTimeIncrement = 0;
7713 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7715 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7717 AFSServerName = LibraryInit->AFSServerName;
7719 AFSMountRootName = LibraryInit->AFSMountRootName;
7721 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7724 // Callbacks in the framework
7727 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7729 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7731 AFSDebugTraceFnc = AFSDbgLogMsg;
7733 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7735 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7737 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
7739 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7741 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7743 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7745 if( LibraryInit->AFSCacheBaseAddress != NULL)
7748 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7750 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7752 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7756 // Initialize some flush parameters
7759 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7761 ulTimeIncrement = KeQueryTimeIncrement();
7763 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7764 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7765 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7766 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7767 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7770 // Initialize the global root entry
7773 ntStatus = AFSInitVolume( NULL,
7774 &LibraryInit->GlobalRootFid,
7775 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
7778 if( !NT_SUCCESS( ntStatus))
7781 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7782 AFS_TRACE_LEVEL_ERROR,
7783 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7786 try_return( ntStatus);
7789 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7792 if( !NT_SUCCESS( ntStatus))
7795 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7796 AFS_TRACE_LEVEL_ERROR,
7797 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7800 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7801 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7803 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7804 AFS_TRACE_LEVEL_VERBOSE,
7805 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7809 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7811 try_return( ntStatus);
7815 // Update the node type code to AFS_ROOT_ALL
7818 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7820 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7823 // Invalidate all known volumes since contact with the service and therefore
7824 // the file server was lost.
7827 AFSInvalidateAllVolumes();
7830 // Drop the locks acquired above
7833 AFSInitVolumeWorker( AFSGlobalRoot);
7835 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7836 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7838 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7839 AFS_TRACE_LEVEL_VERBOSE,
7840 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7844 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7846 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7860 NTSTATUS ntStatus = STATUS_SUCCESS;
7861 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7867 if( AFSGlobalDotDirEntry != NULL)
7870 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
7871 AFS_OBJECT_REFERENCE_GLOBAL);
7873 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7874 AFS_TRACE_LEVEL_VERBOSE,
7875 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7876 AFSGlobalDotDirEntry->ObjectInformation,
7882 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
7885 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7887 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry->NonPaged,
7888 AFS_DIR_ENTRY_NP_TAG);
7890 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry,
7893 AFSGlobalDotDirEntry = NULL;
7896 if( AFSGlobalDotDotDirEntry != NULL)
7899 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
7900 AFS_OBJECT_REFERENCE_GLOBAL);
7902 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7903 AFS_TRACE_LEVEL_VERBOSE,
7904 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7905 AFSGlobalDotDotDirEntry->ObjectInformation,
7911 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
7914 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7916 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry->NonPaged,
7917 AFS_DIR_ENTRY_NP_TAG);
7919 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry,
7922 AFSGlobalDotDotDirEntry = NULL;
7925 if( AFSSpecialShareNames != NULL)
7928 pDirNode = AFSSpecialShareNames;
7930 while( pDirNode != NULL)
7933 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7935 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
7936 AFS_OBJECT_REFERENCE_GLOBAL);
7938 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7939 AFS_TRACE_LEVEL_VERBOSE,
7940 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7941 pDirNode->ObjectInformation,
7947 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
7950 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7952 AFSLibExFreePoolWithTag( pDirNode->NonPaged,
7953 AFS_DIR_ENTRY_NP_TAG);
7955 AFSLibExFreePoolWithTag( pDirNode,
7958 pDirNode = pLastDirNode;
7961 AFSSpecialShareNames = NULL;
7969 AFSDefaultLogMsg( IN ULONG Subsystem,
7975 UNREFERENCED_PARAMETER(Subsystem);
7976 UNREFERENCED_PARAMETER(Level);
7977 NTSTATUS ntStatus = STATUS_SUCCESS;
7979 char chDebugBuffer[ 256];
7984 va_start( va_args, Format);
7986 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7991 if( NT_SUCCESS( ntStatus))
7993 DbgPrint( chDebugBuffer);
8003 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8004 IN ULONG InputBufferLength,
8005 IN AFSStatusInfoCB *StatusInfo,
8006 OUT ULONG *ReturnLength)
8009 NTSTATUS ntStatus = STATUS_SUCCESS;
8010 AFSVolumeCB *pVolumeCB = NULL;
8011 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8012 AFSVolumeCB *pNewVolumeCB = NULL;
8013 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8014 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8015 AFSObjectInfoCB *pObjectInfo = NULL;
8016 ULONGLONG ullIndex = 0;
8017 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8018 AFSNameArrayHdr *pNameArray = NULL;
8019 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8020 AFSDirectoryCB *pNewParentDirEntry = NULL;
8027 // If we are given a FID then look up the entry by that, otherwise
8031 if( GetStatusInfo->FileID.Cell != 0 &&
8032 GetStatusInfo->FileID.Volume != 0 &&
8033 GetStatusInfo->FileID.Vnode != 0 &&
8034 GetStatusInfo->FileID.Unique != 0)
8037 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8040 // Locate the volume node
8043 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8045 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8047 (AFSBTreeEntry **)&pVolumeCB);
8049 if( pVolumeCB != NULL)
8052 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8054 lCount = AFSVolumeIncrement( pVolumeCB,
8055 VolumeReferenceReason);
8057 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8058 AFS_TRACE_LEVEL_VERBOSE,
8059 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
8061 VolumeReferenceReason,
8065 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8067 if( !NT_SUCCESS( ntStatus) ||
8070 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8073 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8076 pObjectInfo = &pVolumeCB->ObjectInformation;
8078 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8081 lCount = AFSObjectInfoIncrement( pObjectInfo,
8082 AFS_OBJECT_REFERENCE_STATUS);
8084 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8085 AFS_TRACE_LEVEL_VERBOSE,
8086 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8090 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8095 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
8098 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8100 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8102 (AFSBTreeEntry **)&pObjectInfo);
8104 if( pObjectInfo != NULL)
8108 // Reference the node so it won't be torn down
8111 lCount = AFSObjectInfoIncrement( pObjectInfo,
8112 AFS_OBJECT_REFERENCE_STATUS);
8114 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8115 AFS_TRACE_LEVEL_VERBOSE,
8116 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8120 KeQueryTickCount( &pObjectInfo->LastAccessCount);
8123 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8125 if( !NT_SUCCESS( ntStatus) ||
8126 pObjectInfo == NULL)
8128 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8135 if( GetStatusInfo->FileNameLength == 0 ||
8136 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8138 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8141 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8142 uniFullPathName.MaximumLength = uniFullPathName.Length;
8144 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8147 // This name should begin with the \afs server so parse it off and check it
8150 FsRtlDissectName( uniFullPathName,
8154 if( RtlCompareUnicodeString( &uniComponentName,
8158 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8159 AFS_TRACE_LEVEL_ERROR,
8160 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8163 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8166 uniFullPathName = uniRemainingPath;
8168 uniParsedName = uniFullPathName;
8174 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8177 if( pNameArray == NULL)
8179 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8182 pVolumeCB = AFSGlobalRoot;
8184 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8187 // Increment the ref count on the volume and dir entry for correct processing below
8190 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8192 lCount = AFSVolumeIncrement( pVolumeCB,
8193 VolumeReferenceReason);
8195 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8196 AFS_TRACE_LEVEL_VERBOSE,
8197 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8199 VolumeReferenceReason,
8202 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8204 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8205 AFS_TRACE_LEVEL_VERBOSE,
8206 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8207 &pParentDirEntry->NameInformation.FileName,
8212 ntStatus = AFSLocateNameEntry( NULL,
8217 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8218 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8222 &NewVolumeReferenceReason,
8223 &pNewParentDirEntry,
8227 if ( pNewVolumeCB != NULL)
8231 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8232 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8233 // the reference on pVolumeCB that was held prior to the call.
8234 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8235 // will be released second.
8238 lCount = AFSVolumeDecrement( pVolumeCB,
8239 VolumeReferenceReason);
8241 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8242 AFS_TRACE_LEVEL_VERBOSE,
8243 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8245 VolumeReferenceReason,
8248 pVolumeCB = pNewVolumeCB;
8250 pNewVolumeCB = NULL;
8252 VolumeReferenceReason = NewVolumeReferenceReason;
8254 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8258 // AFSLocateNameEntry does not alter the reference count of
8259 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8260 // a reference held.
8263 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8265 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8266 AFS_TRACE_LEVEL_VERBOSE,
8267 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8268 &pParentDirEntry->NameInformation.FileName,
8272 pParentDirEntry = pNewParentDirEntry;
8274 pNewParentDirEntry = NULL;
8276 if( !NT_SUCCESS( ntStatus) ||
8277 ntStatus == STATUS_REPARSE)
8282 try_return( ntStatus);
8285 pObjectInfo = pDirectoryEntry->ObjectInformation;
8287 AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
8290 lCount = AFSObjectInfoIncrement( pObjectInfo,
8291 AFS_OBJECT_REFERENCE_STATUS);
8293 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8294 AFS_TRACE_LEVEL_VERBOSE,
8295 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8299 AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
8303 // At this point we have an object info block, return the information
8306 StatusInfo->FileId = pObjectInfo->FileId;
8308 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8310 StatusInfo->Expiration = pObjectInfo->Expiration;
8312 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8314 StatusInfo->FileType = pObjectInfo->FileType;
8316 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8318 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8320 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8322 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8324 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8326 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8328 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8330 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8332 StatusInfo->EaSize = pObjectInfo->EaSize;
8334 StatusInfo->Links = pObjectInfo->Links;
8337 // Return the information length
8340 *ReturnLength = sizeof( AFSStatusInfoCB);
8344 if( pDirectoryEntry != NULL)
8347 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8349 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8350 AFS_TRACE_LEVEL_VERBOSE,
8351 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8352 &pDirectoryEntry->NameInformation.FileName,
8357 ASSERT( lCount >= 0);
8360 if ( pParentDirEntry != NULL)
8363 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8365 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8366 AFS_TRACE_LEVEL_VERBOSE,
8367 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8368 &pParentDirEntry->NameInformation.FileName,
8373 ASSERT( lCount >= 0);
8376 if( pVolumeCB != NULL)
8379 if( pObjectInfo != NULL)
8382 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8385 lCount = AFSObjectInfoDecrement( pObjectInfo,
8386 AFS_OBJECT_REFERENCE_STATUS);
8388 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8389 AFS_TRACE_LEVEL_VERBOSE,
8390 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8394 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8397 lCount = AFSVolumeDecrement( pVolumeCB,
8398 VolumeReferenceReason);
8400 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8401 AFS_TRACE_LEVEL_VERBOSE,
8402 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8404 VolumeReferenceReason,
8408 if( pNameArray != NULL)
8411 AFSFreeNameArray( pNameArray);
8419 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8420 IN UNICODE_STRING *ComponentName)
8423 NTSTATUS ntStatus = STATUS_SUCCESS;
8424 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8425 AFSDirectoryCB *pDirEntry = NULL;
8433 // Search for the entry in the parent
8436 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8437 AFS_TRACE_LEVEL_VERBOSE_2,
8438 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8441 ulCRC = AFSGenerateCRC( ComponentName,
8444 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8447 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8451 if( pDirEntry == NULL)
8455 // Missed so perform a case insensitive lookup
8458 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8459 AFS_TRACE_LEVEL_VERBOSE_2,
8460 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8463 ulCRC = AFSGenerateCRC( ComponentName,
8466 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8470 if( pDirEntry == NULL)
8474 // OK, if this component is a valid short name then try
8475 // a lookup in the short name tree
8478 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8479 RtlIsNameLegalDOS8Dot3( ComponentName,
8484 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8485 AFS_TRACE_LEVEL_VERBOSE_2,
8486 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8489 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8496 if( pDirEntry != NULL)
8498 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8500 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8501 AFS_TRACE_LEVEL_VERBOSE,
8502 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8503 &pDirEntry->NameInformation.FileName,
8508 ASSERT( lCount >= 0);
8511 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8513 if( pDirEntry == NULL)
8516 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8517 AFS_TRACE_LEVEL_VERBOSE_2,
8518 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8520 STATUS_OBJECT_NAME_NOT_FOUND));
8522 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8526 // We have the symlink object but previously failed to process it so return access
8530 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8531 AFS_TRACE_LEVEL_VERBOSE_2,
8532 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8535 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8537 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8539 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8540 AFS_TRACE_LEVEL_VERBOSE,
8541 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8542 &pDirEntry->NameInformation.FileName,
8547 ASSERT( lCount >= 0);
8558 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8559 OUT UNICODE_STRING *ComponentName)
8562 NTSTATUS ntStatus = STATUS_SUCCESS;
8563 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8565 uniFullPathName = *FullPathName;
8570 FsRtlDissectName( uniFullPathName,
8574 if( uniRemainingPath.Length == 0)
8579 uniFullPathName = uniRemainingPath;
8582 if( uniComponentName.Length > 0)
8584 *ComponentName = uniComponentName;
8591 AFSDumpTraceFiles_Default()
8597 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8600 BOOLEAN bIsValidName = TRUE;
8606 while( usIndex < FileName->Length/sizeof( WCHAR))
8609 if( FileName->Buffer[ usIndex] == L':' ||
8610 FileName->Buffer[ usIndex] == L'*' ||
8611 FileName->Buffer[ usIndex] == L'?' ||
8612 FileName->Buffer[ usIndex] == L'"' ||
8613 FileName->Buffer[ usIndex] == L'<' ||
8614 FileName->Buffer[ usIndex] == L'>')
8616 bIsValidName = FALSE;
8624 return bIsValidName;
8628 AFSCreateDefaultSecurityDescriptor()
8631 NTSTATUS ntStatus = STATUS_SUCCESS;
8633 ULONG ulSACLSize = 0;
8634 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8635 ULONG ulACESize = 0;
8636 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8637 ULONG ulSDLength = 0;
8638 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8639 PSID pWorldSID = NULL;
8640 ULONG *pulSubAuthority = NULL;
8641 ULONG ulWorldSIDLEngth = 0;
8646 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8648 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8650 AFS_GENERIC_MEMORY_29_TAG);
8652 if( pWorldSID == NULL)
8654 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8656 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8659 RtlZeroMemory( pWorldSID,
8662 RtlInitializeSid( pWorldSID,
8663 &SeWorldSidAuthority,
8666 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8667 *pulSubAuthority = SECURITY_WORLD_RID;
8669 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8672 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8677 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8679 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8681 AFS_GENERIC_MEMORY_29_TAG);
8686 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8688 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8691 RtlZeroMemory( pACE,
8694 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8695 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8696 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8697 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8699 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8701 SeExports->SeLowMandatorySid);
8703 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8704 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8706 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8708 AFS_GENERIC_MEMORY_29_TAG);
8713 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8715 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8718 ntStatus = RtlCreateAcl( pSACL,
8722 if( !NT_SUCCESS( ntStatus))
8725 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8728 try_return( ntStatus);
8731 ntStatus = RtlAddAce( pSACL,
8735 pACE->Header.AceSize);
8737 if( !NT_SUCCESS( ntStatus))
8740 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8743 try_return( ntStatus);
8747 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8748 sizeof( SECURITY_DESCRIPTOR),
8749 AFS_GENERIC_MEMORY_27_TAG);
8751 if( pSecurityDescr == NULL)
8754 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8756 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8759 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8760 SECURITY_DESCRIPTOR_REVISION);
8762 if( !NT_SUCCESS( ntStatus))
8765 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8768 try_return( ntStatus);
8771 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8773 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8778 if( !NT_SUCCESS( ntStatus))
8781 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8784 try_return( ntStatus);
8789 // Add in the group and owner to the SD
8792 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8794 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8798 if( !NT_SUCCESS( ntStatus))
8801 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8804 try_return( ntStatus);
8808 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8812 if( !NT_SUCCESS( ntStatus))
8815 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8818 try_return( ntStatus);
8821 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8824 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8826 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8829 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)AFSLibExAllocatePoolWithTag( NonPagedPool,
8831 AFS_GENERIC_MEMORY_27_TAG);
8833 if( pRelativeSecurityDescr == NULL)
8836 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8838 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8841 ulSDLength = PAGE_SIZE;
8843 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8844 pRelativeSecurityDescr,
8847 if( !NT_SUCCESS( ntStatus))
8850 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8853 try_return( ntStatus);
8856 AFSDefaultSD = pRelativeSecurityDescr;
8860 if( !NT_SUCCESS( ntStatus))
8863 if( pRelativeSecurityDescr != NULL)
8866 AFSLibExFreePoolWithTag( pRelativeSecurityDescr,
8867 AFS_GENERIC_MEMORY_27_TAG);
8871 if( pSecurityDescr != NULL)
8874 AFSLibExFreePoolWithTag( pSecurityDescr,
8875 AFS_GENERIC_MEMORY_27_TAG);
8881 AFSLibExFreePoolWithTag( pSACL,
8882 AFS_GENERIC_MEMORY_29_TAG);
8888 AFSLibExFreePoolWithTag( pACE,
8889 AFS_GENERIC_MEMORY_29_TAG);
8892 if( pWorldSID != NULL)
8895 AFSLibExFreePoolWithTag( pWorldSID,
8896 AFS_GENERIC_MEMORY_29_TAG);
8904 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8905 OUT UNICODE_STRING *ParentPath)
8908 *ParentPath = *FullFileName;
8911 // If the final character is a \, jump over it
8914 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8916 ParentPath->Length -= sizeof( WCHAR);
8919 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8921 ParentPath->Length -= sizeof( WCHAR);
8925 // And the separator
8928 ParentPath->Length -= sizeof( WCHAR);
8934 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8935 IN AFSObjectInfoCB *ObjectInfo,
8936 IN BOOLEAN WriteAccess,
8937 OUT GUID *AuthGroup)
8940 NTSTATUS ntStatus = STATUS_SUCCESS;
8941 GUID stAuthGroup, stZeroAuthGroup;
8942 BOOLEAN bFoundAuthGroup = FALSE;
8943 AFSCcb *pCcb = NULL;
8949 RtlZeroMemory( &stAuthGroup,
8952 RtlZeroMemory( &stZeroAuthGroup,
8958 if( ObjectInfo != NULL &&
8959 ObjectInfo->Fcb != NULL)
8961 pFcb = ObjectInfo->Fcb;
8968 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8971 pCcb = Fcb->CcbListHead;
8973 while( pCcb != NULL)
8977 pCcb->GrantedAccess & FILE_WRITE_DATA)
8979 RtlCopyMemory( &stAuthGroup,
8983 bFoundAuthGroup = TRUE;
8987 else if( pCcb->GrantedAccess & FILE_READ_DATA)
8990 // At least get the read-only access
8993 RtlCopyMemory( &stAuthGroup,
8997 bFoundAuthGroup = TRUE;
9000 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9003 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9006 if( !bFoundAuthGroup)
9009 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9010 (ULONGLONG)PsGetCurrentThreadId(),
9013 if( RtlCompareMemory( &stZeroAuthGroup,
9015 sizeof( GUID)) == sizeof( GUID))
9018 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9020 try_return( ntStatus = STATUS_ACCESS_DENIED);
9024 RtlCopyMemory( AuthGroup,
9037 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9038 IN ULONG InvalidateReason)
9041 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
9042 NTSTATUS ntStatus = STATUS_SUCCESS;
9045 ULONG ulProcessCount = 0;
9052 switch( InvalidateReason)
9055 case AFS_INVALIDATE_DELETED:
9058 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9059 ObjectInfo->Fcb != NULL)
9062 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9065 ObjectInfo->Links = 0;
9067 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9069 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9074 // Clear out the extents
9075 // And get rid of them (note this involves waiting
9076 // for any writes or reads to the cache to complete)
9079 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9082 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9088 case AFS_INVALIDATE_DATA_VERSION:
9091 LARGE_INTEGER liCurrentOffset = {0,0};
9092 LARGE_INTEGER liFlushLength = {0,0};
9093 ULONG ulFlushLength = 0;
9094 BOOLEAN bLocked = FALSE;
9095 BOOLEAN bExtentsLocked = FALSE;
9096 BOOLEAN bCleanExtents = FALSE;
9098 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9099 ObjectInfo->Fcb != NULL)
9102 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9107 if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
9110 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9111 AFS_TRACE_LEVEL_VERBOSE,
9112 "AFSPerformObjectInvalidation DirectIO Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9113 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9114 PsGetCurrentThread()));
9116 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9119 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9126 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9127 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9133 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9134 AFS_TRACE_LEVEL_WARNING,
9135 "AFSPerformObjectInvalidation DirectIO CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9136 ObjectInfo->FileId.Cell,
9137 ObjectInfo->FileId.Volume,
9138 ObjectInfo->FileId.Vnode,
9139 ObjectInfo->FileId.Unique));
9141 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9146 bCleanExtents = TRUE;
9149 __except( EXCEPTION_EXECUTE_HANDLER)
9152 ntStatus = GetExceptionCode();
9156 "EXCEPTION - AFSPerformObjectInvalidation DirectIO FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9157 ObjectInfo->FileId.Cell,
9158 ObjectInfo->FileId.Volume,
9159 ObjectInfo->FileId.Vnode,
9160 ObjectInfo->FileId.Unique,
9163 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9166 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9167 AFS_TRACE_LEVEL_VERBOSE,
9168 "AFSPerformObjectInvalidation DirectIO Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9169 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9170 PsGetCurrentThread()));
9172 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9177 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9178 AFS_TRACE_LEVEL_VERBOSE,
9179 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9180 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9181 PsGetCurrentThread()));
9183 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9186 bExtentsLocked = TRUE;
9189 // There are several possibilities here:
9191 // 0. If there are no extents or all of the extents are dirty, do nothing.
9193 // 1. There could be nothing dirty and an open reference count of zero
9194 // in which case we can just tear down all of the extents without
9195 // holding any resources.
9197 // 2. There could be nothing dirty and a non-zero open reference count
9198 // in which case we can issue a CcPurge against the entire file
9199 // while holding just the Fcb Resource.
9201 // 3. There can be dirty extents in which case we need to identify
9202 // the non-dirty ranges and then perform a CcPurge on just the
9203 // non-dirty ranges while holding just the Fcb Resource.
9206 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9209 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9212 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9214 bExtentsLocked = FALSE;
9216 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9219 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9223 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9229 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9230 AFS_TRACE_LEVEL_VERBOSE,
9231 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9232 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9233 PsGetCurrentThread()));
9235 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9238 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9245 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9246 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9252 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9253 AFS_TRACE_LEVEL_WARNING,
9254 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9255 ObjectInfo->FileId.Cell,
9256 ObjectInfo->FileId.Volume,
9257 ObjectInfo->FileId.Vnode,
9258 ObjectInfo->FileId.Unique));
9260 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9265 bCleanExtents = TRUE;
9268 __except( EXCEPTION_EXECUTE_HANDLER)
9271 ntStatus = GetExceptionCode();
9275 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9276 ObjectInfo->FileId.Cell,
9277 ObjectInfo->FileId.Volume,
9278 ObjectInfo->FileId.Vnode,
9279 ObjectInfo->FileId.Unique,
9282 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9285 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9286 AFS_TRACE_LEVEL_VERBOSE,
9287 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9288 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9289 PsGetCurrentThread()));
9291 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9297 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9299 bExtentsLocked = FALSE;
9301 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9302 AFS_TRACE_LEVEL_VERBOSE,
9303 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9304 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9305 PsGetCurrentThread()));
9307 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9310 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9315 // Must build a list of non-dirty ranges from the beginning of the file
9316 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9317 // ranges. In all but the most extreme random data write scenario there will
9318 // be significantly fewer.
9320 // For each range we need offset and size.
9323 AFSByteRange * ByteRangeList = NULL;
9324 ULONG ulByteRangeCount = 0;
9326 BOOLEAN bPurgeOnClose = FALSE;
9331 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9334 if ( ByteRangeList != NULL ||
9335 ulByteRangeCount == 0)
9338 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9345 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9347 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9348 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9349 &ByteRangeList[ulIndex].FileOffset,
9354 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9355 AFS_TRACE_LEVEL_WARNING,
9356 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9357 ObjectInfo->FileId.Cell,
9358 ObjectInfo->FileId.Volume,
9359 ObjectInfo->FileId.Vnode,
9360 ObjectInfo->FileId.Unique));
9362 bPurgeOnClose = TRUE;
9367 bCleanExtents = TRUE;
9370 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9372 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9374 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9381 // We couldn't allocate the memory to build the purge list
9382 // so just walk the extent list while holding the ExtentsList Resource.
9383 // This could deadlock but we do not have much choice.
9386 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9388 bExtentsLocked = TRUE;
9390 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9394 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9398 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9400 while( ulProcessCount < ulCount)
9402 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9404 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9406 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9407 &pEntry->FileOffset,
9412 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9413 AFS_TRACE_LEVEL_WARNING,
9414 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9415 ObjectInfo->FileId.Cell,
9416 ObjectInfo->FileId.Volume,
9417 ObjectInfo->FileId.Vnode,
9418 ObjectInfo->FileId.Unique));
9420 bPurgeOnClose = TRUE;
9425 bCleanExtents = TRUE;
9429 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9432 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9434 while( liFlushLength.QuadPart > 0)
9437 if( liFlushLength.QuadPart > 512 * 1024000)
9439 ulFlushLength = 512 * 1024000;
9443 ulFlushLength = liFlushLength.LowPart;
9446 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9452 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9453 AFS_TRACE_LEVEL_WARNING,
9454 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9455 ObjectInfo->FileId.Cell,
9456 ObjectInfo->FileId.Volume,
9457 ObjectInfo->FileId.Vnode,
9458 ObjectInfo->FileId.Unique));
9460 bPurgeOnClose = TRUE;
9465 bCleanExtents = TRUE;
9468 liFlushLength.QuadPart -= ulFlushLength;
9472 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9480 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9486 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9487 AFS_TRACE_LEVEL_WARNING,
9488 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9489 ObjectInfo->FileId.Cell,
9490 ObjectInfo->FileId.Volume,
9491 ObjectInfo->FileId.Vnode,
9492 ObjectInfo->FileId.Unique));
9494 bPurgeOnClose = TRUE;
9499 bCleanExtents = TRUE;
9506 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9510 __except( EXCEPTION_EXECUTE_HANDLER)
9513 ntStatus = GetExceptionCode();
9517 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9518 ObjectInfo->FileId.Cell,
9519 ObjectInfo->FileId.Volume,
9520 ObjectInfo->FileId.Vnode,
9521 ObjectInfo->FileId.Unique,
9525 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9526 AFS_TRACE_LEVEL_VERBOSE,
9527 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9528 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9529 PsGetCurrentThread()));
9531 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9535 if ( bExtentsLocked)
9538 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9545 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9551 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9561 // Destroy the reference passed in by the caller to AFSInvalidateObject
9562 // or AFSQueueInvalidateObject
9565 AFSAcquireShared( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
9568 lCount = AFSObjectInfoDecrement( ObjectInfo,
9569 AFS_OBJECT_REFERENCE_INVALIDATION);
9571 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9572 AFS_TRACE_LEVEL_VERBOSE,
9573 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",
9577 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
9584 AFSIgnoreReparsePointToFile( void)
9586 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
9587 BOOLEAN bIgnoreReparsePoint;
9591 bIgnoreReparsePoint = BooleanFlagOn( pDeviceExt->Specific.RDR.ReparsePointPolicy,
9592 AFS_REPARSE_POINT_TO_FILE_AS_FILE);
9595 return bIgnoreReparsePoint;