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,
1874 AFS_TRACE_LEVEL_VERBOSE,
1875 "AFSInvalidateObject Flush/purge Acquiring Fcb lock %p EXCL %08lX\n",
1876 &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1877 PsGetCurrentThread()));
1879 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1882 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1883 AFS_TRACE_LEVEL_VERBOSE,
1884 "AFSInvalidateObject Flush/purge Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
1885 &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1886 PsGetCurrentThread()));
1888 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1894 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1899 if( !NT_SUCCESS( stIoStatus.Status))
1902 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1903 AFS_TRACE_LEVEL_ERROR,
1904 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1905 (*ppObjectInfo)->FileId.Cell,
1906 (*ppObjectInfo)->FileId.Volume,
1907 (*ppObjectInfo)->FileId.Vnode,
1908 (*ppObjectInfo)->FileId.Unique,
1910 stIoStatus.Information));
1912 ntStatus = stIoStatus.Status;
1916 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1919 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1925 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1926 AFS_TRACE_LEVEL_WARNING,
1927 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1928 (*ppObjectInfo)->FileId.Cell,
1929 (*ppObjectInfo)->FileId.Volume,
1930 (*ppObjectInfo)->FileId.Vnode,
1931 (*ppObjectInfo)->FileId.Unique));
1933 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1937 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
1940 ntStatus = GetExceptionCode();
1944 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1945 (*ppObjectInfo)->FileId.Cell,
1946 (*ppObjectInfo)->FileId.Volume,
1947 (*ppObjectInfo)->FileId.Vnode,
1948 (*ppObjectInfo)->FileId.Unique,
1951 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1954 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1955 AFS_TRACE_LEVEL_VERBOSE,
1956 "AFSInvalidateObject Flush/purge Releasing Fcb SectionObject lock %p EXCL %08lX\n",
1957 &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1958 PsGetCurrentThread()));
1960 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1962 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1963 AFS_TRACE_LEVEL_VERBOSE,
1964 "AFSInvalidateObject Flush/purge Releasing Fcb lock %p EXCL %08lX\n",
1965 &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1966 PsGetCurrentThread()));
1968 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->Resource);
1971 // Clear out the extents
1972 // Get rid of them (note this involves waiting
1973 // for any writes or reads to the cache to complete)
1976 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1980 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1983 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1986 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1987 AFS_TRACE_LEVEL_VERBOSE,
1988 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1989 (*ppObjectInfo)->FileId.Cell,
1990 (*ppObjectInfo)->FileId.Volume,
1991 (*ppObjectInfo)->FileId.Vnode,
1992 (*ppObjectInfo)->FileId.Unique));
1994 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1997 // Fall through to the default processing
2003 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
2005 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2009 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2012 if( Reason == AFS_INVALIDATE_CREDS)
2014 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2017 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2019 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2023 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2026 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
2029 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
2032 FILE_ACTION_MODIFIED);
2034 else if ( pParentObjectInfo != NULL)
2037 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2040 FILE_ACTION_MODIFIED);
2044 // Indicate this node requires re-evaluation for the remaining reasons
2047 (*ppObjectInfo)->Expiration.QuadPart = 0;
2049 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2050 AFS_TRACE_LEVEL_VERBOSE,
2051 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2052 (*ppObjectInfo)->FileId.Cell,
2053 (*ppObjectInfo)->FileId.Volume,
2054 (*ppObjectInfo)->FileId.Vnode,
2055 (*ppObjectInfo)->FileId.Unique));
2057 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
2059 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2060 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
2061 ( Reason == AFS_INVALIDATE_CALLBACK ||
2062 Reason == AFS_INVALIDATE_EXPIRED))
2064 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
2065 AFS_INVALIDATE_DATA_VERSION)))
2068 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
2078 if ( pParentObjectInfo != NULL)
2081 AFSReleaseObjectInfo( &pParentObjectInfo);
2088 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
2091 NTSTATUS ntStatus = STATUS_SUCCESS;
2092 AFSVolumeCB *pVolumeCB = NULL;
2093 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2094 ULONGLONG ullIndex = 0;
2095 AFSObjectInfoCB *pObjectInfo = NULL;
2101 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2102 AFS_TRACE_LEVEL_VERBOSE,
2103 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
2104 InvalidateCB->FileID.Cell,
2105 InvalidateCB->FileID.Volume,
2106 InvalidateCB->FileID.Vnode,
2107 InvalidateCB->FileID.Unique,
2108 InvalidateCB->FileType,
2109 InvalidateCB->WholeVolume,
2110 InvalidateCB->Reason));
2113 // Need to locate the Fcb for the directory to purge
2116 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2117 AFS_TRACE_LEVEL_VERBOSE,
2118 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2119 &pDevExt->Specific.RDR.VolumeTreeLock,
2120 PsGetCurrentThread()));
2123 // Starve any exclusive waiters on this paticular call
2126 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2129 // Locate the volume node
2132 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2134 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2136 (AFSBTreeEntry **)&pVolumeCB);
2138 if( pVolumeCB != NULL)
2141 lCount = AFSVolumeIncrement( pVolumeCB,
2142 AFS_VOLUME_REFERENCE_INVALIDATE);
2144 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2145 AFS_TRACE_LEVEL_VERBOSE,
2146 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2151 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2153 if( !NT_SUCCESS( ntStatus) ||
2157 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2158 AFS_TRACE_LEVEL_WARNING,
2159 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2160 InvalidateCB->FileID.Cell,
2161 InvalidateCB->FileID.Volume,
2162 InvalidateCB->FileID.Vnode,
2163 InvalidateCB->FileID.Unique,
2166 try_return( ntStatus = STATUS_SUCCESS);
2170 // If this is a whole volume invalidation then go do it now
2173 if( InvalidateCB->WholeVolume)
2176 ntStatus = AFSInvalidateVolume( pVolumeCB,
2177 InvalidateCB->Reason);
2179 try_return( ntStatus);
2182 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
2185 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2188 pObjectInfo = &pVolumeCB->ObjectInformation;
2193 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2195 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2197 (AFSBTreeEntry **)&pObjectInfo);
2200 if( pObjectInfo != NULL)
2204 // Reference the node so it won't be torn down
2207 lCount = AFSObjectInfoIncrement( pObjectInfo,
2208 AFS_OBJECT_REFERENCE_INVALIDATION);
2210 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2211 AFS_TRACE_LEVEL_VERBOSE,
2212 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2217 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2219 if( !NT_SUCCESS( ntStatus) ||
2220 pObjectInfo == NULL)
2223 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2224 AFS_TRACE_LEVEL_VERBOSE,
2225 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2226 InvalidateCB->FileID.Cell,
2227 InvalidateCB->FileID.Volume,
2228 InvalidateCB->FileID.Vnode,
2229 InvalidateCB->FileID.Unique,
2232 try_return( ntStatus = STATUS_SUCCESS);
2235 AFSInvalidateObject( &pObjectInfo,
2236 InvalidateCB->Reason);
2240 if( pObjectInfo != NULL)
2243 lCount = AFSObjectInfoDecrement( pObjectInfo,
2244 AFS_OBJECT_REFERENCE_INVALIDATION);
2246 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2247 AFS_TRACE_LEVEL_VERBOSE,
2248 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2253 if ( pVolumeCB != NULL)
2256 lCount = AFSVolumeDecrement( pVolumeCB,
2257 AFS_VOLUME_REFERENCE_INVALIDATE);
2259 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2260 AFS_TRACE_LEVEL_VERBOSE,
2261 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2271 AFSIsChildOfParent( IN AFSFcb *Dcb,
2275 BOOLEAN bIsChild = FALSE;
2276 AFSFcb *pCurrentFcb = Fcb;
2277 AFSObjectInfoCB * pParentObjectInfo = NULL;
2279 while( pCurrentFcb != NULL)
2282 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2283 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2291 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2292 &pCurrentFcb->ObjectInformation->ParentFileId,
2295 if ( pParentObjectInfo != NULL)
2298 pCurrentFcb = pParentObjectInfo->Fcb;
2300 AFSReleaseObjectInfo( &pParentObjectInfo);
2314 AFSCreateHighIndex( IN AFSFileID *FileID)
2317 ULONGLONG ullIndex = 0;
2319 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2326 AFSCreateLowIndex( IN AFSFileID *FileID)
2329 ULONGLONG ullIndex = 0;
2331 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2337 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2338 IN ACCESS_MASK GrantedAccess,
2339 IN BOOLEAN DirectoryEntry)
2342 BOOLEAN bAccessGranted = TRUE;
2345 // Check if we are asking for read/write and granted only read only
2346 // NOTE: There will be more checks here
2349 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2351 AFSCheckForReadOnlyAccess( GrantedAccess,
2355 bAccessGranted = FALSE;
2358 return bAccessGranted;
2362 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2365 NTSTATUS ntStatus = STATUS_SUCCESS;
2366 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2372 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2374 if( AFSGlobalRoot == NULL)
2381 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2384 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2391 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2398 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2399 IN UNICODE_STRING *SubstituteName,
2400 IN ULONG StringIndex)
2403 NTSTATUS ntStatus = STATUS_SUCCESS;
2404 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2405 AFSSysNameCB *pSysName = NULL;
2406 ERESOURCE *pSysNameLock = NULL;
2409 UNICODE_STRING uniSysName;
2416 if( IoIs32bitProcess( NULL))
2419 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2421 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2426 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2428 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2432 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2434 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2438 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2439 AFS_TRACE_LEVEL_VERBOSE,
2440 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2442 PsGetCurrentThread()));
2444 AFSAcquireShared( pSysNameLock,
2448 // Find where we are in the list
2451 while( pSysName != NULL &&
2452 ulIndex < StringIndex)
2455 pSysName = pSysName->fLink;
2460 if( pSysName == NULL)
2463 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2464 AFS_TRACE_LEVEL_VERBOSE_2,
2465 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2467 STATUS_OBJECT_NAME_NOT_FOUND));
2469 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2472 RtlInitUnicodeString( &uniSysName,
2475 // If it is a full component of @SYS then just substitue the
2479 if( RtlCompareUnicodeString( &uniSysName,
2484 SubstituteName->Length = pSysName->SysName.Length;
2485 SubstituteName->MaximumLength = SubstituteName->Length;
2487 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2488 SubstituteName->Length,
2489 AFS_SUBST_BUFFER_TAG);
2491 if( SubstituteName->Buffer == NULL)
2494 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2497 RtlCopyMemory( SubstituteName->Buffer,
2498 pSysName->SysName.Buffer,
2499 pSysName->SysName.Length);
2506 while( ComponentName->Buffer[ usIndex] != L'@')
2512 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2513 SubstituteName->MaximumLength = SubstituteName->Length;
2515 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2516 SubstituteName->Length,
2517 AFS_SUBST_BUFFER_TAG);
2519 if( SubstituteName->Buffer == NULL)
2522 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2525 RtlCopyMemory( SubstituteName->Buffer,
2526 ComponentName->Buffer,
2527 usIndex * sizeof( WCHAR));
2529 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2530 pSysName->SysName.Buffer,
2531 pSysName->SysName.Length);
2536 AFSReleaseResource( pSysNameLock);
2543 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2544 IN OUT UNICODE_STRING *ComponentName,
2545 IN UNICODE_STRING *SubstituteName,
2546 IN OUT UNICODE_STRING *RemainingPath,
2547 IN BOOLEAN FreePathName)
2550 NTSTATUS ntStatus = STATUS_SUCCESS;
2551 UNICODE_STRING uniPathName;
2552 USHORT usPrefixNameLen = 0;
2553 SHORT sNameLenDelta = 0;
2559 // If the passed in name can handle the additional length
2560 // then just moves things around
2563 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2565 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2567 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2570 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2573 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2574 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2575 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2578 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2579 SubstituteName->Buffer,
2580 SubstituteName->Length);
2582 FullPathName->Length += sNameLenDelta;
2584 ComponentName->Length += sNameLenDelta;
2586 ComponentName->MaximumLength = ComponentName->Length;
2588 if ( RemainingPath->Buffer)
2591 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2594 try_return( ntStatus);
2598 // Need to re-allocate the buffer
2601 uniPathName.Length = FullPathName->Length -
2602 ComponentName->Length +
2603 SubstituteName->Length;
2605 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2607 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2608 uniPathName.MaximumLength,
2609 AFS_NAME_BUFFER_FOUR_TAG);
2611 if( uniPathName.Buffer == NULL)
2614 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2617 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2619 usPrefixNameLen *= sizeof( WCHAR);
2621 RtlZeroMemory( uniPathName.Buffer,
2622 uniPathName.MaximumLength);
2624 RtlCopyMemory( uniPathName.Buffer,
2625 FullPathName->Buffer,
2628 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2629 SubstituteName->Buffer,
2630 SubstituteName->Length);
2632 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2635 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2636 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2637 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2640 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2642 ComponentName->Length += sNameLenDelta;
2644 ComponentName->MaximumLength = ComponentName->Length;
2646 if ( RemainingPath->Buffer)
2649 RemainingPath->Buffer = uniPathName.Buffer
2650 + (RemainingPath->Buffer - FullPathName->Buffer)
2651 + sNameLenDelta/sizeof( WCHAR);
2656 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2659 *FullPathName = uniPathName;
2670 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2674 NTSTATUS ntStatus = STATUS_SUCCESS;
2675 AFSObjectInfoCB *pCurrentObject = NULL;
2676 AFSObjectInfoCB *pNextObject = NULL;
2682 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2683 AFS_TRACE_LEVEL_VERBOSE,
2684 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2685 VolumeCB->ObjectInformation.FileId.Cell,
2686 VolumeCB->ObjectInformation.FileId.Volume,
2687 VolumeCB->ObjectInformation.FileId.Vnode,
2688 VolumeCB->ObjectInformation.FileId.Unique,
2692 // Depending on the reason for invalidation then perform work on the node
2698 case AFS_INVALIDATE_DELETED:
2702 // Mark this volume as invalid
2705 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2707 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2713 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2717 // Invalidate the volume root directory
2720 pCurrentObject = &VolumeCB->ObjectInformation;
2722 if ( pCurrentObject )
2725 lCount = AFSObjectInfoIncrement( pCurrentObject,
2726 AFS_OBJECT_REFERENCE_INVALIDATION);
2728 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2729 AFS_TRACE_LEVEL_VERBOSE,
2730 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2734 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2736 AFSInvalidateObject( &pCurrentObject,
2739 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2742 if ( pCurrentObject)
2745 lCount = AFSObjectInfoDecrement( pCurrentObject,
2746 AFS_OBJECT_REFERENCE_INVALIDATION);
2748 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2749 AFS_TRACE_LEVEL_VERBOSE,
2750 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2757 // Apply invalidation to all other volume objects
2760 pCurrentObject = VolumeCB->ObjectInfoListHead;
2762 if ( pCurrentObject)
2766 // Reference the node so it won't be torn down
2769 lCount = AFSObjectInfoIncrement( pCurrentObject,
2770 AFS_OBJECT_REFERENCE_INVALIDATION);
2772 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2773 AFS_TRACE_LEVEL_VERBOSE,
2774 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2779 while( pCurrentObject != NULL)
2782 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2788 // Reference the node so it won't be torn down
2791 lCount = AFSObjectInfoIncrement( pNextObject,
2792 AFS_OBJECT_REFERENCE_INVALIDATION);
2794 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2795 AFS_TRACE_LEVEL_VERBOSE,
2796 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2801 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2803 AFSInvalidateObject( &pCurrentObject,
2806 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2809 if ( pCurrentObject )
2812 lCount = AFSObjectInfoDecrement( pCurrentObject,
2813 AFS_OBJECT_REFERENCE_INVALIDATION);
2815 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2816 AFS_TRACE_LEVEL_VERBOSE,
2817 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2822 pCurrentObject = pNextObject;
2825 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2832 AFSInvalidateAllVolumes( VOID)
2834 AFSVolumeCB *pVolumeCB = NULL;
2835 AFSVolumeCB *pNextVolumeCB = NULL;
2836 AFSDeviceExt *pRDRDeviceExt = NULL;
2839 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2841 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2842 AFS_TRACE_LEVEL_VERBOSE,
2843 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2844 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2845 PsGetCurrentThread()));
2847 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2850 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2855 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2856 AFS_TRACE_LEVEL_VERBOSE,
2857 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2858 pVolumeCB->ObjectInfoTree.TreeLock,
2859 PsGetCurrentThread()));
2861 lCount = AFSVolumeIncrement( pVolumeCB,
2862 AFS_VOLUME_REFERENCE_INVALIDATE);
2864 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2865 AFS_TRACE_LEVEL_VERBOSE,
2866 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2871 while( pVolumeCB != NULL)
2874 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2879 lCount = AFSVolumeIncrement( pNextVolumeCB,
2880 AFS_VOLUME_REFERENCE_INVALIDATE);
2882 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2883 AFS_TRACE_LEVEL_VERBOSE,
2884 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2889 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2891 // do I need to hold the volume lock here?
2893 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2895 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2898 lCount = AFSVolumeDecrement( pVolumeCB,
2899 AFS_VOLUME_REFERENCE_INVALIDATE);
2901 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2902 AFS_TRACE_LEVEL_VERBOSE,
2903 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2907 pVolumeCB = pNextVolumeCB;
2910 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2914 AFSVerifyEntry( IN GUID *AuthGroup,
2915 IN AFSDirectoryCB *DirEntry,
2916 IN BOOLEAN bFollowMountPoint)
2919 NTSTATUS ntStatus = STATUS_SUCCESS;
2920 AFSDirEnumEntry *pDirEnumEntry = NULL;
2921 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2922 IO_STATUS_BLOCK stIoStatus;
2927 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2928 AFS_TRACE_LEVEL_VERBOSE_2,
2929 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2930 &DirEntry->NameInformation.FileName,
2931 pObjectInfo->FileId.Cell,
2932 pObjectInfo->FileId.Volume,
2933 pObjectInfo->FileId.Vnode,
2934 pObjectInfo->FileId.Unique));
2936 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2938 bFollowMountPoint ? FALSE : TRUE,
2941 if( !NT_SUCCESS( ntStatus))
2944 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2945 AFS_TRACE_LEVEL_ERROR,
2946 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2947 &DirEntry->NameInformation.FileName,
2948 pObjectInfo->FileId.Cell,
2949 pObjectInfo->FileId.Volume,
2950 pObjectInfo->FileId.Vnode,
2951 pObjectInfo->FileId.Unique,
2954 try_return( ntStatus);
2958 // Check the data version of the file
2961 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2962 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2965 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2966 AFS_TRACE_LEVEL_VERBOSE,
2967 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2968 pObjectInfo->DataVersion.QuadPart,
2969 &DirEntry->NameInformation.FileName,
2970 pObjectInfo->FileId.Cell,
2971 pObjectInfo->FileId.Volume,
2972 pObjectInfo->FileId.Vnode,
2973 pObjectInfo->FileId.Unique));
2976 // We are ok, just get out
2979 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2981 try_return( ntStatus = STATUS_SUCCESS);
2985 // New data version so we will need to process the node based on the type
2988 switch( pDirEnumEntry->FileType)
2991 case AFS_FILE_TYPE_MOUNTPOINT:
2995 // For a mount point we need to ensure the target is the same
2998 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2999 &pDirEnumEntry->TargetFileId))
3005 // Update the metadata for the entry
3008 ntStatus = AFSUpdateMetaData( DirEntry,
3011 if( NT_SUCCESS( ntStatus))
3014 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3020 case AFS_FILE_TYPE_SYMLINK:
3024 // Update the metadata for the entry
3027 ntStatus = AFSUpdateMetaData( DirEntry,
3030 if( NT_SUCCESS( ntStatus))
3033 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3039 case AFS_FILE_TYPE_FILE:
3041 FILE_OBJECT * pCCFileObject = NULL;
3043 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3046 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3047 AFS_TRACE_LEVEL_VERBOSE,
3048 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3049 &DirEntry->NameInformation.FileName,
3050 pObjectInfo->FileId.Cell,
3051 pObjectInfo->FileId.Volume,
3052 pObjectInfo->FileId.Vnode,
3053 pObjectInfo->FileId.Unique));
3055 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3058 if( pObjectInfo->Fcb != NULL)
3061 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3062 AFS_TRACE_LEVEL_VERBOSE,
3063 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3064 &DirEntry->NameInformation.FileName,
3065 pObjectInfo->FileId.Cell,
3066 pObjectInfo->FileId.Volume,
3067 pObjectInfo->FileId.Vnode,
3068 pObjectInfo->FileId.Unique));
3070 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3071 AFS_TRACE_LEVEL_VERBOSE,
3072 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3073 &pObjectInfo->Fcb->NPFcb->Resource,
3074 PsGetCurrentThread()));
3076 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3079 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3080 AFS_TRACE_LEVEL_VERBOSE,
3081 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3082 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3083 PsGetCurrentThread()));
3085 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3091 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3096 if( !NT_SUCCESS( stIoStatus.Status))
3099 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3100 AFS_TRACE_LEVEL_ERROR,
3101 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3102 &DirEntry->NameInformation.FileName,
3103 pObjectInfo->FileId.Cell,
3104 pObjectInfo->FileId.Volume,
3105 pObjectInfo->FileId.Vnode,
3106 pObjectInfo->FileId.Unique,
3108 stIoStatus.Information));
3110 ntStatus = stIoStatus.Status;
3113 if ( pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3116 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3122 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3123 AFS_TRACE_LEVEL_WARNING,
3124 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3125 &DirEntry->NameInformation.FileName,
3126 pObjectInfo->FileId.Cell,
3127 pObjectInfo->FileId.Volume,
3128 pObjectInfo->FileId.Vnode,
3129 pObjectInfo->FileId.Unique));
3131 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3135 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3137 ntStatus = GetExceptionCode();
3141 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3142 &DirEntry->NameInformation.FileName,
3143 pObjectInfo->FileId.Cell,
3144 pObjectInfo->FileId.Volume,
3145 pObjectInfo->FileId.Vnode,
3146 pObjectInfo->FileId.Unique,
3149 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3152 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3153 AFS_TRACE_LEVEL_VERBOSE,
3154 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3155 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3156 PsGetCurrentThread()));
3158 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3160 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3161 AFS_TRACE_LEVEL_VERBOSE,
3162 "AFSVerifyEntry Releasing Fcb lock %p EXCL %08lX\n",
3163 &pObjectInfo->Fcb->NPFcb->Resource,
3164 PsGetCurrentThread()));
3166 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3168 AFSFlushExtents( pObjectInfo->Fcb,
3172 // Acquire the Fcb to purge the cache
3175 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3176 AFS_TRACE_LEVEL_VERBOSE,
3177 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3178 &pObjectInfo->Fcb->NPFcb->Resource,
3179 PsGetCurrentThread()));
3181 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3185 // Update the metadata for the entry
3188 ntStatus = AFSUpdateMetaData( DirEntry,
3191 if( !NT_SUCCESS( ntStatus))
3194 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3195 AFS_TRACE_LEVEL_ERROR,
3196 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3197 &DirEntry->NameInformation.FileName,
3198 pObjectInfo->FileId.Cell,
3199 pObjectInfo->FileId.Volume,
3200 pObjectInfo->FileId.Vnode,
3201 pObjectInfo->FileId.Unique,
3208 // Update file sizes
3211 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3212 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3213 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3215 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3216 AFS_TRACE_LEVEL_VERBOSE,
3217 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3218 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3219 PsGetCurrentThread()));
3221 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3227 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3229 if ( pCCFileObject != NULL)
3231 CcSetFileSizes( pCCFileObject,
3232 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3235 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3238 ntStatus = GetExceptionCode();
3242 "EXCEPTION - AFSVerifyEntry CcSetFileSized failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3243 pObjectInfo->FileId.Cell,
3244 pObjectInfo->FileId.Volume,
3245 pObjectInfo->FileId.Vnode,
3246 pObjectInfo->FileId.Unique,
3250 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3251 AFS_TRACE_LEVEL_VERBOSE,
3252 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3253 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3254 PsGetCurrentThread()));
3256 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3259 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3260 AFS_TRACE_LEVEL_VERBOSE,
3261 "AFSVerifyEntry Releasing Fcb lock %p EXCL %08lX\n",
3262 &pObjectInfo->Fcb->NPFcb->Resource,
3263 PsGetCurrentThread()));
3265 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3271 // Update the metadata for the entry
3274 ntStatus = AFSUpdateMetaData( DirEntry,
3277 if( !NT_SUCCESS( ntStatus))
3280 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3281 AFS_TRACE_LEVEL_ERROR,
3282 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3283 &DirEntry->NameInformation.FileName,
3284 pObjectInfo->FileId.Cell,
3285 pObjectInfo->FileId.Volume,
3286 pObjectInfo->FileId.Vnode,
3287 pObjectInfo->FileId.Unique,
3293 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3294 AFS_TRACE_LEVEL_WARNING,
3295 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3296 &DirEntry->NameInformation.FileName,
3297 pObjectInfo->FileId.Cell,
3298 pObjectInfo->FileId.Volume,
3299 pObjectInfo->FileId.Vnode,
3300 pObjectInfo->FileId.Unique));
3304 if ( NT_SUCCESS( ntStatus))
3307 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3312 case AFS_FILE_TYPE_DIRECTORY:
3316 // For a directory or root entry flush the content of
3317 // the directory enumeration.
3320 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3323 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3324 AFS_TRACE_LEVEL_VERBOSE_2,
3325 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3326 &DirEntry->NameInformation.FileName,
3327 pObjectInfo->FileId.Cell,
3328 pObjectInfo->FileId.Volume,
3329 pObjectInfo->FileId.Vnode,
3330 pObjectInfo->FileId.Unique));
3332 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3335 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3338 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3340 if ( !NT_SUCCESS( ntStatus))
3343 try_return( ntStatus);
3348 // Update the metadata for the entry
3351 ntStatus = AFSUpdateMetaData( DirEntry,
3354 if( NT_SUCCESS( ntStatus))
3357 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3363 case AFS_FILE_TYPE_DFSLINK:
3366 UNICODE_STRING uniTargetName;
3369 // For a DFS link need to check the target name has not changed
3372 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3374 uniTargetName.MaximumLength = uniTargetName.Length;
3376 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3378 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3381 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3382 RtlCompareUnicodeString( &uniTargetName,
3383 &DirEntry->NameInformation.TargetName,
3388 // Update the target name
3391 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3393 uniTargetName.Buffer,
3394 uniTargetName.Length);
3396 if( !NT_SUCCESS( ntStatus))
3399 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3405 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3408 // Update the metadata for the entry
3411 ntStatus = AFSUpdateMetaData( DirEntry,
3414 if( NT_SUCCESS( ntStatus))
3417 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3425 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3426 AFS_TRACE_LEVEL_WARNING,
3427 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3428 pObjectInfo->FileType,
3429 &DirEntry->NameInformation.FileName,
3430 pObjectInfo->FileId.Cell,
3431 pObjectInfo->FileId.Volume,
3432 pObjectInfo->FileId.Vnode,
3433 pObjectInfo->FileId.Unique));
3440 if( pDirEnumEntry != NULL)
3443 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3451 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3454 NTSTATUS ntStatus = STATUS_SUCCESS;
3455 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3456 ULONGLONG ullIndex = 0;
3457 AFSVolumeCB *pVolumeCB = NULL;
3463 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3464 AFS_TRACE_LEVEL_VERBOSE,
3465 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3466 VolumeStatus->Online,
3467 VolumeStatus->FileID.Cell,
3468 VolumeStatus->FileID.Volume));
3471 // Need to locate the Fcb for the directory to purge
3474 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3475 AFS_TRACE_LEVEL_VERBOSE,
3476 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3477 &pDevExt->Specific.RDR.VolumeTreeLock,
3478 PsGetCurrentThread()));
3480 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3483 // Locate the volume node
3486 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3488 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3490 (AFSBTreeEntry **)&pVolumeCB);
3492 if( pVolumeCB != NULL)
3495 lCount = AFSVolumeIncrement( pVolumeCB,
3496 AFS_VOLUME_REFERENCE_INVALIDATE);
3498 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3499 AFS_TRACE_LEVEL_VERBOSE,
3500 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3504 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3507 // Set the volume state accordingly
3510 if( VolumeStatus->Online)
3513 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3518 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3527 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3530 NTSTATUS ntStatus = STATUS_SUCCESS;
3535 if( AFSGlobalRoot == NULL)
3538 try_return( ntStatus);
3541 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3545 // Set the network state according to the information
3548 if( NetworkStatus->Online)
3551 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3556 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3559 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3570 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3574 NTSTATUS ntStatus = STATUS_SUCCESS;
3575 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3576 BOOLEAN bAcquiredLock = FALSE;
3577 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3582 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3583 AFS_TRACE_LEVEL_VERBOSE,
3584 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3585 ObjectInfo->FileId.Cell,
3586 ObjectInfo->FileId.Volume,
3587 ObjectInfo->FileId.Vnode,
3588 ObjectInfo->FileId.Unique));
3590 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3593 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3594 AFS_TRACE_LEVEL_VERBOSE,
3595 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3596 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3597 PsGetCurrentThread()));
3599 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3602 bAcquiredLock = TRUE;
3606 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3609 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3610 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3613 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3614 AFS_TRACE_LEVEL_ERROR,
3615 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3616 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3617 ObjectInfo->FileId.Cell,
3618 ObjectInfo->FileId.Volume,
3619 ObjectInfo->FileId.Vnode,
3620 ObjectInfo->FileId.Unique));
3624 // Reset the directory list information by clearing all valid entries
3627 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3629 while( pCurrentDirEntry != NULL)
3632 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3634 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3638 // If this entry has been deleted then process it here
3641 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3642 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3643 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3646 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3647 AFS_TRACE_LEVEL_VERBOSE,
3648 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3650 &pCurrentDirEntry->NameInformation.FileName));
3652 AFSDeleteDirEntry( ObjectInfo,
3658 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3660 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3661 AFS_TRACE_LEVEL_VERBOSE,
3662 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3664 pCurrentDirEntry->DirOpenReferenceCount));
3667 // We pull the short name from the parent tree since it could change below
3670 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3673 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3674 AFS_TRACE_LEVEL_VERBOSE,
3675 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3677 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3678 &pCurrentDirEntry->NameInformation.FileName));
3680 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3683 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3688 pCurrentDirEntry = pNextDirEntry;
3692 // Reget the directory contents
3695 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3698 if ( !NT_SUCCESS( ntStatus))
3700 try_return( ntStatus);
3704 // Now start again and tear down any entries not valid
3707 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;