2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2012, 2013 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
16 * nor the names of their contributors may be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission from Kernel Drivers, LLC and Your File System, Inc.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 // File: AFSGeneric.cpp
37 #include "AFSCommon.h"
40 // Function: AFSExceptionFilter
44 // This function is the exception handler
48 // A status is returned for the function
52 AFSExceptionFilter( IN CHAR *FunctionString,
54 IN PEXCEPTION_POINTERS ExceptPtrs)
57 UNREFERENCED_PARAMETER(Code);
58 PEXCEPTION_RECORD ExceptRec;
64 ExceptRec = ExceptPtrs->ExceptionRecord;
66 Context = ExceptPtrs->ContextRecord;
70 "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
74 ExceptRec->ExceptionCode,
75 ExceptRec->ExceptionAddress,
76 (void *)AFSExceptionFilter));
78 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
80 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
81 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
83 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
85 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
88 KeBugCheck( (ULONG)-2);
96 __except( EXCEPTION_EXECUTE_HANDLER)
102 return EXCEPTION_EXECUTE_HANDLER;
106 // Function: AFSLibExAllocatePoolWithTag()
108 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
109 // is configured on, then bugcheck the system if
110 // a memory allocation fails. The routine should be
111 // used for all memory allocations that are to be freed
112 // when the library is unloaded. Memory allocations that
113 // are to survive library unload and reload should be
114 // performed using AFSExAllocatePoolWithTag() which is
115 // provided by the AFS Framework.
118 // POOL_TYPE PoolType - Paged or NonPaged
119 // SIZE_T NumberOfBytes - requested allocation size
120 // ULONG Tag - Pool Allocation Tag to be applied for tracking
123 // void * - the memory allocation
127 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
128 IN SIZE_T NumberOfBytes,
132 void *pBuffer = NULL;
134 pBuffer = ExAllocatePoolWithTag( PoolType,
141 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
144 KeBugCheck( (ULONG)-2);
151 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
155 PsGetCurrentThread()));
165 // Function: AFSAcquireExcl()
167 // Purpose: Called to acquire a resource exclusive with optional wait
170 // PERESOURCE Resource - Resource to acquire
171 // BOOLEAN Wait - Whether to block
174 // BOOLEAN - Whether the mask was acquired
178 AFSAcquireExcl( IN PERESOURCE Resource,
182 BOOLEAN bStatus = FALSE;
185 // Normal kernel APCs must be disabled before calling
186 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
189 KeEnterCriticalRegion();
191 bStatus = ExAcquireResourceExclusiveLite( Resource,
197 KeLeaveCriticalRegion();
204 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
208 BOOLEAN bStatus = FALSE;
210 KeEnterCriticalRegion();
212 bStatus = ExAcquireSharedStarveExclusive( Resource,
218 KeLeaveCriticalRegion();
225 // Function: AFSAcquireShared()
227 // Purpose: Called to acquire a resource shared with optional wait
230 // PERESOURCE Resource - Resource to acquire
231 // BOOLEAN Wait - Whether to block
234 // BOOLEAN - Whether the mask was acquired
238 AFSAcquireShared( IN PERESOURCE Resource,
242 BOOLEAN bStatus = FALSE;
244 KeEnterCriticalRegion();
246 bStatus = ExAcquireResourceSharedLite( Resource,
252 KeLeaveCriticalRegion();
259 // Function: AFSReleaseResource()
261 // Purpose: Called to release a resource
264 // PERESOURCE Resource - Resource to release
271 AFSReleaseResource( IN PERESOURCE Resource)
274 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
275 AFS_TRACE_LEVEL_VERBOSE,
276 "AFSReleaseResource Releasing lock %p Thread %08lX\n",
278 PsGetCurrentThread()));
280 ExReleaseResourceLite( Resource);
282 KeLeaveCriticalRegion();
288 AFSConvertToShared( IN PERESOURCE Resource)
291 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
292 AFS_TRACE_LEVEL_VERBOSE,
293 "AFSConvertToShared Converting lock %p Thread %08lX\n",
295 PsGetCurrentThread()));
297 ExConvertExclusiveToSharedLite( Resource);
303 // Function: AFSCompleteRequest
307 // This function completes irps
311 // A status is returned for the function
315 AFSCompleteRequest( IN PIRP Irp,
319 Irp->IoStatus.Status = Status;
321 IoCompleteRequest( Irp,
328 // Function: AFSGenerateCRC
332 // Given a device and filename this function generates a CRC
336 // A status is returned for the function
340 AFSGenerateCRC( IN PUNICODE_STRING FileName,
341 IN BOOLEAN UpperCaseName)
345 NTSTATUS ntStatus = STATUS_SUCCESS;
347 ntStatus = RtlHashUnicodeString( FileName,
349 HASH_STRING_ALGORITHM_DEFAULT,
352 if( !NT_SUCCESS( ntStatus))
361 AFSLockSystemBuffer( IN PIRP Irp,
365 void *pAddress = NULL;
367 if( Irp->MdlAddress != NULL)
370 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
373 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
376 pAddress = Irp->AssociatedIrp.SystemBuffer;
378 else if( Irp->UserBuffer != NULL)
381 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
387 if( Irp->MdlAddress != NULL)
391 // Lock the new Mdl in memory.
396 PIO_STACK_LOCATION pIoStack;
397 pIoStack = IoGetCurrentIrpStackLocation( Irp);
400 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
401 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
403 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
406 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
409 AFSDumpTraceFilesFnc();
411 IoFreeMdl( Irp->MdlAddress );
412 Irp->MdlAddress = NULL;
422 AFSLockUserBuffer( IN void *UserBuffer,
423 IN ULONG BufferLength,
427 NTSTATUS ntStatus = STATUS_SUCCESS;
428 void *pAddress = NULL;
434 pMdl = IoAllocateMdl( UserBuffer,
443 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
447 // Lock the new Mdl in memory.
453 MmProbeAndLockPages( pMdl,
457 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
460 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
463 AFSDumpTraceFilesFnc();
485 AFSMapToService( IN PIRP Irp,
489 NTSTATUS ntStatus = STATUS_SUCCESS;
490 void *pMappedBuffer = NULL;
491 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
497 if( pDevExt->Specific.Control.ServiceProcess == NULL)
500 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
503 if( Irp->MdlAddress == NULL)
506 if( AFSLockSystemBuffer( Irp,
510 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
515 // Attach to the service process for mapping
518 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
519 (PRKAPC_STATE)&stApcState);
521 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
528 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
535 return pMappedBuffer;
539 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
543 NTSTATUS ntStatus = STATUS_SUCCESS;
544 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
550 if( pDevExt->Specific.Control.ServiceProcess == NULL)
553 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
560 // Attach to the service process for mapping
563 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
564 (PRKAPC_STATE)&stApcState);
566 MmUnmapLockedPages( MappedBuffer,
569 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
581 AFSInitializeLibraryDevice()
584 NTSTATUS ntStatus = STATUS_SUCCESS;
585 AFSDeviceExt *pDeviceExt = NULL;
590 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
593 // The PIOCtl file name
596 RtlInitUnicodeString( &AFSPIOCtlName,
597 AFS_PIOCTL_FILE_INTERFACE_NAME);
600 // And the global root share name
603 RtlInitUnicodeString( &AFSGlobalRootName,
604 AFS_GLOBAL_ROOT_SHARE_NAME);
612 AFSRemoveLibraryDevice()
615 NTSTATUS ntStatus = STATUS_SUCCESS;
626 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
630 UNREFERENCED_PARAMETER(DeviceObject);
631 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
633 AFSCompleteRequest( Irp,
640 AFSInitializeGlobalDirectoryEntries()
643 NTSTATUS ntStatus = STATUS_SUCCESS;
644 AFSDirectoryCB *pDirNode = NULL;
645 ULONG ulEntryLength = 0;
646 AFSObjectInfoCB *pObjectInfoCB = NULL;
647 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
654 // Initialize the global . entry
657 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
660 if( pObjectInfoCB == NULL)
663 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
664 AFS_TRACE_LEVEL_ERROR,
665 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
668 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
671 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
672 AFS_OBJECT_REFERENCE_GLOBAL);
674 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
675 AFS_TRACE_LEVEL_VERBOSE,
676 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
680 ntStatus = STATUS_SUCCESS;
682 ulEntryLength = sizeof( AFSDirectoryCB) +
685 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
689 if( pDirNode == NULL)
692 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
693 AFS_OBJECT_REFERENCE_GLOBAL);
695 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
696 AFS_TRACE_LEVEL_VERBOSE,
697 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
704 AFSDeleteObjectInfo( &pObjectInfoCB);
707 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
708 AFS_TRACE_LEVEL_ERROR,
709 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n"));
711 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
714 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
715 AFS_TRACE_LEVEL_VERBOSE,
716 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocated %p\n",
719 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
720 sizeof( AFSNonPagedDirectoryCB),
721 AFS_DIR_ENTRY_NP_TAG);
723 if( pNonPagedDirEntry == NULL)
726 AFSLibExFreePoolWithTag( pDirNode,
729 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
730 AFS_OBJECT_REFERENCE_GLOBAL);
732 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
733 AFS_TRACE_LEVEL_VERBOSE,
734 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
741 AFSDeleteObjectInfo( &pObjectInfoCB);
744 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
745 AFS_TRACE_LEVEL_ERROR,
746 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n"));
748 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
751 RtlZeroMemory( pDirNode,
754 RtlZeroMemory( pNonPagedDirEntry,
755 sizeof( AFSNonPagedDirectoryCB));
757 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
759 pDirNode->NonPaged = pNonPagedDirEntry;
761 pDirNode->ObjectInformation = pObjectInfoCB;
767 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
769 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
772 // Setup the names in the entry
775 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
777 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
779 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
781 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
784 // Populate the rest of the data
787 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
789 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
791 AFSGlobalDotDirEntry = pDirNode;
797 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
800 if( pObjectInfoCB == NULL)
803 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
804 AFS_TRACE_LEVEL_ERROR,
805 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
808 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
811 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
812 AFS_OBJECT_REFERENCE_GLOBAL);
814 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
815 AFS_TRACE_LEVEL_VERBOSE,
816 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
820 ntStatus = STATUS_SUCCESS;
822 ulEntryLength = sizeof( AFSDirectoryCB) +
823 ( 2 * sizeof( WCHAR));
825 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
829 if( pDirNode == NULL)
832 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
833 AFS_TRACE_LEVEL_ERROR,
834 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocation failure\n"));
836 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
837 AFS_OBJECT_REFERENCE_GLOBAL);
839 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
840 AFS_TRACE_LEVEL_VERBOSE,
841 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
848 AFSDeleteObjectInfo( &pObjectInfoCB);
851 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
854 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
855 AFS_TRACE_LEVEL_VERBOSE,
856 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocated %p\n",
859 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
860 sizeof( AFSNonPagedDirectoryCB),
861 AFS_DIR_ENTRY_NP_TAG);
863 if( pNonPagedDirEntry == NULL)
866 AFSLibExFreePoolWithTag( pDirNode,
869 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
870 AFS_OBJECT_REFERENCE_GLOBAL);
872 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
873 AFS_TRACE_LEVEL_VERBOSE,
874 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
881 AFSDeleteObjectInfo( &pObjectInfoCB);
884 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
887 RtlZeroMemory( pDirNode,
890 RtlZeroMemory( pNonPagedDirEntry,
891 sizeof( AFSNonPagedDirectoryCB));
893 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
895 pDirNode->NonPaged = pNonPagedDirEntry;
897 pDirNode->ObjectInformation = pObjectInfoCB;
903 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
905 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
908 // Setup the names in the entry
911 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
913 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
915 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
917 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
919 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
922 // Populate the rest of the data
925 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
927 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
929 AFSGlobalDotDotDirEntry = pDirNode;
933 if( !NT_SUCCESS( ntStatus))
936 if( AFSGlobalDotDirEntry != NULL)
939 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
940 AFS_OBJECT_REFERENCE_GLOBAL);
942 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
943 AFS_TRACE_LEVEL_VERBOSE,
944 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
945 AFSGlobalDotDirEntry->ObjectInformation,
951 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
954 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
956 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry->NonPaged,
957 AFS_DIR_ENTRY_NP_TAG);
959 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry,
962 AFSGlobalDotDirEntry = NULL;
965 if( AFSGlobalDotDotDirEntry != NULL)
968 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
969 AFS_OBJECT_REFERENCE_GLOBAL);
971 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
972 AFS_TRACE_LEVEL_VERBOSE,
973 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
974 AFSGlobalDotDotDirEntry->ObjectInformation,
980 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
983 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
985 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry->NonPaged,
986 AFS_DIR_ENTRY_NP_TAG);
988 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry,
991 AFSGlobalDotDotDirEntry = NULL;
1000 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
1001 IN PUNICODE_STRING FileName,
1002 IN PUNICODE_STRING TargetName,
1003 IN AFSDirEnumEntry *DirEnumEntry,
1007 AFSDirectoryCB *pDirNode = NULL;
1008 NTSTATUS ntStatus = STATUS_SUCCESS;
1009 ULONG ulEntryLength = 0;
1010 AFSObjectInfoCB *pObjectInfoCB = NULL;
1011 ULONGLONG ullIndex = 0;
1012 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
1018 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1019 AFS_TRACE_LEVEL_VERBOSE,
1020 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
1022 ParentObjectInfo->FileId.Cell,
1023 ParentObjectInfo->FileId.Volume,
1024 ParentObjectInfo->FileId.Vnode,
1025 ParentObjectInfo->FileId.Unique));
1028 // First thing is to locate/create our object information block
1032 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
1035 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
1037 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
1039 (AFSBTreeEntry **)&pObjectInfoCB);
1041 if( !NT_SUCCESS( ntStatus))
1045 // Allocate our object info cb
1048 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
1051 if( pObjectInfoCB == NULL)
1054 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1056 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1059 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1060 AFS_TRACE_LEVEL_VERBOSE,
1061 "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
1067 // If we allocated the object information cb then set the information
1070 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1072 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1074 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1076 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1078 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1079 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1082 pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1085 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
1088 if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1091 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1096 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1101 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1102 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1106 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1107 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1108 pObjectInfoCB->TargetFileId.Unique == 0 &&
1109 (TargetName == NULL || TargetName->Length == 0))
1113 // This will ensure we perform a validation on the node
1116 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1119 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1122 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1125 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1128 if ( BooleanFlagOn( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY))
1131 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1133 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1135 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1137 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1139 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1141 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1143 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1145 pObjectInfoCB->Links = DirEnumEntry->Links;
1147 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1149 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1151 ClearFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1155 // This reference count is either stored into the return DirectoryCB
1156 // or released before function exit.
1159 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
1160 AFS_OBJECT_REFERENCE_DIRENTRY);
1162 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1163 AFS_TRACE_LEVEL_VERBOSE,
1164 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
1168 KeQueryTickCount( &pObjectInfoCB->LastAccessCount);
1170 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1172 ntStatus = STATUS_SUCCESS;
1174 ulEntryLength = sizeof( AFSDirectoryCB) +
1177 if( TargetName != NULL)
1180 ulEntryLength += TargetName->Length;
1183 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1187 if( pDirNode == NULL)
1190 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1193 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1194 AFS_TRACE_LEVEL_VERBOSE,
1195 "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
1198 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1199 sizeof( AFSNonPagedDirectoryCB),
1200 AFS_DIR_ENTRY_NP_TAG);
1202 if( pNonPagedDirEntry == NULL)
1205 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1208 RtlZeroMemory( pDirNode,
1211 RtlZeroMemory( pNonPagedDirEntry,
1212 sizeof( AFSNonPagedDirectoryCB));
1214 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1216 pDirNode->NonPaged = pNonPagedDirEntry;
1218 pDirNode->ObjectInformation = pObjectInfoCB;
1221 // Set valid entry and NOT_IN_PARENT flag
1224 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1226 pDirNode->FileIndex = FileIndex;
1229 // Setup the names in the entry
1232 if( FileName->Length > 0)
1235 pDirNode->NameInformation.FileName.Length = FileName->Length;
1237 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1239 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1241 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1243 pDirNode->NameInformation.FileName.Length);
1246 // Create a CRC for the file
1249 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1252 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1256 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1257 AFS_TRACE_LEVEL_VERBOSE,
1258 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1261 ParentObjectInfo->FileId.Cell,
1262 ParentObjectInfo->FileId.Volume,
1263 ParentObjectInfo->FileId.Vnode,
1264 ParentObjectInfo->FileId.Unique));
1266 if( TargetName != NULL &&
1267 TargetName->Length > 0)
1270 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1272 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1274 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1275 sizeof( AFSDirectoryCB) +
1276 pDirNode->NameInformation.FileName.Length);
1278 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1280 pDirNode->NameInformation.TargetName.Length);
1286 if( !NT_SUCCESS( ntStatus))
1289 if( pNonPagedDirEntry != NULL)
1292 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1294 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1297 if( pDirNode != NULL)
1300 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1301 AFS_TRACE_LEVEL_VERBOSE,
1302 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1305 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1311 // Dereference our object info block if we have one
1314 if( pObjectInfoCB != NULL)
1317 AFSAcquireShared( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
1320 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1321 AFS_OBJECT_REFERENCE_DIRENTRY);
1323 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1324 AFS_TRACE_LEVEL_VERBOSE,
1325 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1329 AFSReleaseResource( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
1338 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1339 IN BOOLEAN DirectoryEntry)
1342 BOOLEAN bReturn = TRUE;
1343 ACCESS_MASK stAccessMask = 0;
1346 // Get rid of anything we don't know about
1349 DesiredAccess = (DesiredAccess &
1355 ACCESS_SYSTEM_SECURITY |
1359 FILE_READ_ATTRIBUTES |
1360 FILE_WRITE_ATTRIBUTES |
1361 FILE_LIST_DIRECTORY |
1367 // Our 'read only' access mask. These are the accesses we will
1368 // allow for a read only file
1371 stAccessMask = DELETE |
1376 ACCESS_SYSTEM_SECURITY |
1380 FILE_READ_ATTRIBUTES |
1381 FILE_WRITE_ATTRIBUTES |
1383 FILE_LIST_DIRECTORY |
1387 // For a directory, add in the directory specific accesses
1393 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1398 if( FlagOn( DesiredAccess, ~stAccessMask))
1402 // A write access is set ...
1412 AFSEvaluateNode( IN GUID *AuthGroup,
1413 IN AFSDirectoryCB *DirEntry)
1416 NTSTATUS ntStatus = STATUS_SUCCESS;
1417 AFSDirEnumEntry *pDirEntry = NULL;
1418 UNICODE_STRING uniTargetName;
1423 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1428 if( !NT_SUCCESS( ntStatus))
1431 try_return( ntStatus);
1434 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1436 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1438 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1440 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1442 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1444 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1446 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1448 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1450 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1452 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1454 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1456 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1457 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1460 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1463 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1466 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1469 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1474 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1478 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1480 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1483 // If we have a target name then see if it needs updating ...
1486 if( pDirEntry->TargetNameLength > 0)
1490 // Update the target name information if needed
1493 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1495 uniTargetName.MaximumLength = uniTargetName.Length;
1497 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1499 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1502 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1503 RtlCompareUnicodeString( &uniTargetName,
1504 &DirEntry->NameInformation.TargetName,
1509 // Update the target name
1512 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1514 uniTargetName.Buffer,
1515 uniTargetName.Length);
1517 if( !NT_SUCCESS( ntStatus))
1520 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1522 try_return( ntStatus);
1526 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1531 if( pDirEntry != NULL)
1534 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1542 AFSValidateSymLink( IN GUID *AuthGroup,
1543 IN AFSDirectoryCB *DirEntry)
1546 NTSTATUS ntStatus = STATUS_SUCCESS;
1547 AFSDirEnumEntry *pDirEntry = NULL;
1548 UNICODE_STRING uniTargetName;
1553 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1558 if( !NT_SUCCESS( ntStatus))
1561 try_return( ntStatus);
1564 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1565 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1568 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1569 AFS_TRACE_LEVEL_VERBOSE_2,
1570 "AFSValidateSymLink Invalid type Status %08lX\n",
1571 STATUS_OBJECT_NAME_NOT_FOUND));
1573 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1576 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1578 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1580 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1583 // Update the target name information if needed
1586 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1588 uniTargetName.MaximumLength = uniTargetName.Length;
1590 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1592 if( uniTargetName.Length > 0)
1595 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1598 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1599 RtlCompareUnicodeString( &uniTargetName,
1600 &DirEntry->NameInformation.TargetName,
1605 // Update the target name
1608 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1610 uniTargetName.Buffer,
1611 uniTargetName.Length);
1613 if( !NT_SUCCESS( ntStatus))
1616 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1618 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1622 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1626 // If the FileType is the same then nothing to do since it IS
1630 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1633 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1635 try_return( ntStatus = STATUS_SUCCESS);
1638 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1640 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1642 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1644 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1646 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1648 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1650 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1652 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1654 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1655 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1658 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1661 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1664 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1667 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1672 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1676 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1678 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1682 if( pDirEntry != NULL)
1685 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1693 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1697 NTSTATUS ntStatus = STATUS_SUCCESS;
1698 IO_STATUS_BLOCK stIoStatus;
1700 AFSObjectInfoCB * pParentObjectInfo = NULL;
1702 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1703 AFS_TRACE_LEVEL_VERBOSE,
1704 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1705 (*ppObjectInfo)->FileType,
1706 (*ppObjectInfo)->FileId.Cell,
1707 (*ppObjectInfo)->FileId.Volume,
1708 (*ppObjectInfo)->FileId.Vnode,
1709 (*ppObjectInfo)->FileId.Unique,
1712 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1715 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1716 &(*ppObjectInfo)->ParentFileId,
1720 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1721 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1722 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1725 // We only act on the mount point itself, not the target. If the
1726 // node has been deleted then mark it as such otherwise indicate
1727 // it requires verification
1730 if( Reason == AFS_INVALIDATE_DELETED)
1732 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1737 if( Reason == AFS_INVALIDATE_FLUSHED)
1740 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1742 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1745 (*ppObjectInfo)->Expiration.QuadPart = 0;
1747 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1749 (*ppObjectInfo)->TargetFileId.Unique = 0;
1751 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1752 AFS_TRACE_LEVEL_VERBOSE,
1753 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1754 (*ppObjectInfo)->FileId.Cell,
1755 (*ppObjectInfo)->FileId.Volume,
1756 (*ppObjectInfo)->FileId.Vnode,
1757 (*ppObjectInfo)->FileId.Unique));
1759 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1762 if ( pParentObjectInfo != NULL)
1765 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1767 if( Reason == AFS_INVALIDATE_CREDS)
1769 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1772 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1773 Reason == AFS_INVALIDATE_FLUSHED)
1775 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1779 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1782 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1785 FILE_ACTION_MODIFIED);
1788 try_return( ntStatus);
1792 // Depending on the reason for invalidation then perform work on the node
1798 case AFS_INVALIDATE_DELETED:
1802 // Mark this node as invalid
1805 (*ppObjectInfo)->Links = 0;
1807 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1809 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1810 AFS_TRACE_LEVEL_VERBOSE,
1811 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1812 (*ppObjectInfo)->FileId.Cell,
1813 (*ppObjectInfo)->FileId.Volume,
1814 (*ppObjectInfo)->FileId.Vnode,
1815 (*ppObjectInfo)->FileId.Unique));
1817 if( pParentObjectInfo != NULL)
1820 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1821 AFS_TRACE_LEVEL_VERBOSE,
1822 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1823 pParentObjectInfo->FileId.Cell,
1824 pParentObjectInfo->FileId.Volume,
1825 pParentObjectInfo->FileId.Vnode,
1826 pParentObjectInfo->FileId.Unique));
1828 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1830 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1832 pParentObjectInfo->Expiration.QuadPart = 0;
1834 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1836 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1840 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1843 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1846 FILE_ACTION_REMOVED);
1849 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1852 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1858 case AFS_INVALIDATE_FLUSHED:
1861 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1862 (*ppObjectInfo)->Fcb != NULL)
1865 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1866 AFS_TRACE_LEVEL_VERBOSE,
1867 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1868 (*ppObjectInfo)->FileId.Cell,
1869 (*ppObjectInfo)->FileId.Volume,
1870 (*ppObjectInfo)->FileId.Vnode,
1871 (*ppObjectInfo)->FileId.Unique));
1873 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1874 AFS_TRACE_LEVEL_VERBOSE,
1875 "AFSInvalidateObject Flush/purge Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
1876 &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1877 PsGetCurrentThread()));
1879 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1885 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1890 if( !NT_SUCCESS( stIoStatus.Status))
1893 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1894 AFS_TRACE_LEVEL_ERROR,
1895 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1896 (*ppObjectInfo)->FileId.Cell,
1897 (*ppObjectInfo)->FileId.Volume,
1898 (*ppObjectInfo)->FileId.Vnode,
1899 (*ppObjectInfo)->FileId.Unique,
1901 stIoStatus.Information));
1903 ntStatus = stIoStatus.Status;
1907 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1910 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1916 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1917 AFS_TRACE_LEVEL_WARNING,
1918 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1919 (*ppObjectInfo)->FileId.Cell,
1920 (*ppObjectInfo)->FileId.Volume,
1921 (*ppObjectInfo)->FileId.Vnode,
1922 (*ppObjectInfo)->FileId.Unique));
1924 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1928 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
1931 ntStatus = GetExceptionCode();
1935 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1936 (*ppObjectInfo)->FileId.Cell,
1937 (*ppObjectInfo)->FileId.Volume,
1938 (*ppObjectInfo)->FileId.Vnode,
1939 (*ppObjectInfo)->FileId.Unique,
1942 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1945 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1946 AFS_TRACE_LEVEL_VERBOSE,
1947 "AFSInvalidateObject Flush/purge Releasing Fcb SectionObject lock %p EXCL %08lX\n",
1948 &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1949 PsGetCurrentThread()));
1951 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1954 // Clear out the extents
1955 // Get rid of them (note this involves waiting
1956 // for any writes or reads to the cache to complete)
1959 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1963 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1966 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1969 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1970 AFS_TRACE_LEVEL_VERBOSE,
1971 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1972 (*ppObjectInfo)->FileId.Cell,
1973 (*ppObjectInfo)->FileId.Volume,
1974 (*ppObjectInfo)->FileId.Vnode,
1975 (*ppObjectInfo)->FileId.Unique));
1977 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1980 // Fall through to the default processing
1986 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1988 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1992 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1995 if( Reason == AFS_INVALIDATE_CREDS)
1997 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2000 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2002 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2006 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2009 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
2012 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
2015 FILE_ACTION_MODIFIED);
2017 else if ( pParentObjectInfo != NULL)
2020 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2023 FILE_ACTION_MODIFIED);
2027 // Indicate this node requires re-evaluation for the remaining reasons
2030 (*ppObjectInfo)->Expiration.QuadPart = 0;
2032 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2033 AFS_TRACE_LEVEL_VERBOSE,
2034 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2035 (*ppObjectInfo)->FileId.Cell,
2036 (*ppObjectInfo)->FileId.Volume,
2037 (*ppObjectInfo)->FileId.Vnode,
2038 (*ppObjectInfo)->FileId.Unique));
2040 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
2042 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2043 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
2044 ( Reason == AFS_INVALIDATE_CALLBACK ||
2045 Reason == AFS_INVALIDATE_EXPIRED))
2047 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
2048 AFS_INVALIDATE_DATA_VERSION)))
2051 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
2061 if ( pParentObjectInfo != NULL)
2064 AFSReleaseObjectInfo( &pParentObjectInfo);
2071 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
2074 NTSTATUS ntStatus = STATUS_SUCCESS;
2075 AFSVolumeCB *pVolumeCB = NULL;
2076 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2077 ULONGLONG ullIndex = 0;
2078 AFSObjectInfoCB *pObjectInfo = NULL;
2084 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2085 AFS_TRACE_LEVEL_VERBOSE,
2086 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
2087 InvalidateCB->FileID.Cell,
2088 InvalidateCB->FileID.Volume,
2089 InvalidateCB->FileID.Vnode,
2090 InvalidateCB->FileID.Unique,
2091 InvalidateCB->FileType,
2092 InvalidateCB->WholeVolume,
2093 InvalidateCB->Reason));
2096 // Need to locate the Fcb for the directory to purge
2099 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2100 AFS_TRACE_LEVEL_VERBOSE,
2101 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2102 &pDevExt->Specific.RDR.VolumeTreeLock,
2103 PsGetCurrentThread()));
2106 // Starve any exclusive waiters on this paticular call
2109 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2112 // Locate the volume node
2115 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2117 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2119 (AFSBTreeEntry **)&pVolumeCB);
2121 if( pVolumeCB != NULL)
2124 lCount = AFSVolumeIncrement( pVolumeCB,
2125 AFS_VOLUME_REFERENCE_INVALIDATE);
2127 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2128 AFS_TRACE_LEVEL_VERBOSE,
2129 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2134 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2136 if( !NT_SUCCESS( ntStatus) ||
2140 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2141 AFS_TRACE_LEVEL_WARNING,
2142 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2143 InvalidateCB->FileID.Cell,
2144 InvalidateCB->FileID.Volume,
2145 InvalidateCB->FileID.Vnode,
2146 InvalidateCB->FileID.Unique,
2149 try_return( ntStatus = STATUS_SUCCESS);
2153 // If this is a whole volume invalidation then go do it now
2156 if( InvalidateCB->WholeVolume)
2159 ntStatus = AFSInvalidateVolume( pVolumeCB,
2160 InvalidateCB->Reason);
2162 try_return( ntStatus);
2165 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
2168 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2171 pObjectInfo = &pVolumeCB->ObjectInformation;
2176 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2178 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2180 (AFSBTreeEntry **)&pObjectInfo);
2183 if( pObjectInfo != NULL)
2187 // Reference the node so it won't be torn down
2190 lCount = AFSObjectInfoIncrement( pObjectInfo,
2191 AFS_OBJECT_REFERENCE_INVALIDATION);
2193 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2194 AFS_TRACE_LEVEL_VERBOSE,
2195 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2200 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2202 if( !NT_SUCCESS( ntStatus) ||
2203 pObjectInfo == NULL)
2206 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2207 AFS_TRACE_LEVEL_VERBOSE,
2208 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2209 InvalidateCB->FileID.Cell,
2210 InvalidateCB->FileID.Volume,
2211 InvalidateCB->FileID.Vnode,
2212 InvalidateCB->FileID.Unique,
2215 try_return( ntStatus = STATUS_SUCCESS);
2218 AFSInvalidateObject( &pObjectInfo,
2219 InvalidateCB->Reason);
2223 if( pObjectInfo != NULL)
2226 lCount = AFSObjectInfoDecrement( pObjectInfo,
2227 AFS_OBJECT_REFERENCE_INVALIDATION);
2229 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2230 AFS_TRACE_LEVEL_VERBOSE,
2231 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2236 if ( pVolumeCB != NULL)
2239 lCount = AFSVolumeDecrement( pVolumeCB,
2240 AFS_VOLUME_REFERENCE_INVALIDATE);
2242 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2243 AFS_TRACE_LEVEL_VERBOSE,
2244 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2254 AFSIsChildOfParent( IN AFSFcb *Dcb,
2258 BOOLEAN bIsChild = FALSE;
2259 AFSFcb *pCurrentFcb = Fcb;
2260 AFSObjectInfoCB * pParentObjectInfo = NULL;
2262 while( pCurrentFcb != NULL)
2265 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2266 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2274 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2275 &pCurrentFcb->ObjectInformation->ParentFileId,
2278 if ( pParentObjectInfo != NULL)
2281 pCurrentFcb = pParentObjectInfo->Fcb;
2283 AFSReleaseObjectInfo( &pParentObjectInfo);
2297 AFSCreateHighIndex( IN AFSFileID *FileID)
2300 ULONGLONG ullIndex = 0;
2302 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2309 AFSCreateLowIndex( IN AFSFileID *FileID)
2312 ULONGLONG ullIndex = 0;
2314 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2320 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2321 IN ACCESS_MASK GrantedAccess,
2322 IN BOOLEAN DirectoryEntry)
2325 BOOLEAN bAccessGranted = TRUE;
2328 // Check if we are asking for read/write and granted only read only
2329 // NOTE: There will be more checks here
2332 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2334 AFSCheckForReadOnlyAccess( GrantedAccess,
2338 bAccessGranted = FALSE;
2341 return bAccessGranted;
2345 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2348 NTSTATUS ntStatus = STATUS_SUCCESS;
2349 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2355 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2357 if( AFSGlobalRoot == NULL)
2364 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2367 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2374 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2381 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2382 IN UNICODE_STRING *SubstituteName,
2383 IN ULONG StringIndex)
2386 NTSTATUS ntStatus = STATUS_SUCCESS;
2387 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2388 AFSSysNameCB *pSysName = NULL;
2389 ERESOURCE *pSysNameLock = NULL;
2392 UNICODE_STRING uniSysName;
2399 if( IoIs32bitProcess( NULL))
2402 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2404 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2409 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2411 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2415 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2417 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2421 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2422 AFS_TRACE_LEVEL_VERBOSE,
2423 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2425 PsGetCurrentThread()));
2427 AFSAcquireShared( pSysNameLock,
2431 // Find where we are in the list
2434 while( pSysName != NULL &&
2435 ulIndex < StringIndex)
2438 pSysName = pSysName->fLink;
2443 if( pSysName == NULL)
2446 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2447 AFS_TRACE_LEVEL_VERBOSE_2,
2448 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2450 STATUS_OBJECT_NAME_NOT_FOUND));
2452 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2455 RtlInitUnicodeString( &uniSysName,
2458 // If it is a full component of @SYS then just substitue the
2462 if( RtlCompareUnicodeString( &uniSysName,
2467 SubstituteName->Length = pSysName->SysName.Length;
2468 SubstituteName->MaximumLength = SubstituteName->Length;
2470 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2471 SubstituteName->Length,
2472 AFS_SUBST_BUFFER_TAG);
2474 if( SubstituteName->Buffer == NULL)
2477 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2480 RtlCopyMemory( SubstituteName->Buffer,
2481 pSysName->SysName.Buffer,
2482 pSysName->SysName.Length);
2489 while( ComponentName->Buffer[ usIndex] != L'@')
2495 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2496 SubstituteName->MaximumLength = SubstituteName->Length;
2498 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2499 SubstituteName->Length,
2500 AFS_SUBST_BUFFER_TAG);
2502 if( SubstituteName->Buffer == NULL)
2505 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2508 RtlCopyMemory( SubstituteName->Buffer,
2509 ComponentName->Buffer,
2510 usIndex * sizeof( WCHAR));
2512 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2513 pSysName->SysName.Buffer,
2514 pSysName->SysName.Length);
2519 AFSReleaseResource( pSysNameLock);
2526 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2527 IN OUT UNICODE_STRING *ComponentName,
2528 IN UNICODE_STRING *SubstituteName,
2529 IN OUT UNICODE_STRING *RemainingPath,
2530 IN BOOLEAN FreePathName)
2533 NTSTATUS ntStatus = STATUS_SUCCESS;
2534 UNICODE_STRING uniPathName;
2535 USHORT usPrefixNameLen = 0;
2536 SHORT sNameLenDelta = 0;
2542 // If the passed in name can handle the additional length
2543 // then just moves things around
2546 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2548 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2550 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2553 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2556 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2557 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2558 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2561 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2562 SubstituteName->Buffer,
2563 SubstituteName->Length);
2565 FullPathName->Length += sNameLenDelta;
2567 ComponentName->Length += sNameLenDelta;
2569 ComponentName->MaximumLength = ComponentName->Length;
2571 if ( RemainingPath->Buffer)
2574 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2577 try_return( ntStatus);
2581 // Need to re-allocate the buffer
2584 uniPathName.Length = FullPathName->Length -
2585 ComponentName->Length +
2586 SubstituteName->Length;
2588 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2590 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2591 uniPathName.MaximumLength,
2592 AFS_NAME_BUFFER_FOUR_TAG);
2594 if( uniPathName.Buffer == NULL)
2597 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2600 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2602 usPrefixNameLen *= sizeof( WCHAR);
2604 RtlZeroMemory( uniPathName.Buffer,
2605 uniPathName.MaximumLength);
2607 RtlCopyMemory( uniPathName.Buffer,
2608 FullPathName->Buffer,
2611 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2612 SubstituteName->Buffer,
2613 SubstituteName->Length);
2615 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2618 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2619 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2620 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2623 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2625 ComponentName->Length += sNameLenDelta;
2627 ComponentName->MaximumLength = ComponentName->Length;
2629 if ( RemainingPath->Buffer)
2632 RemainingPath->Buffer = uniPathName.Buffer
2633 + (RemainingPath->Buffer - FullPathName->Buffer)
2634 + sNameLenDelta/sizeof( WCHAR);
2639 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2642 *FullPathName = uniPathName;
2653 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2657 NTSTATUS ntStatus = STATUS_SUCCESS;
2658 AFSObjectInfoCB *pCurrentObject = NULL;
2659 AFSObjectInfoCB *pNextObject = NULL;
2665 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2666 AFS_TRACE_LEVEL_VERBOSE,
2667 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2668 VolumeCB->ObjectInformation.FileId.Cell,
2669 VolumeCB->ObjectInformation.FileId.Volume,
2670 VolumeCB->ObjectInformation.FileId.Vnode,
2671 VolumeCB->ObjectInformation.FileId.Unique,
2675 // Depending on the reason for invalidation then perform work on the node
2681 case AFS_INVALIDATE_DELETED:
2685 // Mark this volume as invalid
2688 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2690 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2696 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2700 // Invalidate the volume root directory
2703 pCurrentObject = &VolumeCB->ObjectInformation;
2705 if ( pCurrentObject )
2708 lCount = AFSObjectInfoIncrement( pCurrentObject,
2709 AFS_OBJECT_REFERENCE_INVALIDATION);
2711 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2712 AFS_TRACE_LEVEL_VERBOSE,
2713 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2717 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2719 AFSInvalidateObject( &pCurrentObject,
2722 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2725 if ( pCurrentObject)
2728 lCount = AFSObjectInfoDecrement( pCurrentObject,
2729 AFS_OBJECT_REFERENCE_INVALIDATION);
2731 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2732 AFS_TRACE_LEVEL_VERBOSE,
2733 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2740 // Apply invalidation to all other volume objects
2743 pCurrentObject = VolumeCB->ObjectInfoListHead;
2745 if ( pCurrentObject)
2749 // Reference the node so it won't be torn down
2752 lCount = AFSObjectInfoIncrement( pCurrentObject,
2753 AFS_OBJECT_REFERENCE_INVALIDATION);
2755 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2756 AFS_TRACE_LEVEL_VERBOSE,
2757 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2762 while( pCurrentObject != NULL)
2765 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2771 // Reference the node so it won't be torn down
2774 lCount = AFSObjectInfoIncrement( pNextObject,
2775 AFS_OBJECT_REFERENCE_INVALIDATION);
2777 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2778 AFS_TRACE_LEVEL_VERBOSE,
2779 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2784 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2786 AFSInvalidateObject( &pCurrentObject,
2789 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2792 if ( pCurrentObject )
2795 lCount = AFSObjectInfoDecrement( pCurrentObject,
2796 AFS_OBJECT_REFERENCE_INVALIDATION);
2798 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2799 AFS_TRACE_LEVEL_VERBOSE,
2800 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2805 pCurrentObject = pNextObject;
2808 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2815 AFSInvalidateAllVolumes( VOID)
2817 AFSVolumeCB *pVolumeCB = NULL;
2818 AFSVolumeCB *pNextVolumeCB = NULL;
2819 AFSDeviceExt *pRDRDeviceExt = NULL;
2822 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2824 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2825 AFS_TRACE_LEVEL_VERBOSE,
2826 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2827 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2828 PsGetCurrentThread()));
2830 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2833 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2838 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2839 AFS_TRACE_LEVEL_VERBOSE,
2840 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2841 pVolumeCB->ObjectInfoTree.TreeLock,
2842 PsGetCurrentThread()));
2844 lCount = AFSVolumeIncrement( pVolumeCB,
2845 AFS_VOLUME_REFERENCE_INVALIDATE);
2847 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2848 AFS_TRACE_LEVEL_VERBOSE,
2849 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2854 while( pVolumeCB != NULL)
2857 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2862 lCount = AFSVolumeIncrement( pNextVolumeCB,
2863 AFS_VOLUME_REFERENCE_INVALIDATE);
2865 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2866 AFS_TRACE_LEVEL_VERBOSE,
2867 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2872 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2874 // do I need to hold the volume lock here?
2876 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2878 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2881 lCount = AFSVolumeDecrement( pVolumeCB,
2882 AFS_VOLUME_REFERENCE_INVALIDATE);
2884 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2885 AFS_TRACE_LEVEL_VERBOSE,
2886 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2890 pVolumeCB = pNextVolumeCB;
2893 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2897 AFSVerifyEntry( IN GUID *AuthGroup,
2898 IN AFSDirectoryCB *DirEntry,
2899 IN BOOLEAN bFollowMountPoint)
2902 NTSTATUS ntStatus = STATUS_SUCCESS;
2903 AFSDirEnumEntry *pDirEnumEntry = NULL;
2904 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2905 IO_STATUS_BLOCK stIoStatus;
2910 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2911 AFS_TRACE_LEVEL_VERBOSE_2,
2912 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2913 &DirEntry->NameInformation.FileName,
2914 pObjectInfo->FileId.Cell,
2915 pObjectInfo->FileId.Volume,
2916 pObjectInfo->FileId.Vnode,
2917 pObjectInfo->FileId.Unique));
2919 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2921 bFollowMountPoint ? FALSE : TRUE,
2924 if( !NT_SUCCESS( ntStatus))
2927 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2928 AFS_TRACE_LEVEL_ERROR,
2929 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2930 &DirEntry->NameInformation.FileName,
2931 pObjectInfo->FileId.Cell,
2932 pObjectInfo->FileId.Volume,
2933 pObjectInfo->FileId.Vnode,
2934 pObjectInfo->FileId.Unique,
2937 try_return( ntStatus);
2941 // Check the data version of the file
2944 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2946 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2949 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2950 AFS_TRACE_LEVEL_VERBOSE,
2951 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2952 pObjectInfo->DataVersion.QuadPart,
2953 &DirEntry->NameInformation.FileName,
2954 pObjectInfo->FileId.Cell,
2955 pObjectInfo->FileId.Volume,
2956 pObjectInfo->FileId.Vnode,
2957 pObjectInfo->FileId.Unique));
2960 // We are ok, just get out
2963 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2965 try_return( ntStatus = STATUS_SUCCESS);
2970 // New data version so we will need to process the node based on the type
2973 switch( pDirEnumEntry->FileType)
2976 case AFS_FILE_TYPE_MOUNTPOINT:
2980 // For a mount point we need to ensure the target is the same
2983 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2984 &pDirEnumEntry->TargetFileId))
2990 // Update the metadata for the entry
2993 ntStatus = AFSUpdateMetaData( DirEntry,
2996 if( NT_SUCCESS( ntStatus))
2999 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3005 case AFS_FILE_TYPE_SYMLINK:
3009 // Update the metadata for the entry
3012 ntStatus = AFSUpdateMetaData( DirEntry,
3015 if( NT_SUCCESS( ntStatus))
3018 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3024 case AFS_FILE_TYPE_FILE:
3026 FILE_OBJECT * pCCFileObject = NULL;
3027 BOOLEAN bPurgeExtents = FALSE;
3029 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3032 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3033 AFS_TRACE_LEVEL_VERBOSE,
3034 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
3035 &DirEntry->NameInformation.FileName,
3036 pObjectInfo->FileId.Cell,
3037 pObjectInfo->FileId.Volume,
3038 pObjectInfo->FileId.Vnode,
3039 pObjectInfo->FileId.Unique,
3040 pObjectInfo->DataVersion.LowPart,
3041 pDirEnumEntry->DataVersion.LowPart));
3043 bPurgeExtents = TRUE;
3046 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3049 bPurgeExtents = TRUE;
3051 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3052 AFS_TRACE_LEVEL_VERBOSE,
3053 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3054 &DirEntry->NameInformation.FileName,
3055 pObjectInfo->FileId.Cell,
3056 pObjectInfo->FileId.Volume,
3057 pObjectInfo->FileId.Vnode,
3058 pObjectInfo->FileId.Unique));
3060 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3063 if( pObjectInfo->Fcb != NULL)
3066 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3067 AFS_TRACE_LEVEL_VERBOSE,
3068 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3069 &DirEntry->NameInformation.FileName,
3070 pObjectInfo->FileId.Cell,
3071 pObjectInfo->FileId.Volume,
3072 pObjectInfo->FileId.Vnode,
3073 pObjectInfo->FileId.Unique));
3075 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3076 AFS_TRACE_LEVEL_VERBOSE,
3077 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3078 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3079 PsGetCurrentThread()));
3081 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3087 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3092 if( !NT_SUCCESS( stIoStatus.Status))
3095 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3096 AFS_TRACE_LEVEL_ERROR,
3097 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3098 &DirEntry->NameInformation.FileName,
3099 pObjectInfo->FileId.Cell,
3100 pObjectInfo->FileId.Volume,
3101 pObjectInfo->FileId.Vnode,
3102 pObjectInfo->FileId.Unique,
3104 stIoStatus.Information));
3106 ntStatus = stIoStatus.Status;
3109 if ( bPurgeExtents &&
3110 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3113 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3119 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3120 AFS_TRACE_LEVEL_WARNING,
3121 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3122 &DirEntry->NameInformation.FileName,
3123 pObjectInfo->FileId.Cell,
3124 pObjectInfo->FileId.Volume,
3125 pObjectInfo->FileId.Vnode,
3126 pObjectInfo->FileId.Unique));
3128 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3132 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3134 ntStatus = GetExceptionCode();
3138 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3139 &DirEntry->NameInformation.FileName,
3140 pObjectInfo->FileId.Cell,
3141 pObjectInfo->FileId.Volume,
3142 pObjectInfo->FileId.Vnode,
3143 pObjectInfo->FileId.Unique,
3146 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3149 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3150 AFS_TRACE_LEVEL_VERBOSE,
3151 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3152 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3153 PsGetCurrentThread()));
3155 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3159 AFSFlushExtents( pObjectInfo->Fcb,
3164 // Acquire the Fcb to purge the cache
3167 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3168 AFS_TRACE_LEVEL_VERBOSE,
3169 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3170 &pObjectInfo->Fcb->NPFcb->Resource,
3171 PsGetCurrentThread()));
3173 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3177 // Update the metadata for the entry
3180 ntStatus = AFSUpdateMetaData( DirEntry,
3183 if( !NT_SUCCESS( ntStatus))
3186 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3187 AFS_TRACE_LEVEL_ERROR,
3188 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3189 &DirEntry->NameInformation.FileName,
3190 pObjectInfo->FileId.Cell,
3191 pObjectInfo->FileId.Volume,
3192 pObjectInfo->FileId.Vnode,
3193 pObjectInfo->FileId.Unique,
3200 // Update file sizes
3203 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3204 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3205 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3207 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3208 AFS_TRACE_LEVEL_VERBOSE,
3209 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3210 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3211 PsGetCurrentThread()));
3213 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3219 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3221 if ( pCCFileObject != NULL)
3223 CcSetFileSizes( pCCFileObject,
3224 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3227 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3230 ntStatus = GetExceptionCode();
3234 "EXCEPTION - AFSVerifyEntry CcSetFileSized failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3235 pObjectInfo->FileId.Cell,
3236 pObjectInfo->FileId.Volume,
3237 pObjectInfo->FileId.Vnode,
3238 pObjectInfo->FileId.Unique,
3242 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3243 AFS_TRACE_LEVEL_VERBOSE,
3244 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3245 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3246 PsGetCurrentThread()));
3248 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3250 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3256 // Update the metadata for the entry
3259 ntStatus = AFSUpdateMetaData( DirEntry,
3262 if( !NT_SUCCESS( ntStatus))
3265 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3266 AFS_TRACE_LEVEL_ERROR,
3267 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3268 &DirEntry->NameInformation.FileName,
3269 pObjectInfo->FileId.Cell,
3270 pObjectInfo->FileId.Volume,
3271 pObjectInfo->FileId.Vnode,
3272 pObjectInfo->FileId.Unique,
3278 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3279 AFS_TRACE_LEVEL_WARNING,
3280 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3281 &DirEntry->NameInformation.FileName,
3282 pObjectInfo->FileId.Cell,
3283 pObjectInfo->FileId.Volume,
3284 pObjectInfo->FileId.Vnode,
3285 pObjectInfo->FileId.Unique));
3288 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3293 case AFS_FILE_TYPE_DIRECTORY:
3297 // For a directory or root entry flush the content of
3298 // the directory enumeration.
3301 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3304 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3305 AFS_TRACE_LEVEL_VERBOSE_2,
3306 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3307 &DirEntry->NameInformation.FileName,
3308 pObjectInfo->FileId.Cell,
3309 pObjectInfo->FileId.Volume,
3310 pObjectInfo->FileId.Vnode,
3311 pObjectInfo->FileId.Unique));
3313 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3316 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3319 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3321 if ( !NT_SUCCESS( ntStatus))
3324 try_return( ntStatus);
3329 // Update the metadata for the entry
3332 ntStatus = AFSUpdateMetaData( DirEntry,
3335 if( NT_SUCCESS( ntStatus))
3338 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3344 case AFS_FILE_TYPE_DFSLINK:
3347 UNICODE_STRING uniTargetName;
3350 // For a DFS link need to check the target name has not changed
3353 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3355 uniTargetName.MaximumLength = uniTargetName.Length;
3357 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3359 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3362 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3363 RtlCompareUnicodeString( &uniTargetName,
3364 &DirEntry->NameInformation.TargetName,
3369 // Update the target name
3372 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3374 uniTargetName.Buffer,
3375 uniTargetName.Length);
3377 if( !NT_SUCCESS( ntStatus))
3380 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3386 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3389 // Update the metadata for the entry
3392 ntStatus = AFSUpdateMetaData( DirEntry,
3395 if( NT_SUCCESS( ntStatus))
3398 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3406 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3407 AFS_TRACE_LEVEL_WARNING,
3408 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3409 pObjectInfo->FileType,
3410 &DirEntry->NameInformation.FileName,
3411 pObjectInfo->FileId.Cell,
3412 pObjectInfo->FileId.Volume,
3413 pObjectInfo->FileId.Vnode,
3414 pObjectInfo->FileId.Unique));
3421 if( pDirEnumEntry != NULL)
3424 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3432 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3435 NTSTATUS ntStatus = STATUS_SUCCESS;
3436 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3437 ULONGLONG ullIndex = 0;
3438 AFSVolumeCB *pVolumeCB = NULL;
3444 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3445 AFS_TRACE_LEVEL_VERBOSE,
3446 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3447 VolumeStatus->Online,
3448 VolumeStatus->FileID.Cell,
3449 VolumeStatus->FileID.Volume));
3452 // Need to locate the Fcb for the directory to purge
3455 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3456 AFS_TRACE_LEVEL_VERBOSE,
3457 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3458 &pDevExt->Specific.RDR.VolumeTreeLock,
3459 PsGetCurrentThread()));
3461 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3464 // Locate the volume node
3467 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3469 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3471 (AFSBTreeEntry **)&pVolumeCB);
3473 if( pVolumeCB != NULL)
3476 lCount = AFSVolumeIncrement( pVolumeCB,
3477 AFS_VOLUME_REFERENCE_INVALIDATE);
3479 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3480 AFS_TRACE_LEVEL_VERBOSE,
3481 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3485 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3488 // Set the volume state accordingly
3491 if( VolumeStatus->Online)
3494 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3499 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3508 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3511 NTSTATUS ntStatus = STATUS_SUCCESS;
3516 if( AFSGlobalRoot == NULL)
3519 try_return( ntStatus);
3522 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3526 // Set the network state according to the information
3529 if( NetworkStatus->Online)
3532 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3537 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3540 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3551 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3555 NTSTATUS ntStatus = STATUS_SUCCESS;
3556 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3557 BOOLEAN bAcquiredLock = FALSE;
3558 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3563 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3564 AFS_TRACE_LEVEL_VERBOSE,
3565 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3566 ObjectInfo->FileId.Cell,
3567 ObjectInfo->FileId.Volume,
3568 ObjectInfo->FileId.Vnode,
3569 ObjectInfo->FileId.Unique));
3571 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3574 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3575 AFS_TRACE_LEVEL_VERBOSE,
3576 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3577 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3578 PsGetCurrentThread()));
3580 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3583 bAcquiredLock = TRUE;
3587 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3590 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3591 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3594 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3595 AFS_TRACE_LEVEL_ERROR,
3596 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3597 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3598 ObjectInfo->FileId.Cell,
3599 ObjectInfo->FileId.Volume,
3600 ObjectInfo->FileId.Vnode,
3601 ObjectInfo->FileId.Unique));
3605 // Reset the directory list information by clearing all valid entries
3608 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3610 while( pCurrentDirEntry != NULL)
3613 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3615 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3619 // If this entry has been deleted then process it here
3622 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3623 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3624 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3627 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3628 AFS_TRACE_LEVEL_VERBOSE,
3629 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3631 &pCurrentDirEntry->NameInformation.FileName));
3633 AFSDeleteDirEntry( ObjectInfo,
3639 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3641 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3642 AFS_TRACE_LEVEL_VERBOSE,
3643 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3645 pCurrentDirEntry->DirOpenReferenceCount));
3648 // We pull the short name from the parent tree since it could change below
3651 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3654 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3655 AFS_TRACE_LEVEL_VERBOSE,
3656 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3658 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3659 &pCurrentDirEntry->NameInformation.FileName));
3661 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3664 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3669 pCurrentDirEntry = pNextDirEntry;
3673 // Reget the directory contents
3676 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3679 if ( !NT_SUCCESS( ntStatus))
3681 try_return( ntStatus);
3685 // Now start again and tear down any entries not valid
3688 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3690 while( pCurrentDirEntry != NULL)
3693 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3695 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3698 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3699 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3700 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3703 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3706 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3708 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3709 AFS_TRACE_LEVEL_VERBOSE,
3710 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3712 &pCurrentDirEntry->NameInformation.FileName));
3714 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3719 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3722 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3723 AFS_TRACE_LEVEL_VERBOSE,
3724 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3726 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3727 &pCurrentDirEntry->NameInformation.FileName));
3731 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3733 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3734 AFS_TRACE_LEVEL_VERBOSE,
3735 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3737 &pCurrentDirEntry->NameInformation.FileName));
3742 pCurrentDirEntry = pNextDirEntry;
3747 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3748 AFS_TRACE_LEVEL_VERBOSE,
3749 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3751 pCurrentDirEntry->DirOpenReferenceCount));
3753 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3754 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3757 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3758 AFS_TRACE_LEVEL_VERBOSE,
3759 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3760 &pCurrentDirEntry->NameInformation.FileName,
3761 ObjectInfo->FileId.Cell,
3762 ObjectInfo->FileId.Volume,
3763 ObjectInfo->FileId.Vnode,
3764 ObjectInfo->FileId.Unique));
3766 AFSDeleteDirEntry( ObjectInfo,
3772 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3773 AFS_TRACE_LEVEL_VERBOSE,
3774 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3776 &pCurrentDirEntry->NameInformation.FileName,
3777 ObjectInfo->FileId.Cell,
3778 ObjectInfo->FileId.Volume,
3779 ObjectInfo->FileId.Vnode,
3780 ObjectInfo->FileId.Unique));
3782 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3784 AFSRemoveNameEntry( ObjectInfo,
3788 pCurrentDirEntry = pNextDirEntry;
3792 if( !AFSValidateDirList( ObjectInfo))
3795 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3804 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3812 AFSIsVolumeFID( IN AFSFileID *FileID)
3815 BOOLEAN bIsVolume = FALSE;
3817 if( FileID->Vnode == 1 &&
3818 FileID->Unique == 1)
3828 AFSIsFinalNode( IN AFSFcb *Fcb)
3831 BOOLEAN bIsFinalNode = FALSE;
3833 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3834 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3835 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3836 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3837 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3840 bIsFinalNode = TRUE;
3845 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3846 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3849 return bIsFinalNode;
3853 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3854 IN AFSDirEnumEntry *DirEnumEntry)
3857 NTSTATUS ntStatus = STATUS_SUCCESS;
3858 UNICODE_STRING uniTargetName;
3859 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3864 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3866 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3868 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3870 pObjectInfo->FileType = DirEnumEntry->FileType;
3872 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3874 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3876 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3878 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3880 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3882 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3884 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3886 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3887 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3890 pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3893 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
3896 if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
3899 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3904 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3908 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3910 pObjectInfo->Links = DirEnumEntry->Links;
3912 if( DirEnumEntry->TargetNameLength > 0 &&
3913 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3914 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3918 // Update the target name information if needed
3921 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3923 uniTargetName.MaximumLength = uniTargetName.Length;
3925 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3927 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3930 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3931 RtlCompareUnicodeString( &uniTargetName,
3932 &DirEntry->NameInformation.TargetName,
3937 // Update the target name
3940 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3942 uniTargetName.Buffer,
3943 uniTargetName.Length);
3945 if( !NT_SUCCESS( ntStatus))
3948 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3950 try_return( ntStatus);
3954 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3956 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3957 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3960 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3963 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3964 DirEntry->NameInformation.TargetName.Buffer != NULL)
3966 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3969 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3971 DirEntry->NameInformation.TargetName.Length = 0;
3972 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3973 DirEntry->NameInformation.TargetName.Buffer = NULL;
3975 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3987 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3989 IN BOOLEAN FastCall,
3990 IN BOOLEAN bSafeToPurge)
3993 NTSTATUS ntStatus = STATUS_SUCCESS;
3994 LARGE_INTEGER liSystemTime;
3995 AFSDirEnumEntry *pDirEnumEntry = NULL;
3996 AFSFcb *pCurrentFcb = NULL;
3997 BOOLEAN bReleaseFcb = FALSE;
3998 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
4004 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
4008 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4009 AFS_TRACE_LEVEL_VERBOSE_2,
4010 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
4011 &DirEntry->NameInformation.FileName,
4012 pObjectInfo->FileId.Cell,
4013 pObjectInfo->FileId.Volume,
4014 pObjectInfo->FileId.Vnode,
4015 pObjectInfo->FileId.Unique,
4019 // If this is a fake node then bail since the service knows nothing about it
4022 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
4025 try_return( ntStatus);
4029 // This routine ensures that the current entry is valid by:
4031 // 1) Checking that the expiration time is non-zero and after where we
4035 KeQuerySystemTime( &liSystemTime);
4037 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
4038 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
4039 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
4040 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
4043 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4044 AFS_TRACE_LEVEL_VERBOSE_2,
4045 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
4046 &DirEntry->NameInformation.FileName,
4047 pObjectInfo->FileId.Cell,
4048 pObjectInfo->FileId.Volume,
4049 pObjectInfo->FileId.Vnode,
4050 pObjectInfo->FileId.Unique));
4052 try_return( ntStatus);
4056 // This node requires updating
4059 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
4064 if( !NT_SUCCESS( ntStatus))
4067 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4068 AFS_TRACE_LEVEL_ERROR,
4069 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4071 &DirEntry->NameInformation.FileName,
4072 pObjectInfo->FileId.Cell,
4073 pObjectInfo->FileId.Volume,
4074 pObjectInfo->FileId.Vnode,
4075 pObjectInfo->FileId.Unique,
4079 // Failed validation of node so return access-denied
4082 try_return( ntStatus);
4085 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4086 AFS_TRACE_LEVEL_VERBOSE,
4087 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
4089 &DirEntry->NameInformation.FileName,
4090 pObjectInfo->FileId.Cell,
4091 pObjectInfo->FileId.Volume,
4092 pObjectInfo->FileId.Vnode,
4093 pObjectInfo->FileId.Unique,
4094 pObjectInfo->DataVersion.QuadPart,
4095 pDirEnumEntry->DataVersion.QuadPart,
4096 pDirEnumEntry->FileType));
4100 // Based on the file type, process the node
4103 switch( pDirEnumEntry->FileType)
4106 case AFS_FILE_TYPE_MOUNTPOINT:
4110 // Update the metadata for the entry
4113 ntStatus = AFSUpdateMetaData( DirEntry,
4116 if( NT_SUCCESS( ntStatus))
4119 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4125 case AFS_FILE_TYPE_SYMLINK:
4126 case AFS_FILE_TYPE_DFSLINK:
4130 // Update the metadata for the entry
4133 ntStatus = AFSUpdateMetaData( DirEntry,
4136 if( NT_SUCCESS( ntStatus))
4139 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4145 case AFS_FILE_TYPE_FILE:
4148 BOOLEAN bPurgeExtents = FALSE;
4151 // For a file where the data version has become invalid we need to
4152 // fail any current extent requests and purge the cache for the file
4153 // Can't hold the Fcb resource while doing this
4156 if( pObjectInfo->Fcb != NULL &&
4157 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4158 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4161 pCurrentFcb = pObjectInfo->Fcb;
4163 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4166 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4167 AFS_TRACE_LEVEL_VERBOSE,
4168 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4169 &pCurrentFcb->NPFcb->Resource,
4170 PsGetCurrentThread()));
4172 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4178 if( pCurrentFcb != NULL)
4181 IO_STATUS_BLOCK stIoStatus;
4183 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4184 AFS_TRACE_LEVEL_VERBOSE_2,
4185 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4186 &DirEntry->NameInformation.FileName,
4187 pObjectInfo->FileId.Cell,
4188 pObjectInfo->FileId.Volume,
4189 pObjectInfo->FileId.Vnode,
4190 pObjectInfo->FileId.Unique));
4192 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4195 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4196 AFS_TRACE_LEVEL_VERBOSE,
4197 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4198 &DirEntry->NameInformation.FileName,
4199 pObjectInfo->FileId.Cell,
4200 pObjectInfo->FileId.Volume,
4201 pObjectInfo->FileId.Vnode,
4202 pObjectInfo->FileId.Unique,
4203 pObjectInfo->DataVersion.LowPart,
4204 pDirEnumEntry->DataVersion.LowPart));
4206 bPurgeExtents = TRUE;
4212 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4214 bPurgeExtents = TRUE;
4216 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4217 AFS_TRACE_LEVEL_VERBOSE,
4218 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4219 &DirEntry->NameInformation.FileName,
4220 pObjectInfo->FileId.Cell,
4221 pObjectInfo->FileId.Volume,
4222 pObjectInfo->FileId.Vnode,
4223 pObjectInfo->FileId.Unique));
4225 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4228 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4229 AFS_TRACE_LEVEL_VERBOSE,
4230 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4231 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4232 PsGetCurrentThread()));
4234 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4238 // Release Fcb->Resource to avoid Trend Micro deadlock
4241 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
4246 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4251 if( !NT_SUCCESS( stIoStatus.Status))
4254 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4255 AFS_TRACE_LEVEL_ERROR,
4256 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4257 &DirEntry->NameInformation.FileName,
4258 pObjectInfo->FileId.Cell,
4259 pObjectInfo->FileId.Volume,
4260 pObjectInfo->FileId.Vnode,
4261 pObjectInfo->FileId.Unique,
4263 stIoStatus.Information));
4265 ntStatus = stIoStatus.Status;
4268 if ( bPurgeExtents &&
4269 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4272 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
4278 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4279 AFS_TRACE_LEVEL_WARNING,
4280 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4281 &DirEntry->NameInformation.FileName,
4282 pObjectInfo->FileId.Cell,
4283 pObjectInfo->FileId.Volume,
4284 pObjectInfo->FileId.Vnode,
4285 pObjectInfo->FileId.Unique));
4287 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4291 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
4293 ntStatus = GetExceptionCode();
4297 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4298 &DirEntry->NameInformation.FileName,
4299 pObjectInfo->FileId.Cell,
4300 pObjectInfo->FileId.Volume,
4301 pObjectInfo->FileId.Vnode,
4302 pObjectInfo->FileId.Unique,
4305 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4308 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4309 AFS_TRACE_LEVEL_VERBOSE,
4310 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4311 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4312 PsGetCurrentThread()));
4314 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4316 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
4325 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4330 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4332 bReleaseFcb = FALSE;
4334 if ( bPurgeExtents &&
4337 AFSFlushExtents( pCurrentFcb,
4344 // Update the metadata for the entry but only if it is safe to do so.
4345 // If it was determined that a data version change has occurred or
4346 // that a pending data verification was required, do not update the
4347 // ObjectInfo meta data or the FileObject size information. That
4348 // way it is consistent for the next time that the data is verified
4352 if ( !(bPurgeExtents && bSafeToPurge))
4355 ntStatus = AFSUpdateMetaData( DirEntry,
4358 if( !NT_SUCCESS( ntStatus))
4361 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4362 AFS_TRACE_LEVEL_ERROR,
4363 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4364 &DirEntry->NameInformation.FileName,
4365 pObjectInfo->FileId.Cell,
4366 pObjectInfo->FileId.Volume,
4367 pObjectInfo->FileId.Vnode,
4368 pObjectInfo->FileId.Unique,
4374 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4377 // Update file sizes
4380 if( pObjectInfo->Fcb != NULL)
4382 FILE_OBJECT *pCCFileObject;
4384 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4385 AFS_TRACE_LEVEL_VERBOSE,
4386 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4387 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4388 PsGetCurrentThread()));
4390 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4396 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4398 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4399 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4400 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4402 if ( pCCFileObject != NULL)
4404 CcSetFileSizes( pCCFileObject,
4405 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4408 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
4411 ntStatus = GetExceptionCode();
4415 "EXCEPTION - AFSValidateEntry CcSetFileSizes failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4416 pObjectInfo->FileId.Cell,
4417 pObjectInfo->FileId.Volume,
4418 pObjectInfo->FileId.Vnode,
4419 pObjectInfo->FileId.Unique,
4423 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4424 AFS_TRACE_LEVEL_VERBOSE,
4425 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4426 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4427 PsGetCurrentThread()));
4429 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4435 case AFS_FILE_TYPE_DIRECTORY:
4438 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4442 // For a directory or root entry flush the content of
4443 // the directory enumeration.
4446 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4447 AFS_TRACE_LEVEL_VERBOSE,
4448 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4449 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4450 PsGetCurrentThread()));
4452 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4455 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4456 AFS_TRACE_LEVEL_VERBOSE_2,
4457 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4458 &DirEntry->NameInformation.FileName,
4459 pObjectInfo->FileId.Cell,
4460 pObjectInfo->FileId.Volume,
4461 pObjectInfo->FileId.Vnode,
4462 pObjectInfo->FileId.Unique));
4464 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4467 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4470 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4473 if( !NT_SUCCESS( ntStatus))
4476 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4477 AFS_TRACE_LEVEL_ERROR,
4478 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4479 &DirEntry->NameInformation.FileName,
4480 pObjectInfo->FileId.Cell,
4481 pObjectInfo->FileId.Volume,
4482 pObjectInfo->FileId.Vnode,
4483 pObjectInfo->FileId.Unique,
4491 // Update the metadata for the entry
4494 ntStatus = AFSUpdateMetaData( DirEntry,
4497 if( NT_SUCCESS( ntStatus))
4500 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4508 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4509 AFS_TRACE_LEVEL_WARNING,
4510 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4511 pObjectInfo->FileType,
4513 &DirEntry->NameInformation.FileName,
4514 pObjectInfo->FileId.Cell,
4515 pObjectInfo->FileId.Volume,
4516 pObjectInfo->FileId.Vnode,
4517 pObjectInfo->FileId.Unique));
4527 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4530 if( pDirEnumEntry != NULL)
4533 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4541 AFSInitializeSpecialShareNameList()
4544 NTSTATUS ntStatus = STATUS_SUCCESS;
4545 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4546 AFSObjectInfoCB *pObjectInfoCB = NULL;
4547 UNICODE_STRING uniShareName;
4548 ULONG ulEntryLength = 0;
4549 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4555 RtlInitUnicodeString( &uniShareName,
4558 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4561 if( pObjectInfoCB == NULL)
4564 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4567 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4568 AFS_OBJECT_REFERENCE_GLOBAL);
4570 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4571 AFS_TRACE_LEVEL_VERBOSE,
4572 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4576 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4578 ulEntryLength = sizeof( AFSDirectoryCB) +
4579 uniShareName.Length;
4581 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4585 if( pDirNode == NULL)
4588 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4589 AFS_OBJECT_REFERENCE_GLOBAL);
4591 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4592 AFS_TRACE_LEVEL_VERBOSE,
4593 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4600 AFSDeleteObjectInfo( &pObjectInfoCB);
4603 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4606 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4607 AFS_TRACE_LEVEL_VERBOSE,
4608 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4611 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4612 sizeof( AFSNonPagedDirectoryCB),
4613 AFS_DIR_ENTRY_NP_TAG);
4615 if( pNonPagedDirEntry == NULL)
4618 AFSLibExFreePoolWithTag( pDirNode,
4621 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4622 AFS_OBJECT_REFERENCE_GLOBAL);
4624 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4625 AFS_TRACE_LEVEL_VERBOSE,
4626 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4633 AFSDeleteObjectInfo( &pObjectInfoCB);
4636 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4639 RtlZeroMemory( pDirNode,
4642 RtlZeroMemory( pNonPagedDirEntry,
4643 sizeof( AFSNonPagedDirectoryCB));
4645 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4647 pDirNode->NonPaged = pNonPagedDirEntry;
4649 pDirNode->ObjectInformation = pObjectInfoCB;
4655 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4657 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4659 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4661 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4663 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4664 uniShareName.Buffer,
4665 pDirNode->NameInformation.FileName.Length);
4667 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4670 AFSSpecialShareNames = pDirNode;
4672 pLastDirNode = pDirNode;
4675 RtlInitUnicodeString( &uniShareName,
4678 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4681 if( pObjectInfoCB == NULL)
4684 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4687 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4688 AFS_OBJECT_REFERENCE_GLOBAL);
4690 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4691 AFS_TRACE_LEVEL_VERBOSE,
4692 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4696 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4698 ulEntryLength = sizeof( AFSDirectoryCB) +
4699 uniShareName.Length;
4701 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4705 if( pDirNode == NULL)
4708 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4709 AFS_OBJECT_REFERENCE_GLOBAL);
4711 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4712 AFS_TRACE_LEVEL_VERBOSE,
4713 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4720 AFSDeleteObjectInfo( &pObjectInfoCB);
4723 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4726 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4727 AFS_TRACE_LEVEL_VERBOSE,
4728 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4731 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4732 sizeof( AFSNonPagedDirectoryCB),
4733 AFS_DIR_ENTRY_NP_TAG);
4735 if( pNonPagedDirEntry == NULL)
4738 AFSLibExFreePoolWithTag( pDirNode,
4741 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4742 AFS_OBJECT_REFERENCE_GLOBAL);
4744 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4745 AFS_TRACE_LEVEL_VERBOSE,
4746 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4753 AFSDeleteObjectInfo( &pObjectInfoCB);
4756 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4759 RtlZeroMemory( pDirNode,
4762 RtlZeroMemory( pNonPagedDirEntry,
4763 sizeof( AFSNonPagedDirectoryCB));
4765 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4767 pDirNode->NonPaged = pNonPagedDirEntry;
4769 pDirNode->ObjectInformation = pObjectInfoCB;
4775 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4777 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4779 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4781 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4783 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4784 uniShareName.Buffer,
4785 pDirNode->NameInformation.FileName.Length);
4787 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4790 pLastDirNode->ListEntry.fLink = pDirNode;
4792 pDirNode->ListEntry.bLink = pLastDirNode;
4796 if( !NT_SUCCESS( ntStatus))
4799 if( AFSSpecialShareNames != NULL)
4802 pDirNode = AFSSpecialShareNames;
4804 while( pDirNode != NULL)
4807 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4809 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
4810 AFS_OBJECT_REFERENCE_GLOBAL);
4812 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4813 AFS_TRACE_LEVEL_VERBOSE,
4814 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4815 pDirNode->ObjectInformation,
4821 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4824 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4826 AFSLibExFreePoolWithTag( pDirNode->NonPaged,
4827 AFS_DIR_ENTRY_NP_TAG);
4829 AFSLibExFreePoolWithTag( pDirNode,
4832 pDirNode = pLastDirNode;
4835 AFSSpecialShareNames = NULL;
4844 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4845 IN UNICODE_STRING *SecondaryName)
4848 AFSDirectoryCB *pDirectoryCB = NULL;
4849 ULONGLONG ullHash = 0;
4850 UNICODE_STRING uniFullShareName;
4856 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4857 AFS_TRACE_LEVEL_VERBOSE_2,
4858 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4862 uniFullShareName = *ShareName;
4865 // Generate our hash value
4868 ullHash = AFSGenerateCRC( &uniFullShareName,
4872 // Loop through our special share names to see if this is one of them
4875 pDirectoryCB = AFSSpecialShareNames;
4877 while( pDirectoryCB != NULL)
4880 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4886 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4890 return pDirectoryCB;
4894 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4898 // Block on the queue flush event
4901 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4911 AFSWaitOnQueuedReleases()
4914 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4917 // Block on the queue flush event
4920 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4930 AFSIsEqualFID( IN AFSFileID *FileId1,
4931 IN AFSFileID *FileId2)
4934 BOOLEAN bIsEqual = FALSE;
4936 if( FileId1->Hash == FileId2->Hash &&
4937 FileId1->Unique == FileId2->Unique &&
4938 FileId1->Vnode == FileId2->Vnode &&
4939 FileId1->Volume == FileId2->Volume &&
4940 FileId1->Cell == FileId2->Cell)
4950 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4953 NTSTATUS ntStatus = STATUS_SUCCESS;
4954 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4959 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4962 // Reset the directory list information
4965 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4967 while( pCurrentDirEntry != NULL)
4970 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4972 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
4973 pCurrentDirEntry->NameArrayReferenceCount <= 0)
4976 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4977 AFS_TRACE_LEVEL_VERBOSE,
4978 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4980 &pCurrentDirEntry->NameInformation.FileName));
4982 AFSDeleteDirEntry( ObjectInfoCB,
4988 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4989 AFS_TRACE_LEVEL_VERBOSE,
4990 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4992 &pCurrentDirEntry->NameInformation.FileName));
4994 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4996 AFSRemoveNameEntry( ObjectInfoCB,
5000 pCurrentDirEntry = pNextDirEntry;
5003 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
5005 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
5007 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
5009 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
5011 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
5013 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
5015 AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
5016 AFS_TRACE_LEVEL_VERBOSE,
5017 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
5018 ObjectInfoCB->FileId.Cell,
5019 ObjectInfoCB->FileId.Volume,
5020 ObjectInfoCB->FileId.Vnode,
5021 ObjectInfoCB->FileId.Unique));
5028 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
5031 NTSTATUS ntStatus = STATUS_SUCCESS;
5032 AFSDirectoryCB *pDirGlobalDirNode = NULL;
5033 UNICODE_STRING uniFullName;
5038 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
5039 AFS_TRACE_LEVEL_VERBOSE,
5040 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
5041 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
5042 PsGetCurrentThread()));
5044 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
5047 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
5050 try_return( ntStatus);
5054 // Initialize the root information
5057 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
5060 // Enumerate the shares in the volume
5063 ntStatus = AFSEnumerateDirectory( AuthGroup,
5064 &AFSGlobalRoot->ObjectInformation,
5067 if( !NT_SUCCESS( ntStatus))
5070 try_return( ntStatus);
5073 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
5075 uniFullName.MaximumLength = PAGE_SIZE;
5076 uniFullName.Length = 0;
5078 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
5079 uniFullName.MaximumLength,
5080 AFS_GENERIC_MEMORY_12_TAG);
5082 if( uniFullName.Buffer == NULL)
5086 // Reset the directory content
5089 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
5091 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
5093 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5097 // Populate our list of entries in the NP enumeration list
5100 while( pDirGlobalDirNode != NULL)
5103 uniFullName.Buffer[ 0] = L'\\';
5104 uniFullName.Buffer[ 1] = L'\\';
5106 uniFullName.Length = 2 * sizeof( WCHAR);
5108 RtlCopyMemory( &uniFullName.Buffer[ 2],
5109 AFSServerName.Buffer,
5110 AFSServerName.Length);
5112 uniFullName.Length += AFSServerName.Length;
5114 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
5116 uniFullName.Length += sizeof( WCHAR);
5118 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
5119 pDirGlobalDirNode->NameInformation.FileName.Buffer,
5120 pDirGlobalDirNode->NameInformation.FileName.Length);
5122 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
5124 AFSAddConnectionEx( &uniFullName,
5125 RESOURCEDISPLAYTYPE_SHARE,
5128 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
5131 AFSLibExFreePoolWithTag( uniFullName.Buffer,
5132 AFS_GENERIC_MEMORY_12_TAG);
5136 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
5143 AFSIsRelativeName( IN UNICODE_STRING *Name)
5146 BOOLEAN bIsRelative = FALSE;
5148 if( Name->Length > 0 &&
5149 Name->Buffer[ 0] != L'\\')
5159 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
5161 UNICODE_STRING uniTempName;
5162 BOOLEAN bIsAbsolute = FALSE;
5165 // An absolute AFS path must begin with \afs\... or equivalent
5168 if ( Name->Length == 0 ||
5169 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
5170 Name->Buffer[ 0] != L'\\' ||
5171 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
5177 uniTempName.Length = AFSMountRootName.Length;
5178 uniTempName.MaximumLength = AFSMountRootName.Length;
5180 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5181 uniTempName.MaximumLength,
5182 AFS_NAME_BUFFER_TWO_TAG);
5184 if( uniTempName.Buffer == NULL)
5190 RtlCopyMemory( uniTempName.Buffer,
5192 AFSMountRootName.Length);
5194 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
5198 AFSExFreePoolWithTag( uniTempName.Buffer,
5199 AFS_NAME_BUFFER_TWO_TAG);
5206 AFSUpdateName( IN UNICODE_STRING *Name)
5211 while( usIndex < Name->Length/sizeof( WCHAR))
5214 if( Name->Buffer[ usIndex] == L'/')
5217 Name->Buffer[ usIndex] = L'\\';
5227 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
5228 IN OUT ULONG *Flags,
5229 IN WCHAR *NameBuffer,
5230 IN USHORT NameLength)
5233 NTSTATUS ntStatus = STATUS_SUCCESS;
5234 WCHAR *pTmpBuffer = NULL;
5240 // If we have enough space then just move in the name otherwise
5241 // allocate a new buffer
5244 if( TargetName->Length < NameLength)
5247 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5249 AFS_NAME_BUFFER_FIVE_TAG);
5251 if( pTmpBuffer == NULL)
5254 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5257 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5260 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5263 TargetName->MaximumLength = NameLength;
5265 TargetName->Buffer = pTmpBuffer;
5267 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5270 TargetName->Length = NameLength;
5272 RtlCopyMemory( TargetName->Buffer,
5274 TargetName->Length);
5277 // Update the name in the buffer
5280 AFSUpdateName( TargetName);
5291 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5296 // Depending on the type of node, set the event
5299 switch( Fcb->Header.NodeTypeCode)
5302 case AFS_DIRECTORY_FCB:
5307 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5317 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5323 // Depending on the type of node, set the event
5326 switch( Fcb->Header.NodeTypeCode)
5329 case AFS_DIRECTORY_FCB:
5334 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5336 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5346 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5349 BOOLEAN bIsInProcess = FALSE;
5354 if( ObjectInfo->Fcb == NULL)
5357 try_return( bIsInProcess);
5360 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5363 case AFS_DIRECTORY_FCB:
5368 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5371 bIsInProcess = TRUE;
5383 return bIsInProcess;
5387 AFSVerifyVolume( IN ULONGLONG ProcessId,
5388 IN AFSVolumeCB *VolumeCB)
5391 UNREFERENCED_PARAMETER(ProcessId);
5392 UNREFERENCED_PARAMETER(VolumeCB);
5393 NTSTATUS ntStatus = STATUS_SUCCESS;
5400 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5403 NTSTATUS ntStatus = STATUS_SUCCESS;
5404 AFSObjectInfoCB *pObjectInfoCB = NULL;
5405 AFSDirectoryCB *pDirNode = NULL;
5406 ULONG ulEntryLength = 0;
5407 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5413 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
5416 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5419 if( pObjectInfoCB == NULL)
5422 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5424 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5427 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5428 AFS_OBJECT_REFERENCE_PIOCTL);
5430 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5431 AFS_TRACE_LEVEL_VERBOSE,
5432 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5436 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5438 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5440 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5442 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5444 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5448 if( pDirNode == NULL)
5451 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5454 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5455 AFS_TRACE_LEVEL_VERBOSE,
5456 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5459 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5460 sizeof( AFSNonPagedDirectoryCB),
5461 AFS_DIR_ENTRY_NP_TAG);
5463 if( pNonPagedDirEntry == NULL)
5466 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5469 RtlZeroMemory( pDirNode,
5472 RtlZeroMemory( pNonPagedDirEntry,
5473 sizeof( AFSNonPagedDirectoryCB));
5475 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5477 pDirNode->NonPaged = pNonPagedDirEntry;
5479 pDirNode->ObjectInformation = pObjectInfoCB;
5481 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5487 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5489 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5491 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5493 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5495 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5496 AFSPIOCtlName.Buffer,
5497 pDirNode->NameInformation.FileName.Length);
5499 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5502 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5505 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5506 AFS_TRACE_LEVEL_WARNING,
5507 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5508 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5511 try_return( ntStatus = STATUS_REPARSE);
5516 if ( ntStatus != STATUS_SUCCESS)
5519 if ( pDirNode != NULL)
5522 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5523 AFS_TRACE_LEVEL_VERBOSE,
5524 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
5527 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5530 if( pNonPagedDirEntry != NULL)
5533 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5535 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5538 if ( pObjectInfoCB != NULL)
5541 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
5542 AFS_OBJECT_REFERENCE_PIOCTL);
5544 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5545 AFS_TRACE_LEVEL_VERBOSE,
5546 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
5553 AFSDeleteObjectInfo( &pObjectInfoCB);
5563 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5564 IN AFSDirectoryCB *DirectoryCB,
5565 IN UNICODE_STRING *ParentPathName,
5566 IN AFSNameArrayHdr *RelatedNameArray,
5568 OUT AFSFileInfoCB *FileInfo)
5571 NTSTATUS ntStatus = STATUS_SUCCESS;
5572 AFSDirEnumEntry *pDirEntry = NULL;
5573 UNICODE_STRING uniFullPathName = {0};
5574 AFSNameArrayHdr *pNameArray = NULL;
5575 AFSVolumeCB *pVolumeCB = NULL;
5576 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5577 AFSVolumeCB *pNewVolumeCB = NULL;
5578 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5579 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5580 AFSDirectoryCB *pNewParentDirEntry = NULL;
5581 WCHAR *pwchBuffer = NULL;
5582 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5583 ULONG ulNameDifference = 0;
5590 // Retrieve a target name for the entry
5593 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5596 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5599 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5601 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5606 if( !NT_SUCCESS( ntStatus) ||
5607 pDirEntry->TargetNameLength == 0)
5610 if( pDirEntry != NULL)
5613 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5616 try_return( ntStatus);
5619 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5622 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5626 // Update the target name
5629 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5630 &DirectoryCB->Flags,
5631 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5632 (USHORT)pDirEntry->TargetNameLength);
5634 if( !NT_SUCCESS( ntStatus))
5637 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5639 try_return( ntStatus);
5643 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5647 // Need to pass the full path in for parsing.
5650 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5653 uniFullPathName.Length = 0;
5654 uniFullPathName.MaximumLength = ParentPathName->Length +
5656 DirectoryCB->NameInformation.TargetName.Length;
5658 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5659 uniFullPathName.MaximumLength,
5660 AFS_NAME_BUFFER_SIX_TAG);
5662 if( uniFullPathName.Buffer == NULL)
5665 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5667 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5670 pwchBuffer = uniFullPathName.Buffer;
5672 RtlZeroMemory( uniFullPathName.Buffer,
5673 uniFullPathName.MaximumLength);
5675 RtlCopyMemory( uniFullPathName.Buffer,
5676 ParentPathName->Buffer,
5677 ParentPathName->Length);
5679 uniFullPathName.Length = ParentPathName->Length;
5681 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5682 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5685 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5687 uniFullPathName.Length += sizeof( WCHAR);
5690 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5691 DirectoryCB->NameInformation.TargetName.Buffer,
5692 DirectoryCB->NameInformation.TargetName.Length);
5694 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5696 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5697 uniParsedName.MaximumLength = uniParsedName.Length;
5699 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5701 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5704 // We populate up to the current parent
5707 if( RelatedNameArray != NULL)
5710 pNameArray = AFSInitNameArray( NULL,
5711 RelatedNameArray->MaxElementCount);
5713 if( pNameArray == NULL)
5716 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5719 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5726 pNameArray = AFSInitNameArray( NULL,
5729 if( pNameArray == NULL)
5732 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5735 ntStatus = AFSPopulateNameArray( pNameArray,
5740 if( !NT_SUCCESS( ntStatus))
5743 try_return( ntStatus);
5746 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5748 pParentDirEntry = ParentDirectoryCB;
5753 uniFullPathName.Length = 0;
5754 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5756 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5757 uniFullPathName.MaximumLength,
5758 AFS_NAME_BUFFER_SEVEN_TAG);
5760 if( uniFullPathName.Buffer == NULL)
5763 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5765 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5768 pwchBuffer = uniFullPathName.Buffer;
5770 RtlZeroMemory( uniFullPathName.Buffer,
5771 uniFullPathName.MaximumLength);
5773 RtlCopyMemory( uniFullPathName.Buffer,
5774 DirectoryCB->NameInformation.TargetName.Buffer,
5775 DirectoryCB->NameInformation.TargetName.Length);
5777 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5780 // This name should begin with the \afs server so parse it off and check it
5783 FsRtlDissectName( uniFullPathName,
5787 if( RtlCompareUnicodeString( &uniComponentName,
5792 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5794 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5795 AFS_TRACE_LEVEL_ERROR,
5796 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5799 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5802 uniFullPathName = uniRemainingPath;
5804 uniParsedName = uniFullPathName;
5806 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5808 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5814 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5817 if( pNameArray == NULL)
5820 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5823 pVolumeCB = AFSGlobalRoot;
5825 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5829 // Increment the ref count on the volume and dir entry for correct processing below
5832 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
5834 lCount = AFSVolumeIncrement( pVolumeCB,
5835 VolumeReferenceReason);
5837 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5838 AFS_TRACE_LEVEL_VERBOSE,
5839 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
5841 VolumeReferenceReason,
5844 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
5846 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5847 AFS_TRACE_LEVEL_VERBOSE,
5848 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5849 &pParentDirEntry->NameInformation.FileName,
5854 ntStatus = AFSLocateNameEntry( NULL,
5859 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5863 &NewVolumeReferenceReason,
5864 &pNewParentDirEntry,
5868 if ( pNewVolumeCB != NULL)
5871 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
5872 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
5873 // the reference on pVolumeCB that was held prior to the call.
5874 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
5875 // will be released second.
5878 lCount = AFSVolumeDecrement( pVolumeCB,
5879 VolumeReferenceReason);
5881 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5882 AFS_TRACE_LEVEL_VERBOSE,
5883 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
5885 VolumeReferenceReason,
5888 pVolumeCB = pNewVolumeCB;
5890 pNewVolumeCB = NULL;
5892 VolumeReferenceReason = NewVolumeReferenceReason;
5894 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5898 // AFSLocateNameEntry does not alter the reference count of
5899 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
5900 // a reference held.
5903 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5905 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5906 AFS_TRACE_LEVEL_VERBOSE,
5907 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
5908 &pParentDirEntry->NameInformation.FileName,
5912 pParentDirEntry = pNewParentDirEntry;
5914 pNewParentDirEntry = NULL;
5916 if( !NT_SUCCESS( ntStatus) ||
5917 ntStatus == STATUS_REPARSE)
5920 try_return( ntStatus);
5924 // Store off the information
5927 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5930 // Check for the mount point being returned
5933 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
5934 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5937 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5939 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
5942 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
5945 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
5950 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5954 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5956 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5958 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5960 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5962 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5964 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5968 if( pDirEntry != NULL)
5971 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
5974 if( pDirectoryEntry != NULL)
5977 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
5979 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5980 AFS_TRACE_LEVEL_VERBOSE,
5981 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5982 &pDirectoryEntry->NameInformation.FileName,
5987 ASSERT( lCount >= 0);
5990 if ( pParentDirEntry != NULL)
5993 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5995 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5996 AFS_TRACE_LEVEL_VERBOSE,
5997 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5998 &pParentDirEntry->NameInformation.FileName,
6003 ASSERT( lCount >= 0);
6006 if( pVolumeCB != NULL)
6009 lCount = AFSVolumeDecrement( pVolumeCB,
6010 VolumeReferenceReason);
6012 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6013 AFS_TRACE_LEVEL_VERBOSE,
6014 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
6016 VolumeReferenceReason,
6020 if( pNameArray != NULL)
6023 AFSFreeNameArray( pNameArray);
6026 if( pwchBuffer != NULL)
6030 // Always free the buffer that we allocated as AFSLocateNameEntry
6031 // will not free it. If uniFullPathName.Buffer was allocated by
6032 // AFSLocateNameEntry, then we must free that as well.
6033 // Check that the uniFullPathName.Buffer in the string is not the same
6034 // offset by the length of the server name
6037 if( uniFullPathName.Length > 0 &&
6038 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6041 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6044 AFSExFreePoolWithTag( pwchBuffer, 0);
6052 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6053 IN ULONGLONG HashIndex)
6056 NTSTATUS ntStatus = STATUS_SUCCESS;
6057 AFSObjectInfoCB *pObjectInfo = NULL;
6063 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6064 sizeof( AFSObjectInfoCB),
6065 AFS_OBJECT_INFO_TAG);
6067 if( pObjectInfo == NULL)
6070 try_return( pObjectInfo);
6073 RtlZeroMemory( pObjectInfo,
6074 sizeof( AFSObjectInfoCB));
6076 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6077 sizeof( AFSNonPagedObjectInfoCB),
6078 AFS_NP_OBJECT_INFO_TAG);
6080 if( pObjectInfo->NonPagedInfo == NULL)
6083 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6085 try_return( pObjectInfo = NULL);
6088 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6090 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6092 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6094 if( ParentObjectInfo != NULL)
6097 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6099 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6101 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6103 AFSAcquireShared( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6106 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6107 AFS_OBJECT_REFERENCE_CHILD);
6109 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6110 AFS_TRACE_LEVEL_VERBOSE,
6111 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6115 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6119 // Initialize the access time
6122 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6127 ASSERT( ParentObjectInfo);
6130 // Insert the entry into the object tree and list
6133 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6135 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6138 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6143 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6144 &pObjectInfo->TreeEntry);
6146 ASSERT( NT_SUCCESS( ntStatus));
6150 // And the object list in the volume
6153 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6156 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6161 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6163 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6166 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6169 // Indicate the object is in the hash tree and linked list in the volume
6172 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6184 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6190 if ( ObjectInfo->ObjectReferenceCount == 0)
6193 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6196 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6201 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6204 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6209 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6211 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6216 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6218 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6224 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6228 LONG lCount, lCount2;
6230 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6233 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6238 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6240 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6242 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6245 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6248 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6250 ASSERT( lCount2 >= 0);
6252 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6258 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6259 IN AFSFileID *FileId,
6260 IN BOOLEAN bUpdateLastUse)
6262 DWORD ntStatus = STATUS_SUCCESS;
6264 AFSObjectInfoCB *pObjectInfo = NULL;
6267 ullIndex = AFSCreateLowIndex( FileId);
6269 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
6272 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6275 pObjectInfo = &VolumeCB->ObjectInformation;
6280 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6282 (AFSBTreeEntry **)&pObjectInfo);
6285 if ( NT_SUCCESS( ntStatus)) {
6287 lCount = AFSObjectInfoIncrement( pObjectInfo,
6288 AFS_OBJECT_REFERENCE_FIND);
6290 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6291 AFS_TRACE_LEVEL_VERBOSE,
6292 "AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
6296 if ( bUpdateLastUse)
6299 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6303 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6309 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6313 lCount = AFSObjectInfoDecrement( *ppObjectInfo,
6314 AFS_OBJECT_REFERENCE_FIND);
6316 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6317 AFS_TRACE_LEVEL_VERBOSE,
6318 "AFSReleaseObjectInfo Decrement count on object %p Cnt %d\n",
6322 *ppObjectInfo = NULL;
6326 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6328 BOOLEAN bAcquiredTreeLock = FALSE;
6329 AFSObjectInfoCB *pObjectInfo = NULL;
6330 AFSVolumeCB * pVolume = NULL;
6331 BOOLEAN bHeldInService;
6332 AFSObjectInfoCB * pParentObjectInfo = NULL;
6338 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
6342 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6343 // embedded in the VolumeCB.
6351 pVolume = (*ppObjectInfo)->VolumeCB;
6353 if( !ExIsResourceAcquiredExclusiveLite( pVolume->ObjectInfoTree.TreeLock))
6356 ASSERT( !ExIsResourceAcquiredLite( pVolume->ObjectInfoTree.TreeLock));
6358 AFSAcquireExcl( pVolume->ObjectInfoTree.TreeLock,
6361 bAcquiredTreeLock = TRUE;
6364 for ( lCount = 0; lCount < AFS_OBJECT_REFERENCE_MAX; lCount++)
6367 ASSERT( (*ppObjectInfo)->ObjectReferences[ lCount] >= 0);
6370 ASSERT( (*ppObjectInfo)->ObjectReferenceCount == 0);
6372 pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
6376 if ( pObjectInfo == NULL)
6379 try_return( NOTHING);
6382 ASSERT( *ppObjectInfo == NULL);
6384 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6387 pParentObjectInfo = AFSFindObjectInfo( pVolume,
6388 &pObjectInfo->ParentFileId,
6391 if( pParentObjectInfo != NULL)
6394 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6396 AFSAcquireShared( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6399 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6400 AFS_OBJECT_REFERENCE_CHILD);
6402 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6403 AFS_TRACE_LEVEL_VERBOSE,
6404 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6408 AFSReleaseResource( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6410 AFSReleaseObjectInfo( &pParentObjectInfo);
6415 // Remove it from the tree and list if it was inserted
6418 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6421 AFSRemoveHashEntry( &pVolume->ObjectInfoTree.TreeHead,
6422 &pObjectInfo->TreeEntry);
6425 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6428 if( pObjectInfo->ListEntry.fLink == NULL)
6431 pVolume->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6433 if( pVolume->ObjectInfoListTail != NULL)
6436 pVolume->ObjectInfoListTail->ListEntry.fLink = NULL;
6442 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6445 if( pObjectInfo->ListEntry.bLink == NULL)
6448 pVolume->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6450 if( pVolume->ObjectInfoListHead != NULL)
6453 pVolume->ObjectInfoListHead->ListEntry.bLink = NULL;
6459 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6463 bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6468 FileId = pObjectInfo->FileId;
6471 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6473 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6475 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6477 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6479 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6483 if( bAcquiredTreeLock)
6486 AFSReleaseResource( pVolume->ObjectInfoTree.TreeLock);
6490 // Release the fid in the service
6496 AFSReleaseFid( &FileId);
6504 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6505 OUT AFSDirectoryCB **TargetDirEntry)
6508 NTSTATUS ntStatus = STATUS_SUCCESS;
6509 AFSDirEnumEntry *pDirEntry = NULL;
6510 UNICODE_STRING uniFullPathName = {0};
6511 AFSNameArrayHdr *pNameArray = NULL;
6512 AFSVolumeCB *pVolumeCB = NULL;
6513 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6514 AFSVolumeCB *pNewVolumeCB = NULL;
6515 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6516 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6517 AFSDirectoryCB *pNewParentDirEntry = NULL;
6518 WCHAR *pwchBuffer = NULL;
6519 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6520 ULONG ulNameDifference = 0;
6527 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6528 DirectoryCB->ObjectInformation,
6532 if( !NT_SUCCESS( ntStatus))
6534 try_return( ntStatus);
6538 // Retrieve a target name for the entry
6541 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6544 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6547 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6549 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6554 if( !NT_SUCCESS( ntStatus) ||
6555 pDirEntry->TargetNameLength == 0)
6558 if( pDirEntry != NULL)
6561 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6564 try_return( ntStatus);
6567 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6570 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6574 // Update the target name
6577 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6578 &DirectoryCB->Flags,
6579 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6580 (USHORT)pDirEntry->TargetNameLength);
6582 if( !NT_SUCCESS( ntStatus))
6585 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6587 try_return( ntStatus);
6591 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6595 // Need to pass the full path in for parsing.
6598 uniFullPathName.Length = 0;
6599 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6601 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6602 uniFullPathName.MaximumLength,
6603 AFS_NAME_BUFFER_EIGHT_TAG);
6605 if( uniFullPathName.Buffer == NULL)
6608 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6610 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6613 pwchBuffer = uniFullPathName.Buffer;
6615 RtlZeroMemory( uniFullPathName.Buffer,
6616 uniFullPathName.MaximumLength);
6618 RtlCopyMemory( uniFullPathName.Buffer,
6619 DirectoryCB->NameInformation.TargetName.Buffer,
6620 DirectoryCB->NameInformation.TargetName.Length);
6622 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6625 // This name should begin with the \afs server so parse it off and chech it
6628 FsRtlDissectName( uniFullPathName,
6632 if( RtlCompareUnicodeString( &uniComponentName,
6638 // Try evaluating the full path
6641 uniFullPathName.Buffer = pwchBuffer;
6643 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6645 uniFullPathName.MaximumLength = uniFullPathName.Length;
6650 uniFullPathName = uniRemainingPath;
6653 uniParsedName = uniFullPathName;
6655 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6657 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6663 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6666 if( pNameArray == NULL)
6669 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6672 pVolumeCB = AFSGlobalRoot;
6674 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6676 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
6678 lCount = AFSVolumeIncrement( pVolumeCB,
6679 VolumeReferenceReason);
6681 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6682 AFS_TRACE_LEVEL_VERBOSE,
6683 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
6685 VolumeReferenceReason,
6688 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6690 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6691 AFS_TRACE_LEVEL_VERBOSE,
6692 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6693 &pParentDirEntry->NameInformation.FileName,
6698 ntStatus = AFSLocateNameEntry( NULL,
6707 &VolumeReferenceReason,
6708 &pNewParentDirEntry,
6712 if ( pNewVolumeCB != NULL)
6715 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6716 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6717 // the reference on pVolumeCB that was held prior to the call.
6718 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6719 // will be released second.
6722 lCount = AFSVolumeDecrement( pVolumeCB,
6723 VolumeReferenceReason);
6725 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6726 AFS_TRACE_LEVEL_VERBOSE,
6727 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
6729 VolumeReferenceReason,
6732 pVolumeCB = pNewVolumeCB;
6734 pNewVolumeCB = NULL;
6736 VolumeReferenceReason = NewVolumeReferenceReason;
6738 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6742 // AFSLocateNameEntry does not alter the reference count of
6743 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6744 // a reference held.
6747 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6749 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6750 AFS_TRACE_LEVEL_VERBOSE,
6751 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
6752 &pParentDirEntry->NameInformation.FileName,
6756 pParentDirEntry = pNewParentDirEntry;
6758 pNewParentDirEntry = NULL;
6760 if( !NT_SUCCESS( ntStatus) ||
6761 ntStatus == STATUS_REPARSE)
6766 try_return( ntStatus);
6770 // Pass back the target dir entry for this request
6771 // The caller must release the DirOpenReferenceCount
6774 *TargetDirEntry = pDirectoryEntry;
6776 pDirectoryEntry = NULL;
6780 if( pDirectoryEntry != NULL)
6783 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6785 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6786 AFS_TRACE_LEVEL_VERBOSE,
6787 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6788 &pDirectoryEntry->NameInformation.FileName,
6793 ASSERT( lCount >= 0);
6796 if ( pParentDirEntry != NULL)
6799 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6801 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6802 AFS_TRACE_LEVEL_VERBOSE,
6803 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6804 &pParentDirEntry->NameInformation.FileName,
6809 ASSERT( lCount >= 0);
6812 if( pDirEntry != NULL)
6815 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6818 if( pVolumeCB != NULL)
6821 lCount = AFSVolumeDecrement( pVolumeCB,
6822 VolumeReferenceReason);
6824 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6825 AFS_TRACE_LEVEL_VERBOSE,
6826 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
6828 VolumeReferenceReason,
6832 if( pNameArray != NULL)
6835 AFSFreeNameArray( pNameArray);
6838 if( pwchBuffer != NULL)
6842 // Always free the buffer that we allocated as AFSLocateNameEntry
6843 // will not free it. If uniFullPathName.Buffer was allocated by
6844 // AFSLocateNameEntry, then we must free that as well.
6845 // Check that the uniFullPathName.Buffer in the string is not the same
6846 // offset by the length of the server name
6849 if( uniFullPathName.Length > 0 &&
6850 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6853 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6856 AFSExFreePoolWithTag( pwchBuffer, 0);
6864 AFSCleanupFcb( IN AFSFcb *Fcb,
6865 IN BOOLEAN ForceFlush)
6868 NTSTATUS ntStatus = STATUS_SUCCESS;
6869 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6870 LARGE_INTEGER liTime;
6871 IO_STATUS_BLOCK stIoStatus;
6876 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6878 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6880 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6883 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6884 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6887 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6888 AFS_TRACE_LEVEL_VERBOSE,
6889 "AFSCleanupEntry Acquiring Fcb lock %p SHARED %08lX\n",
6890 &Fcb->NPFcb->Resource,
6891 PsGetCurrentThread()));
6893 AFSAcquireShared( &Fcb->NPFcb->Resource,
6896 if( Fcb->OpenReferenceCount > 0)
6899 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
6900 AFS_TRACE_LEVEL_VERBOSE,
6901 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
6902 &Fcb->NPFcb->SectionObjectResource,
6903 PsGetCurrentThread()));
6905 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
6911 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6916 if( !NT_SUCCESS( stIoStatus.Status))
6919 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6920 AFS_TRACE_LEVEL_ERROR,
6921 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6922 Fcb->ObjectInformation->FileId.Cell,
6923 Fcb->ObjectInformation->FileId.Volume,
6924 Fcb->ObjectInformation->FileId.Vnode,
6925 Fcb->ObjectInformation->FileId.Unique,
6927 stIoStatus.Information));
6929 ntStatus = stIoStatus.Status;
6932 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
6935 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6941 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6942 AFS_TRACE_LEVEL_WARNING,
6943 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
6944 Fcb->ObjectInformation->FileId.Cell,
6945 Fcb->ObjectInformation->FileId.Volume,
6946 Fcb->ObjectInformation->FileId.Vnode,
6947 Fcb->ObjectInformation->FileId.Unique));
6949 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6953 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
6956 ntStatus = GetExceptionCode();
6960 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
6961 Fcb->ObjectInformation->FileId.Cell,
6962 Fcb->ObjectInformation->FileId.Volume,
6963 Fcb->ObjectInformation->FileId.Vnode,
6964 Fcb->ObjectInformation->FileId.Unique,
6967 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6970 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
6971 AFS_TRACE_LEVEL_VERBOSE,
6972 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
6973 &Fcb->NPFcb->SectionObjectResource,
6974 PsGetCurrentThread()));
6976 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
6979 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6980 AFS_TRACE_LEVEL_VERBOSE,
6981 "AFSCleanupEntry Releasing Fcb lock %p SHARED %08lX\n",
6982 &Fcb->NPFcb->Resource,
6983 PsGetCurrentThread()));
6985 AFSReleaseResource( &Fcb->NPFcb->Resource);
6988 // Wait for any currently running flush or release requests to complete
6991 AFSWaitOnQueuedFlushes( Fcb);
6994 // Now perform another flush on the file
6997 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7001 AFSReleaseExtentsWithFlush( Fcb,
7007 if( Fcb->OpenReferenceCount == 0 ||
7008 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7009 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7012 AFSTearDownFcbExtents( Fcb,
7016 try_return( ntStatus);
7019 KeQueryTickCount( &liTime);
7022 // First up are there dirty extents in the cache to flush?
7025 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7026 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7030 // The file has been marked as invalid. Dump it
7033 AFSTearDownFcbExtents( Fcb,
7036 else if( ForceFlush ||
7037 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7038 Fcb->Specific.File.ExtentCount) &&
7039 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7040 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7042 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7044 Fcb->OpenReferenceCount == 0)
7047 AFSReleaseExtentsWithFlush( Fcb,
7054 // If there are extents and they haven't been used recently *and*
7055 // are not being used
7059 ( 0 != Fcb->Specific.File.ExtentCount &&
7060 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7061 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7062 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7065 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7066 AFS_TRACE_LEVEL_VERBOSE,
7067 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7068 &Fcb->NPFcb->SectionObjectResource,
7069 PsGetCurrentThread()));
7071 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7077 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7082 if( !NT_SUCCESS( stIoStatus.Status))
7085 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7086 AFS_TRACE_LEVEL_ERROR,
7087 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7088 Fcb->ObjectInformation->FileId.Cell,
7089 Fcb->ObjectInformation->FileId.Volume,
7090 Fcb->ObjectInformation->FileId.Vnode,
7091 Fcb->ObjectInformation->FileId.Unique,
7093 stIoStatus.Information));
7095 ntStatus = stIoStatus.Status;
7099 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7102 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7108 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7109 AFS_TRACE_LEVEL_WARNING,
7110 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7111 Fcb->ObjectInformation->FileId.Cell,
7112 Fcb->ObjectInformation->FileId.Volume,
7113 Fcb->ObjectInformation->FileId.Vnode,
7114 Fcb->ObjectInformation->FileId.Unique));
7116 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7120 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
7123 ntStatus = GetExceptionCode();
7127 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7128 Fcb->ObjectInformation->FileId.Cell,
7129 Fcb->ObjectInformation->FileId.Volume,
7130 Fcb->ObjectInformation->FileId.Vnode,
7131 Fcb->ObjectInformation->FileId.Unique,
7135 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7136 AFS_TRACE_LEVEL_VERBOSE,
7137 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7138 &Fcb->NPFcb->SectionObjectResource,
7139 PsGetCurrentThread()));
7141 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7143 if( Fcb->OpenReferenceCount <= 0)
7147 // Tear em down we'll not be needing them again
7150 AFSTearDownFcbExtents( Fcb,
7157 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7158 AFS_TRACE_LEVEL_VERBOSE,
7159 "AFSCleanupFcb Failed to Acquire Fcb SectionObject lock %p EXCL %08lX\n",
7160 &Fcb->NPFcb->SectionObjectResource,
7161 PsGetCurrentThread()));
7163 ntStatus = STATUS_RETRY;
7176 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7177 IN UNICODE_STRING *NewFileName)
7180 NTSTATUS ntStatus = STATUS_SUCCESS;
7181 WCHAR *pTmpBuffer = NULL;
7186 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7189 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7192 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7194 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7196 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7200 // OK, we need to allocate a new name buffer
7203 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7204 NewFileName->Length,
7205 AFS_NAME_BUFFER_NINE_TAG);
7207 if( pTmpBuffer == NULL)
7210 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7213 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7215 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7217 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7220 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7222 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7223 NewFileName->Buffer,
7224 NewFileName->Length);
7235 AFSReadCacheFile( IN void *ReadBuffer,
7236 IN LARGE_INTEGER *ReadOffset,
7237 IN ULONG RequestedDataLength,
7238 IN OUT PULONG BytesRead)
7241 NTSTATUS ntStatus = STATUS_SUCCESS;
7244 PIO_STACK_LOCATION pIoStackLocation = NULL;
7245 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7246 FILE_OBJECT *pCacheFileObject = NULL;
7251 pCacheFileObject = AFSReferenceCacheFileObject();
7253 if( pCacheFileObject == NULL)
7255 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7258 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7261 // Initialize the event
7264 KeInitializeEvent( &kEvent,
7265 SynchronizationEvent,
7269 // Allocate an irp for this request. This could also come from a
7270 // private pool, for instance.
7273 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7279 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7283 // Build the IRP's main body
7286 pIrp->UserBuffer = ReadBuffer;
7288 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7289 pIrp->RequestorMode = KernelMode;
7290 pIrp->Flags |= IRP_READ_OPERATION;
7293 // Set up the I/O stack location.
7296 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7297 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7298 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7299 pIoStackLocation->FileObject = pCacheFileObject;
7300 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7302 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7305 // Set the completion routine.
7308 IoSetCompletionRoutine( pIrp,
7316 // Send it to the FSD
7319 ntStatus = IoCallDriver( pTargetDeviceObject,
7322 if( NT_SUCCESS( ntStatus))
7329 ntStatus = KeWaitForSingleObject( &kEvent,
7335 if( NT_SUCCESS( ntStatus))
7338 ntStatus = pIrp->IoStatus.Status;
7340 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7346 if( pCacheFileObject != NULL)
7348 AFSReleaseCacheFileObject( pCacheFileObject);
7354 if( pIrp->MdlAddress != NULL)
7357 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7360 MmUnlockPages( pIrp->MdlAddress);
7363 IoFreeMdl( pIrp->MdlAddress);
7366 pIrp->MdlAddress = NULL;
7380 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7385 UNREFERENCED_PARAMETER(Irp);
7386 UNREFERENCED_PARAMETER(DeviceObject);
7387 KEVENT *pEvent = (KEVENT *)Context;
7393 return STATUS_MORE_PROCESSING_REQUIRED;
7397 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7400 BOOLEAN bIsEmpty = FALSE;
7401 AFSDirectoryCB *pDirEntry = NULL;
7406 ASSERT( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY);
7408 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7413 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7416 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7418 while( pDirEntry != NULL)
7421 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7422 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7430 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7435 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7442 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7443 IN AFSDirectoryCB *DirEntry)
7446 NTSTATUS ntStatus = STATUS_SUCCESS;
7451 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7454 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7455 AFS_TRACE_LEVEL_VERBOSE,
7456 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7458 &DirEntry->NameInformation.FileName));
7460 try_return( ntStatus);
7463 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7466 // Remove the entry from the parent tree
7469 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7470 AFS_TRACE_LEVEL_VERBOSE,
7471 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7473 &DirEntry->NameInformation.FileName));
7475 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7478 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7479 AFS_TRACE_LEVEL_VERBOSE,
7480 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7482 &DirEntry->NameInformation.FileName));
7484 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7487 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7491 // From the short name tree
7494 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7495 AFS_TRACE_LEVEL_VERBOSE,
7496 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7498 &DirEntry->NameInformation.FileName));
7500 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7503 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7506 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7507 AFS_TRACE_LEVEL_VERBOSE,
7508 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7510 &DirEntry->NameInformation.FileName));
7512 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7514 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7525 AFSGetAuthenticationId()
7528 LARGE_INTEGER liAuthId = {0,0};
7529 NTSTATUS ntStatus = STATUS_SUCCESS;
7530 PACCESS_TOKEN hToken = NULL;
7531 PTOKEN_STATISTICS pTokenInfo = NULL;
7532 BOOLEAN bCopyOnOpen = FALSE;
7533 BOOLEAN bEffectiveOnly = FALSE;
7534 BOOLEAN bPrimaryToken = FALSE;
7535 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7540 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7543 &stImpersonationLevel);
7548 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7553 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7554 AFS_TRACE_LEVEL_ERROR,
7555 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
7557 try_return( ntStatus);
7560 bPrimaryToken = TRUE;
7563 ntStatus = SeQueryInformationToken( hToken,
7565 (PVOID *)&pTokenInfo);
7567 if( !NT_SUCCESS( ntStatus))
7570 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7571 AFS_TRACE_LEVEL_ERROR,
7572 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
7575 try_return( ntStatus);
7578 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7579 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7581 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7582 AFS_TRACE_LEVEL_VERBOSE,
7583 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7584 liAuthId.QuadPart));
7594 PsDereferenceImpersonationToken( hToken);
7599 PsDereferencePrimaryToken( hToken);
7603 if( pTokenInfo != NULL)
7606 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7614 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7618 UNREFERENCED_PARAMETER(Fcb);
7619 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7621 Fcb->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7624 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7626 Fcb->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7629 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7631 Fcb->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7634 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7636 Fcb->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7639 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7641 Fcb->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7648 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7651 BOOLEAN bIsValid = TRUE;
7653 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7655 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7657 while( pCurrentDirEntry != NULL)
7660 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7664 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7669 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7670 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7673 if( pDirEntry == NULL)
7680 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7683 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
7686 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7688 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7690 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7699 AFSReferenceCacheFileObject()
7702 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7703 FILE_OBJECT *pCacheFileObject = NULL;
7705 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7708 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7710 if( pCacheFileObject != NULL)
7712 ObReferenceObject( pCacheFileObject);
7715 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7717 return pCacheFileObject;
7721 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7724 ASSERT( CacheFileObject != NULL);
7726 ObDereferenceObject( CacheFileObject);
7732 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7735 NTSTATUS ntStatus = STATUS_SUCCESS;
7736 AFSDeviceExt *pControlDevExt = NULL;
7737 ULONG ulTimeIncrement = 0;
7743 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7745 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7747 AFSServerName = LibraryInit->AFSServerName;
7749 AFSMountRootName = LibraryInit->AFSMountRootName;
7751 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7754 // Callbacks in the framework
7757 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7759 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7761 AFSDebugTraceFnc = AFSDbgLogMsg;
7763 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7765 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7767 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
7769 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7771 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7773 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7775 if( LibraryInit->AFSCacheBaseAddress != NULL)
7778 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7780 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7782 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7786 // Initialize some flush parameters
7789 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7791 ulTimeIncrement = KeQueryTimeIncrement();
7793 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7794 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7795 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7796 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7797 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7800 // Initialize the global root entry
7803 ntStatus = AFSInitVolume( NULL,
7804 &LibraryInit->GlobalRootFid,
7805 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
7808 if( !NT_SUCCESS( ntStatus))
7811 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7812 AFS_TRACE_LEVEL_ERROR,
7813 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7816 try_return( ntStatus);
7819 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7822 if( !NT_SUCCESS( ntStatus))
7825 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7826 AFS_TRACE_LEVEL_ERROR,
7827 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7830 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7831 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7833 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7834 AFS_TRACE_LEVEL_VERBOSE,
7835 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7839 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7841 try_return( ntStatus);
7845 // Update the node type code to AFS_ROOT_ALL
7848 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7850 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7853 // Invalidate all known volumes since contact with the service and therefore
7854 // the file server was lost.
7857 AFSInvalidateAllVolumes();
7860 // Drop the locks acquired above
7863 AFSInitVolumeWorker( AFSGlobalRoot);
7865 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7866 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7868 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7869 AFS_TRACE_LEVEL_VERBOSE,
7870 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7874 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7876 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7890 NTSTATUS ntStatus = STATUS_SUCCESS;
7891 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7897 if( AFSGlobalDotDirEntry != NULL)
7900 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
7901 AFS_OBJECT_REFERENCE_GLOBAL);
7903 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7904 AFS_TRACE_LEVEL_VERBOSE,
7905 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7906 AFSGlobalDotDirEntry->ObjectInformation,
7912 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
7915 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7917 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry->NonPaged,
7918 AFS_DIR_ENTRY_NP_TAG);
7920 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry,
7923 AFSGlobalDotDirEntry = NULL;
7926 if( AFSGlobalDotDotDirEntry != NULL)
7929 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
7930 AFS_OBJECT_REFERENCE_GLOBAL);
7932 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7933 AFS_TRACE_LEVEL_VERBOSE,
7934 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7935 AFSGlobalDotDotDirEntry->ObjectInformation,
7941 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
7944 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7946 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry->NonPaged,
7947 AFS_DIR_ENTRY_NP_TAG);
7949 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry,
7952 AFSGlobalDotDotDirEntry = NULL;
7955 if( AFSSpecialShareNames != NULL)
7958 pDirNode = AFSSpecialShareNames;
7960 while( pDirNode != NULL)
7963 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7965 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
7966 AFS_OBJECT_REFERENCE_GLOBAL);
7968 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7969 AFS_TRACE_LEVEL_VERBOSE,
7970 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7971 pDirNode->ObjectInformation,
7977 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
7980 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7982 AFSLibExFreePoolWithTag( pDirNode->NonPaged,
7983 AFS_DIR_ENTRY_NP_TAG);
7985 AFSLibExFreePoolWithTag( pDirNode,
7988 pDirNode = pLastDirNode;
7991 AFSSpecialShareNames = NULL;
7999 AFSDefaultLogMsg( IN ULONG Subsystem,
8005 UNREFERENCED_PARAMETER(Subsystem);
8006 UNREFERENCED_PARAMETER(Level);
8007 NTSTATUS ntStatus = STATUS_SUCCESS;
8009 char chDebugBuffer[ 256];
8014 va_start( va_args, Format);
8016 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8021 if( NT_SUCCESS( ntStatus))
8023 DbgPrint( chDebugBuffer);
8033 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8034 IN ULONG InputBufferLength,
8035 IN AFSStatusInfoCB *StatusInfo,
8036 OUT ULONG *ReturnLength)
8039 NTSTATUS ntStatus = STATUS_SUCCESS;
8040 AFSVolumeCB *pVolumeCB = NULL;
8041 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8042 AFSVolumeCB *pNewVolumeCB = NULL;
8043 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8044 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8045 AFSObjectInfoCB *pObjectInfo = NULL;
8046 ULONGLONG ullIndex = 0;
8047 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8048 AFSNameArrayHdr *pNameArray = NULL;
8049 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8050 AFSDirectoryCB *pNewParentDirEntry = NULL;
8057 // If we are given a FID then look up the entry by that, otherwise
8061 if( GetStatusInfo->FileID.Cell != 0 &&
8062 GetStatusInfo->FileID.Volume != 0 &&
8063 GetStatusInfo->FileID.Vnode != 0 &&
8064 GetStatusInfo->FileID.Unique != 0)
8067 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8070 // Locate the volume node
8073 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8075 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8077 (AFSBTreeEntry **)&pVolumeCB);
8079 if( pVolumeCB != NULL)
8082 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8084 lCount = AFSVolumeIncrement( pVolumeCB,
8085 VolumeReferenceReason);
8087 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8088 AFS_TRACE_LEVEL_VERBOSE,
8089 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
8091 VolumeReferenceReason,
8095 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8097 if( !NT_SUCCESS( ntStatus) ||
8100 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8103 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8106 pObjectInfo = &pVolumeCB->ObjectInformation;
8108 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8111 lCount = AFSObjectInfoIncrement( pObjectInfo,
8112 AFS_OBJECT_REFERENCE_STATUS);
8114 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8115 AFS_TRACE_LEVEL_VERBOSE,
8116 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8120 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8125 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
8128 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8130 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8132 (AFSBTreeEntry **)&pObjectInfo);
8134 if( pObjectInfo != NULL)
8138 // Reference the node so it won't be torn down
8141 lCount = AFSObjectInfoIncrement( pObjectInfo,
8142 AFS_OBJECT_REFERENCE_STATUS);
8144 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8145 AFS_TRACE_LEVEL_VERBOSE,
8146 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8150 KeQueryTickCount( &pObjectInfo->LastAccessCount);
8153 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8155 if( !NT_SUCCESS( ntStatus) ||
8156 pObjectInfo == NULL)
8158 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8165 if( GetStatusInfo->FileNameLength == 0 ||
8166 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8168 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8171 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8172 uniFullPathName.MaximumLength = uniFullPathName.Length;
8174 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8177 // This name should begin with the \afs server so parse it off and check it
8180 FsRtlDissectName( uniFullPathName,
8184 if( RtlCompareUnicodeString( &uniComponentName,
8188 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8189 AFS_TRACE_LEVEL_ERROR,
8190 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8193 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8196 uniFullPathName = uniRemainingPath;
8198 uniParsedName = uniFullPathName;
8204 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8207 if( pNameArray == NULL)
8209 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8212 pVolumeCB = AFSGlobalRoot;
8214 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8217 // Increment the ref count on the volume and dir entry for correct processing below
8220 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8222 lCount = AFSVolumeIncrement( pVolumeCB,
8223 VolumeReferenceReason);
8225 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8226 AFS_TRACE_LEVEL_VERBOSE,
8227 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8229 VolumeReferenceReason,
8232 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8234 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8235 AFS_TRACE_LEVEL_VERBOSE,
8236 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8237 &pParentDirEntry->NameInformation.FileName,
8242 ntStatus = AFSLocateNameEntry( NULL,
8247 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8248 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8252 &NewVolumeReferenceReason,
8253 &pNewParentDirEntry,
8257 if ( pNewVolumeCB != NULL)
8261 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8262 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8263 // the reference on pVolumeCB that was held prior to the call.
8264 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8265 // will be released second.
8268 lCount = AFSVolumeDecrement( pVolumeCB,
8269 VolumeReferenceReason);
8271 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8272 AFS_TRACE_LEVEL_VERBOSE,
8273 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8275 VolumeReferenceReason,
8278 pVolumeCB = pNewVolumeCB;
8280 pNewVolumeCB = NULL;
8282 VolumeReferenceReason = NewVolumeReferenceReason;
8284 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8288 // AFSLocateNameEntry does not alter the reference count of
8289 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8290 // a reference held.
8293 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8295 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8296 AFS_TRACE_LEVEL_VERBOSE,
8297 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8298 &pParentDirEntry->NameInformation.FileName,
8302 pParentDirEntry = pNewParentDirEntry;
8304 pNewParentDirEntry = NULL;
8306 if( !NT_SUCCESS( ntStatus) ||
8307 ntStatus == STATUS_REPARSE)
8312 try_return( ntStatus);
8315 pObjectInfo = pDirectoryEntry->ObjectInformation;
8317 AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
8320 lCount = AFSObjectInfoIncrement( pObjectInfo,
8321 AFS_OBJECT_REFERENCE_STATUS);
8323 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8324 AFS_TRACE_LEVEL_VERBOSE,
8325 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8329 AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
8333 // At this point we have an object info block, return the information
8336 StatusInfo->FileId = pObjectInfo->FileId;
8338 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8340 StatusInfo->Expiration = pObjectInfo->Expiration;
8342 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8344 StatusInfo->FileType = pObjectInfo->FileType;
8346 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8348 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8350 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8352 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8354 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8356 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8358 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8360 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8362 StatusInfo->EaSize = pObjectInfo->EaSize;
8364 StatusInfo->Links = pObjectInfo->Links;
8367 // Return the information length
8370 *ReturnLength = sizeof( AFSStatusInfoCB);
8374 if( pDirectoryEntry != NULL)
8377 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8379 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8380 AFS_TRACE_LEVEL_VERBOSE,
8381 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8382 &pDirectoryEntry->NameInformation.FileName,
8387 ASSERT( lCount >= 0);
8390 if ( pParentDirEntry != NULL)
8393 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8395 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8396 AFS_TRACE_LEVEL_VERBOSE,
8397 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8398 &pParentDirEntry->NameInformation.FileName,
8403 ASSERT( lCount >= 0);
8406 if( pVolumeCB != NULL)
8409 if( pObjectInfo != NULL)
8412 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8415 lCount = AFSObjectInfoDecrement( pObjectInfo,
8416 AFS_OBJECT_REFERENCE_STATUS);
8418 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8419 AFS_TRACE_LEVEL_VERBOSE,
8420 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8424 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8427 lCount = AFSVolumeDecrement( pVolumeCB,
8428 VolumeReferenceReason);
8430 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8431 AFS_TRACE_LEVEL_VERBOSE,
8432 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8434 VolumeReferenceReason,
8438 if( pNameArray != NULL)
8441 AFSFreeNameArray( pNameArray);
8449 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8450 IN UNICODE_STRING *ComponentName)
8453 NTSTATUS ntStatus = STATUS_SUCCESS;
8454 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8455 AFSDirectoryCB *pDirEntry = NULL;
8463 // Search for the entry in the parent
8466 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8467 AFS_TRACE_LEVEL_VERBOSE_2,
8468 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8471 ulCRC = AFSGenerateCRC( ComponentName,
8474 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8477 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8481 if( pDirEntry == NULL)
8485 // Missed so perform a case insensitive lookup
8488 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8489 AFS_TRACE_LEVEL_VERBOSE_2,
8490 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8493 ulCRC = AFSGenerateCRC( ComponentName,
8496 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8500 if( pDirEntry == NULL)
8504 // OK, if this component is a valid short name then try
8505 // a lookup in the short name tree
8508 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8509 RtlIsNameLegalDOS8Dot3( ComponentName,
8514 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8515 AFS_TRACE_LEVEL_VERBOSE_2,
8516 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8519 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8526 if( pDirEntry != NULL)
8528 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8530 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8531 AFS_TRACE_LEVEL_VERBOSE,
8532 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8533 &pDirEntry->NameInformation.FileName,
8538 ASSERT( lCount >= 0);
8541 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8543 if( pDirEntry == NULL)
8546 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8547 AFS_TRACE_LEVEL_VERBOSE_2,
8548 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8550 STATUS_OBJECT_NAME_NOT_FOUND));
8552 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8556 // We have the symlink object but previously failed to process it so return access
8560 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8561 AFS_TRACE_LEVEL_VERBOSE_2,
8562 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8565 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8567 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8569 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8570 AFS_TRACE_LEVEL_VERBOSE,
8571 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8572 &pDirEntry->NameInformation.FileName,
8577 ASSERT( lCount >= 0);
8588 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8589 OUT UNICODE_STRING *ComponentName)
8592 NTSTATUS ntStatus = STATUS_SUCCESS;
8593 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8595 uniFullPathName = *FullPathName;
8600 FsRtlDissectName( uniFullPathName,
8604 if( uniRemainingPath.Length == 0)
8609 uniFullPathName = uniRemainingPath;
8612 if( uniComponentName.Length > 0)
8614 *ComponentName = uniComponentName;
8621 AFSDumpTraceFiles_Default()
8627 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8630 BOOLEAN bIsValidName = TRUE;
8636 while( usIndex < FileName->Length/sizeof( WCHAR))
8639 if( FileName->Buffer[ usIndex] == L':' ||
8640 FileName->Buffer[ usIndex] == L'*' ||
8641 FileName->Buffer[ usIndex] == L'?' ||
8642 FileName->Buffer[ usIndex] == L'"' ||
8643 FileName->Buffer[ usIndex] == L'<' ||
8644 FileName->Buffer[ usIndex] == L'>')
8646 bIsValidName = FALSE;
8654 return bIsValidName;
8658 AFSCreateDefaultSecurityDescriptor()
8661 NTSTATUS ntStatus = STATUS_SUCCESS;
8663 ULONG ulSACLSize = 0;
8664 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8665 ULONG ulACESize = 0;
8666 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8667 ULONG ulSDLength = 0;
8668 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8669 PSID pWorldSID = NULL;
8670 ULONG *pulSubAuthority = NULL;
8671 ULONG ulWorldSIDLEngth = 0;
8676 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8678 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8680 AFS_GENERIC_MEMORY_29_TAG);
8682 if( pWorldSID == NULL)
8684 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8686 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8689 RtlZeroMemory( pWorldSID,
8692 RtlInitializeSid( pWorldSID,
8693 &SeWorldSidAuthority,
8696 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8697 *pulSubAuthority = SECURITY_WORLD_RID;
8699 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8702 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8707 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8709 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8711 AFS_GENERIC_MEMORY_29_TAG);
8716 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8718 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8721 RtlZeroMemory( pACE,
8724 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8725 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8726 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8727 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8729 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8731 SeExports->SeLowMandatorySid);
8733 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8734 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8736 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8738 AFS_GENERIC_MEMORY_29_TAG);
8743 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8745 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8748 ntStatus = RtlCreateAcl( pSACL,
8752 if( !NT_SUCCESS( ntStatus))
8755 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8758 try_return( ntStatus);
8761 ntStatus = RtlAddAce( pSACL,
8765 pACE->Header.AceSize);
8767 if( !NT_SUCCESS( ntStatus))
8770 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8773 try_return( ntStatus);
8777 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8778 sizeof( SECURITY_DESCRIPTOR),
8779 AFS_GENERIC_MEMORY_27_TAG);
8781 if( pSecurityDescr == NULL)
8784 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8786 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8789 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8790 SECURITY_DESCRIPTOR_REVISION);
8792 if( !NT_SUCCESS( ntStatus))
8795 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8798 try_return( ntStatus);
8801 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8803 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8808 if( !NT_SUCCESS( ntStatus))
8811 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8814 try_return( ntStatus);
8819 // Add in the group and owner to the SD
8822 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8824 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8828 if( !NT_SUCCESS( ntStatus))
8831 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8834 try_return( ntStatus);
8838 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8842 if( !NT_SUCCESS( ntStatus))
8845 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8848 try_return( ntStatus);
8851 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8854 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8856 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8859 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)AFSLibExAllocatePoolWithTag( NonPagedPool,
8861 AFS_GENERIC_MEMORY_27_TAG);
8863 if( pRelativeSecurityDescr == NULL)
8866 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8868 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8871 ulSDLength = PAGE_SIZE;
8873 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8874 pRelativeSecurityDescr,
8877 if( !NT_SUCCESS( ntStatus))
8880 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8883 try_return( ntStatus);
8886 AFSDefaultSD = pRelativeSecurityDescr;
8890 if( !NT_SUCCESS( ntStatus))
8893 if( pRelativeSecurityDescr != NULL)
8896 AFSLibExFreePoolWithTag( pRelativeSecurityDescr,
8897 AFS_GENERIC_MEMORY_27_TAG);
8901 if( pSecurityDescr != NULL)
8904 AFSLibExFreePoolWithTag( pSecurityDescr,
8905 AFS_GENERIC_MEMORY_27_TAG);
8911 AFSLibExFreePoolWithTag( pSACL,
8912 AFS_GENERIC_MEMORY_29_TAG);
8918 AFSLibExFreePoolWithTag( pACE,
8919 AFS_GENERIC_MEMORY_29_TAG);
8922 if( pWorldSID != NULL)
8925 AFSLibExFreePoolWithTag( pWorldSID,
8926 AFS_GENERIC_MEMORY_29_TAG);
8934 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8935 OUT UNICODE_STRING *ParentPath)
8938 *ParentPath = *FullFileName;
8941 // If the final character is a \, jump over it
8944 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8946 ParentPath->Length -= sizeof( WCHAR);
8949 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8951 ParentPath->Length -= sizeof( WCHAR);
8955 // And the separator
8958 ParentPath->Length -= sizeof( WCHAR);
8964 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8965 IN AFSObjectInfoCB *ObjectInfo,
8966 IN BOOLEAN WriteAccess,
8967 OUT GUID *AuthGroup)
8970 NTSTATUS ntStatus = STATUS_SUCCESS;
8971 GUID stAuthGroup, stZeroAuthGroup;
8972 BOOLEAN bFoundAuthGroup = FALSE;
8973 AFSCcb *pCcb = NULL;
8979 RtlZeroMemory( &stAuthGroup,
8982 RtlZeroMemory( &stZeroAuthGroup,
8988 if( ObjectInfo != NULL &&
8989 ObjectInfo->Fcb != NULL)
8991 pFcb = ObjectInfo->Fcb;
8998 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
9001 pCcb = Fcb->CcbListHead;
9003 while( pCcb != NULL)
9007 pCcb->GrantedAccess & FILE_WRITE_DATA)
9009 RtlCopyMemory( &stAuthGroup,
9013 bFoundAuthGroup = TRUE;
9017 else if( pCcb->GrantedAccess & FILE_READ_DATA)
9020 // At least get the read-only access
9023 RtlCopyMemory( &stAuthGroup,
9027 bFoundAuthGroup = TRUE;
9030 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9033 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9036 if( !bFoundAuthGroup)
9039 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9040 (ULONGLONG)PsGetCurrentThreadId(),
9043 if( RtlCompareMemory( &stZeroAuthGroup,
9045 sizeof( GUID)) == sizeof( GUID))
9048 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9050 try_return( ntStatus = STATUS_ACCESS_DENIED);
9054 RtlCopyMemory( AuthGroup,
9067 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9068 IN ULONG InvalidateReason)
9071 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
9072 NTSTATUS ntStatus = STATUS_SUCCESS;
9075 ULONG ulProcessCount = 0;
9082 switch( InvalidateReason)
9085 case AFS_INVALIDATE_DELETED:
9088 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9089 ObjectInfo->Fcb != NULL)
9092 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9095 ObjectInfo->Links = 0;
9097 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9099 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9104 // Clear out the extents
9105 // And get rid of them (note this involves waiting
9106 // for any writes or reads to the cache to complete)
9109 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9112 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9118 case AFS_INVALIDATE_DATA_VERSION:
9121 LARGE_INTEGER liCurrentOffset = {0,0};
9122 LARGE_INTEGER liFlushLength = {0,0};
9123 ULONG ulFlushLength = 0;
9124 BOOLEAN bLocked = FALSE;
9125 BOOLEAN bExtentsLocked = FALSE;
9126 BOOLEAN bCleanExtents = FALSE;
9128 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9129 ObjectInfo->Fcb != NULL)
9132 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9137 if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
9140 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9141 AFS_TRACE_LEVEL_VERBOSE,
9142 "AFSPerformObjectInvalidation DirectIO Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9143 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9144 PsGetCurrentThread()));
9146 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9149 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9156 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9157 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9163 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9164 AFS_TRACE_LEVEL_WARNING,
9165 "AFSPerformObjectInvalidation DirectIO CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9166 ObjectInfo->FileId.Cell,
9167 ObjectInfo->FileId.Volume,
9168 ObjectInfo->FileId.Vnode,
9169 ObjectInfo->FileId.Unique));
9171 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9176 bCleanExtents = TRUE;
9179 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9182 ntStatus = GetExceptionCode();
9186 "EXCEPTION - AFSPerformObjectInvalidation DirectIO FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9187 ObjectInfo->FileId.Cell,
9188 ObjectInfo->FileId.Volume,
9189 ObjectInfo->FileId.Vnode,
9190 ObjectInfo->FileId.Unique,
9193 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9196 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9197 AFS_TRACE_LEVEL_VERBOSE,
9198 "AFSPerformObjectInvalidation DirectIO Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9199 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9200 PsGetCurrentThread()));
9202 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9207 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9208 AFS_TRACE_LEVEL_VERBOSE,
9209 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9210 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9211 PsGetCurrentThread()));
9213 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9216 bExtentsLocked = TRUE;
9219 // There are several possibilities here:
9221 // 0. If there are no extents or all of the extents are dirty, do nothing.
9223 // 1. There could be nothing dirty and an open reference count of zero
9224 // in which case we can just tear down all of the extents without
9225 // holding any resources.
9227 // 2. There could be nothing dirty and a non-zero open reference count
9228 // in which case we can issue a CcPurge against the entire file
9229 // while holding just the Fcb Resource.
9231 // 3. There can be dirty extents in which case we need to identify
9232 // the non-dirty ranges and then perform a CcPurge on just the
9233 // non-dirty ranges while holding just the Fcb Resource.
9236 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9239 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9242 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9244 bExtentsLocked = FALSE;
9246 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9249 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9253 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9259 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9260 AFS_TRACE_LEVEL_VERBOSE,
9261 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9262 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9263 PsGetCurrentThread()));
9265 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9268 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9275 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9276 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9282 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9283 AFS_TRACE_LEVEL_WARNING,
9284 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9285 ObjectInfo->FileId.Cell,
9286 ObjectInfo->FileId.Volume,
9287 ObjectInfo->FileId.Vnode,
9288 ObjectInfo->FileId.Unique));
9290 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9295 bCleanExtents = TRUE;
9298 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9301 ntStatus = GetExceptionCode();
9305 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9306 ObjectInfo->FileId.Cell,
9307 ObjectInfo->FileId.Volume,
9308 ObjectInfo->FileId.Vnode,
9309 ObjectInfo->FileId.Unique,
9312 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9315 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9316 AFS_TRACE_LEVEL_VERBOSE,
9317 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9318 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9319 PsGetCurrentThread()));
9321 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9327 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9329 bExtentsLocked = FALSE;
9331 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9332 AFS_TRACE_LEVEL_VERBOSE,
9333 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9334 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9335 PsGetCurrentThread()));
9337 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9340 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9345 // Must build a list of non-dirty ranges from the beginning of the file
9346 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9347 // ranges. In all but the most extreme random data write scenario there will
9348 // be significantly fewer.
9350 // For each range we need offset and size.
9353 AFSByteRange * ByteRangeList = NULL;
9354 ULONG ulByteRangeCount = 0;
9356 BOOLEAN bPurgeOnClose = FALSE;
9361 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9364 if ( ByteRangeList != NULL ||
9365 ulByteRangeCount == 0)
9368 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9375 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9377 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9378 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9379 &ByteRangeList[ulIndex].FileOffset,
9384 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9385 AFS_TRACE_LEVEL_WARNING,
9386 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9387 ObjectInfo->FileId.Cell,
9388 ObjectInfo->FileId.Volume,
9389 ObjectInfo->FileId.Vnode,
9390 ObjectInfo->FileId.Unique));
9392 bPurgeOnClose = TRUE;
9397 bCleanExtents = TRUE;
9400 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9402 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9404 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9411 // We couldn't allocate the memory to build the purge list
9412 // so just walk the extent list while holding the ExtentsList Resource.
9413 // This could deadlock but we do not have much choice.
9416 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9418 bExtentsLocked = TRUE;
9420 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9424 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9428 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9430 while( ulProcessCount < ulCount)
9432 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9434 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9436 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9437 &pEntry->FileOffset,
9442 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9443 AFS_TRACE_LEVEL_WARNING,
9444 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9445 ObjectInfo->FileId.Cell,
9446 ObjectInfo->FileId.Volume,
9447 ObjectInfo->FileId.Vnode,
9448 ObjectInfo->FileId.Unique));
9450 bPurgeOnClose = TRUE;
9455 bCleanExtents = TRUE;
9459 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9462 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9464 while( liFlushLength.QuadPart > 0)
9467 if( liFlushLength.QuadPart > 512 * 1024000)
9469 ulFlushLength = 512 * 1024000;
9473 ulFlushLength = liFlushLength.LowPart;
9476 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9482 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9483 AFS_TRACE_LEVEL_WARNING,
9484 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9485 ObjectInfo->FileId.Cell,
9486 ObjectInfo->FileId.Volume,
9487 ObjectInfo->FileId.Vnode,
9488 ObjectInfo->FileId.Unique));
9490 bPurgeOnClose = TRUE;
9495 bCleanExtents = TRUE;
9498 liFlushLength.QuadPart -= ulFlushLength;
9502 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9510 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9516 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9517 AFS_TRACE_LEVEL_WARNING,
9518 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9519 ObjectInfo->FileId.Cell,
9520 ObjectInfo->FileId.Volume,
9521 ObjectInfo->FileId.Vnode,
9522 ObjectInfo->FileId.Unique));
9524 bPurgeOnClose = TRUE;
9529 bCleanExtents = TRUE;
9536 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9540 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9543 ntStatus = GetExceptionCode();
9547 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9548 ObjectInfo->FileId.Cell,
9549 ObjectInfo->FileId.Volume,
9550 ObjectInfo->FileId.Vnode,
9551 ObjectInfo->FileId.Unique,
9555 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9556 AFS_TRACE_LEVEL_VERBOSE,
9557 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9558 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9559 PsGetCurrentThread()));
9561 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9565 if ( bExtentsLocked)
9568 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9575 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9581 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9591 // Destroy the reference passed in by the caller to AFSInvalidateObject
9592 // or AFSQueueInvalidateObject
9595 AFSAcquireShared( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
9598 lCount = AFSObjectInfoDecrement( ObjectInfo,
9599 AFS_OBJECT_REFERENCE_INVALIDATION);
9601 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9602 AFS_TRACE_LEVEL_VERBOSE,
9603 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",
9607 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
9614 AFSIgnoreReparsePointToFile( void)
9616 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
9617 BOOLEAN bIgnoreReparsePoint;
9621 bIgnoreReparsePoint = BooleanFlagOn( pDeviceExt->Specific.RDR.ReparsePointPolicy,
9622 AFS_REPARSE_POINT_TO_FILE_AS_FILE);
9625 return bIgnoreReparsePoint;