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 ExFreePool( pDirNode);
728 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
729 AFS_OBJECT_REFERENCE_GLOBAL);
731 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
732 AFS_TRACE_LEVEL_VERBOSE,
733 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
740 AFSDeleteObjectInfo( &pObjectInfoCB);
743 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
744 AFS_TRACE_LEVEL_ERROR,
745 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n"));
747 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
750 RtlZeroMemory( pDirNode,
753 RtlZeroMemory( pNonPagedDirEntry,
754 sizeof( AFSNonPagedDirectoryCB));
756 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
758 pDirNode->NonPaged = pNonPagedDirEntry;
760 pDirNode->ObjectInformation = pObjectInfoCB;
766 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
768 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
771 // Setup the names in the entry
774 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
776 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
778 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
780 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
783 // Populate the rest of the data
786 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
788 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
790 AFSGlobalDotDirEntry = pDirNode;
796 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
799 if( pObjectInfoCB == NULL)
802 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
803 AFS_TRACE_LEVEL_ERROR,
804 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
807 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
810 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
811 AFS_OBJECT_REFERENCE_GLOBAL);
813 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
814 AFS_TRACE_LEVEL_VERBOSE,
815 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
819 ntStatus = STATUS_SUCCESS;
821 ulEntryLength = sizeof( AFSDirectoryCB) +
822 ( 2 * sizeof( WCHAR));
824 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
828 if( pDirNode == NULL)
831 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
832 AFS_TRACE_LEVEL_ERROR,
833 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocation failure\n"));
835 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
836 AFS_OBJECT_REFERENCE_GLOBAL);
838 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
839 AFS_TRACE_LEVEL_VERBOSE,
840 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
847 AFSDeleteObjectInfo( &pObjectInfoCB);
850 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
853 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
854 AFS_TRACE_LEVEL_VERBOSE,
855 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocated %p\n",
858 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
859 sizeof( AFSNonPagedDirectoryCB),
860 AFS_DIR_ENTRY_NP_TAG);
862 if( pNonPagedDirEntry == NULL)
865 ExFreePool( pDirNode);
867 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
868 AFS_OBJECT_REFERENCE_GLOBAL);
870 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
871 AFS_TRACE_LEVEL_VERBOSE,
872 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
879 AFSDeleteObjectInfo( &pObjectInfoCB);
882 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
885 RtlZeroMemory( pDirNode,
888 RtlZeroMemory( pNonPagedDirEntry,
889 sizeof( AFSNonPagedDirectoryCB));
891 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
893 pDirNode->NonPaged = pNonPagedDirEntry;
895 pDirNode->ObjectInformation = pObjectInfoCB;
901 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
903 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
906 // Setup the names in the entry
909 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
911 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
913 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
915 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
917 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
920 // Populate the rest of the data
923 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
925 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
927 AFSGlobalDotDotDirEntry = pDirNode;
931 if( !NT_SUCCESS( ntStatus))
934 if( AFSGlobalDotDirEntry != NULL)
937 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
938 AFS_OBJECT_REFERENCE_GLOBAL);
940 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
941 AFS_TRACE_LEVEL_VERBOSE,
942 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
943 AFSGlobalDotDirEntry->ObjectInformation,
949 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
952 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
954 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
956 ExFreePool( AFSGlobalDotDirEntry);
958 AFSGlobalDotDirEntry = NULL;
961 if( AFSGlobalDotDotDirEntry != NULL)
964 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
965 AFS_OBJECT_REFERENCE_GLOBAL);
967 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
968 AFS_TRACE_LEVEL_VERBOSE,
969 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
970 AFSGlobalDotDotDirEntry->ObjectInformation,
976 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
979 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
981 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
983 ExFreePool( AFSGlobalDotDotDirEntry);
985 AFSGlobalDotDotDirEntry = NULL;
994 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
995 IN PUNICODE_STRING FileName,
996 IN PUNICODE_STRING TargetName,
997 IN AFSDirEnumEntry *DirEnumEntry,
1001 AFSDirectoryCB *pDirNode = NULL;
1002 NTSTATUS ntStatus = STATUS_SUCCESS;
1003 ULONG ulEntryLength = 0;
1004 AFSObjectInfoCB *pObjectInfoCB = NULL;
1005 ULONGLONG ullIndex = 0;
1006 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
1012 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1013 AFS_TRACE_LEVEL_VERBOSE,
1014 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
1016 ParentObjectInfo->FileId.Cell,
1017 ParentObjectInfo->FileId.Volume,
1018 ParentObjectInfo->FileId.Vnode,
1019 ParentObjectInfo->FileId.Unique));
1022 // First thing is to locate/create our object information block
1026 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
1029 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
1031 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
1033 (AFSBTreeEntry **)&pObjectInfoCB);
1035 if( !NT_SUCCESS( ntStatus))
1039 // Allocate our object info cb
1042 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
1045 if( pObjectInfoCB == NULL)
1048 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1050 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1053 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1054 AFS_TRACE_LEVEL_VERBOSE,
1055 "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
1061 // If we allocated the object information cb then set the information
1064 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1066 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1068 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1070 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1072 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1073 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1076 pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1079 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
1082 if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1085 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1090 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1095 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1096 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1100 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1101 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1102 pObjectInfoCB->TargetFileId.Unique == 0 &&
1103 (TargetName == NULL || TargetName->Length == 0))
1107 // This will ensure we perform a validation on the node
1110 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1113 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1116 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1119 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1122 if ( BooleanFlagOn( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY))
1125 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1127 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1129 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1131 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1133 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1135 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1137 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1139 pObjectInfoCB->Links = DirEnumEntry->Links;
1141 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1143 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1145 ClearFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1149 // This reference count is either stored into the return DirectoryCB
1150 // or released before function exit.
1153 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
1154 AFS_OBJECT_REFERENCE_DIRENTRY);
1156 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1157 AFS_TRACE_LEVEL_VERBOSE,
1158 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
1162 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1164 ntStatus = STATUS_SUCCESS;
1166 ulEntryLength = sizeof( AFSDirectoryCB) +
1169 if( TargetName != NULL)
1172 ulEntryLength += TargetName->Length;
1175 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1179 if( pDirNode == NULL)
1182 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1185 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1186 AFS_TRACE_LEVEL_VERBOSE,
1187 "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
1190 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1191 sizeof( AFSNonPagedDirectoryCB),
1192 AFS_DIR_ENTRY_NP_TAG);
1194 if( pNonPagedDirEntry == NULL)
1197 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1200 RtlZeroMemory( pDirNode,
1203 RtlZeroMemory( pNonPagedDirEntry,
1204 sizeof( AFSNonPagedDirectoryCB));
1206 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1208 pDirNode->NonPaged = pNonPagedDirEntry;
1210 pDirNode->ObjectInformation = pObjectInfoCB;
1213 // Set valid entry and NOT_IN_PARENT flag
1216 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1218 pDirNode->FileIndex = FileIndex;
1221 // Setup the names in the entry
1224 if( FileName->Length > 0)
1227 pDirNode->NameInformation.FileName.Length = FileName->Length;
1229 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1231 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1233 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1235 pDirNode->NameInformation.FileName.Length);
1238 // Create a CRC for the file
1241 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1244 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1248 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1249 AFS_TRACE_LEVEL_VERBOSE,
1250 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1253 ParentObjectInfo->FileId.Cell,
1254 ParentObjectInfo->FileId.Volume,
1255 ParentObjectInfo->FileId.Vnode,
1256 ParentObjectInfo->FileId.Unique));
1258 if( TargetName != NULL &&
1259 TargetName->Length > 0)
1262 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1264 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1266 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1267 sizeof( AFSDirectoryCB) +
1268 pDirNode->NameInformation.FileName.Length);
1270 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1272 pDirNode->NameInformation.TargetName.Length);
1278 if( !NT_SUCCESS( ntStatus))
1281 if( pNonPagedDirEntry != NULL)
1284 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1286 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1289 if( pDirNode != NULL)
1292 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1293 AFS_TRACE_LEVEL_VERBOSE,
1294 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1297 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1303 // Dereference our object info block if we have one
1306 if( pObjectInfoCB != NULL)
1309 AFSAcquireShared( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
1312 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1313 AFS_OBJECT_REFERENCE_DIRENTRY);
1315 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1316 AFS_TRACE_LEVEL_VERBOSE,
1317 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1321 AFSReleaseResource( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
1330 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1331 IN BOOLEAN DirectoryEntry)
1334 BOOLEAN bReturn = TRUE;
1335 ACCESS_MASK stAccessMask = 0;
1338 // Get rid of anything we don't know about
1341 DesiredAccess = (DesiredAccess &
1347 ACCESS_SYSTEM_SECURITY |
1351 FILE_READ_ATTRIBUTES |
1352 FILE_WRITE_ATTRIBUTES |
1353 FILE_LIST_DIRECTORY |
1359 // Our 'read only' access mask. These are the accesses we will
1360 // allow for a read only file
1363 stAccessMask = DELETE |
1368 ACCESS_SYSTEM_SECURITY |
1372 FILE_READ_ATTRIBUTES |
1373 FILE_WRITE_ATTRIBUTES |
1375 FILE_LIST_DIRECTORY |
1379 // For a directory, add in the directory specific accesses
1385 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1390 if( FlagOn( DesiredAccess, ~stAccessMask))
1394 // A write access is set ...
1404 AFSEvaluateNode( IN GUID *AuthGroup,
1405 IN AFSDirectoryCB *DirEntry)
1408 NTSTATUS ntStatus = STATUS_SUCCESS;
1409 AFSDirEnumEntry *pDirEntry = NULL;
1410 UNICODE_STRING uniTargetName;
1415 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1420 if( !NT_SUCCESS( ntStatus))
1423 try_return( ntStatus);
1426 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1428 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1430 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1432 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1434 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1436 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1438 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1440 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1442 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1444 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1446 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1448 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1449 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1452 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1455 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1458 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1461 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1466 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1470 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1472 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1475 // If we have a target name then see if it needs updating ...
1478 if( pDirEntry->TargetNameLength > 0)
1482 // Update the target name information if needed
1485 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1487 uniTargetName.MaximumLength = uniTargetName.Length;
1489 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1491 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1494 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1495 RtlCompareUnicodeString( &uniTargetName,
1496 &DirEntry->NameInformation.TargetName,
1501 // Update the target name
1504 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1506 uniTargetName.Buffer,
1507 uniTargetName.Length);
1509 if( !NT_SUCCESS( ntStatus))
1512 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1514 try_return( ntStatus);
1518 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1523 if( pDirEntry != NULL)
1526 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1534 AFSValidateSymLink( IN GUID *AuthGroup,
1535 IN AFSDirectoryCB *DirEntry)
1538 NTSTATUS ntStatus = STATUS_SUCCESS;
1539 AFSDirEnumEntry *pDirEntry = NULL;
1540 UNICODE_STRING uniTargetName;
1545 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1550 if( !NT_SUCCESS( ntStatus))
1553 try_return( ntStatus);
1556 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1557 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1560 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1561 AFS_TRACE_LEVEL_VERBOSE_2,
1562 "AFSValidateSymLink Invalid type Status %08lX\n",
1563 STATUS_OBJECT_NAME_NOT_FOUND));
1565 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1568 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1570 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1572 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1575 // Update the target name information if needed
1578 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1580 uniTargetName.MaximumLength = uniTargetName.Length;
1582 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1584 if( uniTargetName.Length > 0)
1587 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1590 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1591 RtlCompareUnicodeString( &uniTargetName,
1592 &DirEntry->NameInformation.TargetName,
1597 // Update the target name
1600 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1602 uniTargetName.Buffer,
1603 uniTargetName.Length);
1605 if( !NT_SUCCESS( ntStatus))
1608 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1610 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1614 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1618 // If the FileType is the same then nothing to do since it IS
1622 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1625 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1627 try_return( ntStatus = STATUS_SUCCESS);
1630 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1632 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1634 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1636 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1638 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1640 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1642 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1644 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1646 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1647 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1650 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1653 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1656 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1659 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1664 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1668 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1670 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1674 if( pDirEntry != NULL)
1677 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1685 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1689 NTSTATUS ntStatus = STATUS_SUCCESS;
1690 IO_STATUS_BLOCK stIoStatus;
1692 AFSObjectInfoCB * pParentObjectInfo = NULL;
1694 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1695 AFS_TRACE_LEVEL_VERBOSE,
1696 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1697 (*ppObjectInfo)->FileType,
1698 (*ppObjectInfo)->FileId.Cell,
1699 (*ppObjectInfo)->FileId.Volume,
1700 (*ppObjectInfo)->FileId.Vnode,
1701 (*ppObjectInfo)->FileId.Unique,
1704 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1707 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1708 &(*ppObjectInfo)->ParentFileId);
1711 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1712 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1713 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1716 // We only act on the mount point itself, not the target. If the
1717 // node has been deleted then mark it as such otherwise indicate
1718 // it requires verification
1721 if( Reason == AFS_INVALIDATE_DELETED)
1723 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1728 if( Reason == AFS_INVALIDATE_FLUSHED)
1731 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1733 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1736 (*ppObjectInfo)->Expiration.QuadPart = 0;
1738 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1740 (*ppObjectInfo)->TargetFileId.Unique = 0;
1742 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1743 AFS_TRACE_LEVEL_VERBOSE,
1744 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1745 (*ppObjectInfo)->FileId.Cell,
1746 (*ppObjectInfo)->FileId.Volume,
1747 (*ppObjectInfo)->FileId.Vnode,
1748 (*ppObjectInfo)->FileId.Unique));
1750 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1753 if ( pParentObjectInfo != NULL)
1756 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1758 if( Reason == AFS_INVALIDATE_CREDS)
1760 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1763 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1764 Reason == AFS_INVALIDATE_FLUSHED)
1766 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1770 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1773 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1776 FILE_ACTION_MODIFIED);
1779 try_return( ntStatus);
1783 // Depending on the reason for invalidation then perform work on the node
1789 case AFS_INVALIDATE_DELETED:
1793 // Mark this node as invalid
1796 (*ppObjectInfo)->Links = 0;
1798 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1800 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1801 AFS_TRACE_LEVEL_VERBOSE,
1802 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1803 (*ppObjectInfo)->FileId.Cell,
1804 (*ppObjectInfo)->FileId.Volume,
1805 (*ppObjectInfo)->FileId.Vnode,
1806 (*ppObjectInfo)->FileId.Unique));
1808 if( pParentObjectInfo != NULL)
1811 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1812 AFS_TRACE_LEVEL_VERBOSE,
1813 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1814 pParentObjectInfo->FileId.Cell,
1815 pParentObjectInfo->FileId.Volume,
1816 pParentObjectInfo->FileId.Vnode,
1817 pParentObjectInfo->FileId.Unique));
1819 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1821 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1823 pParentObjectInfo->Expiration.QuadPart = 0;
1825 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1827 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1831 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1834 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1837 FILE_ACTION_REMOVED);
1840 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1843 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1849 case AFS_INVALIDATE_FLUSHED:
1852 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1853 (*ppObjectInfo)->Fcb != NULL)
1856 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1857 AFS_TRACE_LEVEL_VERBOSE,
1858 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1859 (*ppObjectInfo)->FileId.Cell,
1860 (*ppObjectInfo)->FileId.Volume,
1861 (*ppObjectInfo)->FileId.Vnode,
1862 (*ppObjectInfo)->FileId.Unique));
1864 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1870 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1875 if( !NT_SUCCESS( stIoStatus.Status))
1878 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1879 AFS_TRACE_LEVEL_ERROR,
1880 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1881 (*ppObjectInfo)->FileId.Cell,
1882 (*ppObjectInfo)->FileId.Volume,
1883 (*ppObjectInfo)->FileId.Vnode,
1884 (*ppObjectInfo)->FileId.Unique,
1886 stIoStatus.Information));
1888 ntStatus = stIoStatus.Status;
1892 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1895 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1901 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1902 AFS_TRACE_LEVEL_WARNING,
1903 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1904 (*ppObjectInfo)->FileId.Cell,
1905 (*ppObjectInfo)->FileId.Volume,
1906 (*ppObjectInfo)->FileId.Vnode,
1907 (*ppObjectInfo)->FileId.Unique));
1909 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1913 __except( EXCEPTION_EXECUTE_HANDLER)
1916 ntStatus = GetExceptionCode();
1920 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1921 (*ppObjectInfo)->FileId.Cell,
1922 (*ppObjectInfo)->FileId.Volume,
1923 (*ppObjectInfo)->FileId.Vnode,
1924 (*ppObjectInfo)->FileId.Unique,
1927 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1930 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1933 // Clear out the extents
1934 // Get rid of them (note this involves waiting
1935 // for any writes or reads to the cache to complete)
1938 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1942 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1945 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1948 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1949 AFS_TRACE_LEVEL_VERBOSE,
1950 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1951 (*ppObjectInfo)->FileId.Cell,
1952 (*ppObjectInfo)->FileId.Volume,
1953 (*ppObjectInfo)->FileId.Vnode,
1954 (*ppObjectInfo)->FileId.Unique));
1956 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1959 // Fall through to the default processing
1965 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1967 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1971 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1974 if( Reason == AFS_INVALIDATE_CREDS)
1976 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1979 if( Reason == AFS_INVALIDATE_DATA_VERSION)
1981 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1985 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1988 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1991 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
1994 FILE_ACTION_MODIFIED);
1996 else if ( pParentObjectInfo != NULL)
1999 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2002 FILE_ACTION_MODIFIED);
2006 // Indicate this node requires re-evaluation for the remaining reasons
2009 (*ppObjectInfo)->Expiration.QuadPart = 0;
2011 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2012 AFS_TRACE_LEVEL_VERBOSE,
2013 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2014 (*ppObjectInfo)->FileId.Cell,
2015 (*ppObjectInfo)->FileId.Volume,
2016 (*ppObjectInfo)->FileId.Vnode,
2017 (*ppObjectInfo)->FileId.Unique));
2019 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
2021 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2022 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
2023 ( Reason == AFS_INVALIDATE_CALLBACK ||
2024 Reason == AFS_INVALIDATE_EXPIRED))
2026 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
2027 AFS_INVALIDATE_DATA_VERSION)))
2030 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
2040 if ( pParentObjectInfo != NULL)
2043 AFSReleaseObjectInfo( &pParentObjectInfo);
2050 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
2053 NTSTATUS ntStatus = STATUS_SUCCESS;
2054 AFSVolumeCB *pVolumeCB = NULL;
2055 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2056 ULONGLONG ullIndex = 0;
2057 AFSObjectInfoCB *pObjectInfo = NULL;
2063 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2064 AFS_TRACE_LEVEL_VERBOSE,
2065 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
2066 InvalidateCB->FileID.Cell,
2067 InvalidateCB->FileID.Volume,
2068 InvalidateCB->FileID.Vnode,
2069 InvalidateCB->FileID.Unique,
2070 InvalidateCB->FileType,
2071 InvalidateCB->WholeVolume,
2072 InvalidateCB->Reason));
2075 // Need to locate the Fcb for the directory to purge
2078 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2079 AFS_TRACE_LEVEL_VERBOSE,
2080 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2081 &pDevExt->Specific.RDR.VolumeTreeLock,
2082 PsGetCurrentThread()));
2085 // Starve any exclusive waiters on this paticular call
2088 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2091 // Locate the volume node
2094 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2096 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2098 (AFSBTreeEntry **)&pVolumeCB);
2100 if( pVolumeCB != NULL)
2103 lCount = AFSVolumeIncrement( pVolumeCB,
2104 AFS_VOLUME_REFERENCE_INVALIDATE);
2106 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2107 AFS_TRACE_LEVEL_VERBOSE,
2108 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2113 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2115 if( !NT_SUCCESS( ntStatus) ||
2119 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2120 AFS_TRACE_LEVEL_WARNING,
2121 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2122 InvalidateCB->FileID.Cell,
2123 InvalidateCB->FileID.Volume,
2124 InvalidateCB->FileID.Vnode,
2125 InvalidateCB->FileID.Unique,
2128 try_return( ntStatus = STATUS_SUCCESS);
2132 // If this is a whole volume invalidation then go do it now
2135 if( InvalidateCB->WholeVolume)
2138 ntStatus = AFSInvalidateVolume( pVolumeCB,
2139 InvalidateCB->Reason);
2141 try_return( ntStatus);
2144 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
2147 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2150 pObjectInfo = &pVolumeCB->ObjectInformation;
2155 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2157 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2159 (AFSBTreeEntry **)&pObjectInfo);
2162 if( pObjectInfo != NULL)
2166 // Reference the node so it won't be torn down
2169 lCount = AFSObjectInfoIncrement( pObjectInfo,
2170 AFS_OBJECT_REFERENCE_INVALIDATION);
2172 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2173 AFS_TRACE_LEVEL_VERBOSE,
2174 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2179 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2181 if( !NT_SUCCESS( ntStatus) ||
2182 pObjectInfo == NULL)
2185 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2186 AFS_TRACE_LEVEL_VERBOSE,
2187 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2188 InvalidateCB->FileID.Cell,
2189 InvalidateCB->FileID.Volume,
2190 InvalidateCB->FileID.Vnode,
2191 InvalidateCB->FileID.Unique,
2194 try_return( ntStatus = STATUS_SUCCESS);
2197 AFSInvalidateObject( &pObjectInfo,
2198 InvalidateCB->Reason);
2202 if( pObjectInfo != NULL)
2205 lCount = AFSObjectInfoDecrement( pObjectInfo,
2206 AFS_OBJECT_REFERENCE_INVALIDATION);
2208 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2209 AFS_TRACE_LEVEL_VERBOSE,
2210 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2215 if ( pVolumeCB != NULL)
2218 lCount = AFSVolumeDecrement( pVolumeCB,
2219 AFS_VOLUME_REFERENCE_INVALIDATE);
2221 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2222 AFS_TRACE_LEVEL_VERBOSE,
2223 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2233 AFSIsChildOfParent( IN AFSFcb *Dcb,
2237 BOOLEAN bIsChild = FALSE;
2238 AFSFcb *pCurrentFcb = Fcb;
2239 AFSObjectInfoCB * pParentObjectInfo = NULL;
2241 while( pCurrentFcb != NULL)
2244 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2245 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2253 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2254 &pCurrentFcb->ObjectInformation->ParentFileId);
2256 if ( pParentObjectInfo != NULL)
2259 pCurrentFcb = pParentObjectInfo->Fcb;
2261 AFSReleaseObjectInfo( &pParentObjectInfo);
2275 AFSCreateHighIndex( IN AFSFileID *FileID)
2278 ULONGLONG ullIndex = 0;
2280 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2287 AFSCreateLowIndex( IN AFSFileID *FileID)
2290 ULONGLONG ullIndex = 0;
2292 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2298 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2299 IN ACCESS_MASK GrantedAccess,
2300 IN BOOLEAN DirectoryEntry)
2303 BOOLEAN bAccessGranted = TRUE;
2306 // Check if we are asking for read/write and granted only read only
2307 // NOTE: There will be more checks here
2310 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2312 AFSCheckForReadOnlyAccess( GrantedAccess,
2316 bAccessGranted = FALSE;
2319 return bAccessGranted;
2323 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2326 NTSTATUS ntStatus = STATUS_SUCCESS;
2327 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2333 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2335 if( AFSGlobalRoot == NULL)
2342 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2345 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2352 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2359 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2360 IN UNICODE_STRING *SubstituteName,
2361 IN ULONG StringIndex)
2364 NTSTATUS ntStatus = STATUS_SUCCESS;
2365 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2366 AFSSysNameCB *pSysName = NULL;
2367 ERESOURCE *pSysNameLock = NULL;
2370 UNICODE_STRING uniSysName;
2377 if( IoIs32bitProcess( NULL))
2380 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2382 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2387 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2389 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2393 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2395 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2399 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2400 AFS_TRACE_LEVEL_VERBOSE,
2401 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2403 PsGetCurrentThread()));
2405 AFSAcquireShared( pSysNameLock,
2409 // Find where we are in the list
2412 while( pSysName != NULL &&
2413 ulIndex < StringIndex)
2416 pSysName = pSysName->fLink;
2421 if( pSysName == NULL)
2424 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2425 AFS_TRACE_LEVEL_VERBOSE_2,
2426 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2428 STATUS_OBJECT_NAME_NOT_FOUND));
2430 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2433 RtlInitUnicodeString( &uniSysName,
2436 // If it is a full component of @SYS then just substitue the
2440 if( RtlCompareUnicodeString( &uniSysName,
2445 SubstituteName->Length = pSysName->SysName.Length;
2446 SubstituteName->MaximumLength = SubstituteName->Length;
2448 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2449 SubstituteName->Length,
2450 AFS_SUBST_BUFFER_TAG);
2452 if( SubstituteName->Buffer == NULL)
2455 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2458 RtlCopyMemory( SubstituteName->Buffer,
2459 pSysName->SysName.Buffer,
2460 pSysName->SysName.Length);
2467 while( ComponentName->Buffer[ usIndex] != L'@')
2473 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2474 SubstituteName->MaximumLength = SubstituteName->Length;
2476 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2477 SubstituteName->Length,
2478 AFS_SUBST_BUFFER_TAG);
2480 if( SubstituteName->Buffer == NULL)
2483 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2486 RtlCopyMemory( SubstituteName->Buffer,
2487 ComponentName->Buffer,
2488 usIndex * sizeof( WCHAR));
2490 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2491 pSysName->SysName.Buffer,
2492 pSysName->SysName.Length);
2497 AFSReleaseResource( pSysNameLock);
2504 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2505 IN OUT UNICODE_STRING *ComponentName,
2506 IN UNICODE_STRING *SubstituteName,
2507 IN OUT UNICODE_STRING *RemainingPath,
2508 IN BOOLEAN FreePathName)
2511 NTSTATUS ntStatus = STATUS_SUCCESS;
2512 UNICODE_STRING uniPathName;
2513 USHORT usPrefixNameLen = 0;
2514 SHORT sNameLenDelta = 0;
2520 // If the passed in name can handle the additional length
2521 // then just moves things around
2524 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2526 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2528 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2531 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2534 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2535 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2536 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2539 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2540 SubstituteName->Buffer,
2541 SubstituteName->Length);
2543 FullPathName->Length += sNameLenDelta;
2545 ComponentName->Length += sNameLenDelta;
2547 ComponentName->MaximumLength = ComponentName->Length;
2549 if ( RemainingPath->Buffer)
2552 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2555 try_return( ntStatus);
2559 // Need to re-allocate the buffer
2562 uniPathName.Length = FullPathName->Length -
2563 ComponentName->Length +
2564 SubstituteName->Length;
2566 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2568 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2569 uniPathName.MaximumLength,
2570 AFS_NAME_BUFFER_FOUR_TAG);
2572 if( uniPathName.Buffer == NULL)
2575 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2578 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2580 usPrefixNameLen *= sizeof( WCHAR);
2582 RtlZeroMemory( uniPathName.Buffer,
2583 uniPathName.MaximumLength);
2585 RtlCopyMemory( uniPathName.Buffer,
2586 FullPathName->Buffer,
2589 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2590 SubstituteName->Buffer,
2591 SubstituteName->Length);
2593 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2596 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2597 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2598 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2601 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2603 ComponentName->Length += sNameLenDelta;
2605 ComponentName->MaximumLength = ComponentName->Length;
2607 if ( RemainingPath->Buffer)
2610 RemainingPath->Buffer = uniPathName.Buffer
2611 + (RemainingPath->Buffer - FullPathName->Buffer)
2612 + sNameLenDelta/sizeof( WCHAR);
2617 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2620 *FullPathName = uniPathName;
2631 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2635 NTSTATUS ntStatus = STATUS_SUCCESS;
2636 AFSObjectInfoCB *pCurrentObject = NULL;
2637 AFSObjectInfoCB *pNextObject = NULL;
2643 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2644 AFS_TRACE_LEVEL_VERBOSE,
2645 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2646 VolumeCB->ObjectInformation.FileId.Cell,
2647 VolumeCB->ObjectInformation.FileId.Volume,
2648 VolumeCB->ObjectInformation.FileId.Vnode,
2649 VolumeCB->ObjectInformation.FileId.Unique,
2653 // Depending on the reason for invalidation then perform work on the node
2659 case AFS_INVALIDATE_DELETED:
2663 // Mark this volume as invalid
2666 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2668 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2675 // Invalidate the volume root directory
2678 pCurrentObject = &VolumeCB->ObjectInformation;
2680 if ( pCurrentObject )
2683 lCount = AFSObjectInfoIncrement( pCurrentObject,
2684 AFS_OBJECT_REFERENCE_INVALIDATION);
2686 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2687 AFS_TRACE_LEVEL_VERBOSE,
2688 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2692 AFSInvalidateObject( &pCurrentObject,
2695 if ( pCurrentObject)
2698 lCount = AFSObjectInfoDecrement( pCurrentObject,
2699 AFS_OBJECT_REFERENCE_INVALIDATION);
2701 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2702 AFS_TRACE_LEVEL_VERBOSE,
2703 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2710 // Apply invalidation to all other volume objects
2713 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2716 pCurrentObject = VolumeCB->ObjectInfoListHead;
2718 if ( pCurrentObject)
2722 // Reference the node so it won't be torn down
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",
2735 while( pCurrentObject != NULL)
2738 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2744 // Reference the node so it won't be torn down
2747 lCount = AFSObjectInfoIncrement( pNextObject,
2748 AFS_OBJECT_REFERENCE_INVALIDATION);
2750 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2751 AFS_TRACE_LEVEL_VERBOSE,
2752 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2757 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2759 AFSInvalidateObject( &pCurrentObject,
2762 if ( pCurrentObject )
2765 lCount = AFSObjectInfoDecrement( pCurrentObject,
2766 AFS_OBJECT_REFERENCE_INVALIDATION);
2768 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2769 AFS_TRACE_LEVEL_VERBOSE,
2770 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2775 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2778 pCurrentObject = pNextObject;
2781 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2788 AFSInvalidateAllVolumes( VOID)
2790 AFSVolumeCB *pVolumeCB = NULL;
2791 AFSVolumeCB *pNextVolumeCB = NULL;
2792 AFSDeviceExt *pRDRDeviceExt = NULL;
2795 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2797 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2798 AFS_TRACE_LEVEL_VERBOSE,
2799 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2800 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2801 PsGetCurrentThread()));
2803 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2806 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2811 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2812 AFS_TRACE_LEVEL_VERBOSE,
2813 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2814 pVolumeCB->ObjectInfoTree.TreeLock,
2815 PsGetCurrentThread()));
2817 lCount = AFSVolumeIncrement( pVolumeCB,
2818 AFS_VOLUME_REFERENCE_INVALIDATE);
2820 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2821 AFS_TRACE_LEVEL_VERBOSE,
2822 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2827 while( pVolumeCB != NULL)
2830 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2835 lCount = AFSVolumeIncrement( pNextVolumeCB,
2836 AFS_VOLUME_REFERENCE_INVALIDATE);
2838 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2839 AFS_TRACE_LEVEL_VERBOSE,
2840 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2845 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2847 // do I need to hold the volume lock here?
2849 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2851 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2854 lCount = AFSVolumeDecrement( pVolumeCB,
2855 AFS_VOLUME_REFERENCE_INVALIDATE);
2857 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2858 AFS_TRACE_LEVEL_VERBOSE,
2859 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2863 pVolumeCB = pNextVolumeCB;
2866 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2870 AFSVerifyEntry( IN GUID *AuthGroup,
2871 IN AFSDirectoryCB *DirEntry)
2874 NTSTATUS ntStatus = STATUS_SUCCESS;
2875 AFSDirEnumEntry *pDirEnumEntry = NULL;
2876 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2877 IO_STATUS_BLOCK stIoStatus;
2882 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2883 AFS_TRACE_LEVEL_VERBOSE_2,
2884 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2885 &DirEntry->NameInformation.FileName,
2886 pObjectInfo->FileId.Cell,
2887 pObjectInfo->FileId.Volume,
2888 pObjectInfo->FileId.Vnode,
2889 pObjectInfo->FileId.Unique));
2891 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2896 if( !NT_SUCCESS( ntStatus))
2899 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2900 AFS_TRACE_LEVEL_ERROR,
2901 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2902 &DirEntry->NameInformation.FileName,
2903 pObjectInfo->FileId.Cell,
2904 pObjectInfo->FileId.Volume,
2905 pObjectInfo->FileId.Vnode,
2906 pObjectInfo->FileId.Unique,
2909 try_return( ntStatus);
2913 // Check the data version of the file
2916 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart)
2918 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2921 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2922 AFS_TRACE_LEVEL_VERBOSE,
2923 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2924 pObjectInfo->DataVersion.QuadPart,
2925 &DirEntry->NameInformation.FileName,
2926 pObjectInfo->FileId.Cell,
2927 pObjectInfo->FileId.Volume,
2928 pObjectInfo->FileId.Vnode,
2929 pObjectInfo->FileId.Unique));
2932 // We are ok, just get out
2935 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2937 try_return( ntStatus = STATUS_SUCCESS);
2942 // New data version so we will need to process the node based on the type
2945 switch( pDirEnumEntry->FileType)
2948 case AFS_FILE_TYPE_MOUNTPOINT:
2952 // For a mount point we need to ensure the target is the same
2955 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2956 &pDirEnumEntry->TargetFileId))
2962 // Update the metadata for the entry
2965 ntStatus = AFSUpdateMetaData( DirEntry,
2968 if( NT_SUCCESS( ntStatus))
2971 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2977 case AFS_FILE_TYPE_SYMLINK:
2981 // Update the metadata for the entry
2984 ntStatus = AFSUpdateMetaData( DirEntry,
2987 if( NT_SUCCESS( ntStatus))
2990 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2996 case AFS_FILE_TYPE_FILE:
2998 FILE_OBJECT * pCCFileObject = NULL;
2999 BOOLEAN bPurgeExtents = FALSE;
3001 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3004 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3005 AFS_TRACE_LEVEL_VERBOSE,
3006 "AFSVerifyEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
3007 &DirEntry->NameInformation.FileName,
3008 pObjectInfo->FileId.Cell,
3009 pObjectInfo->FileId.Volume,
3010 pObjectInfo->FileId.Vnode,
3011 pObjectInfo->FileId.Unique,
3012 pObjectInfo->DataVersion.LowPart,
3013 pDirEnumEntry->DataVersion.LowPart));
3015 bPurgeExtents = TRUE;
3018 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3021 bPurgeExtents = TRUE;
3023 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3024 AFS_TRACE_LEVEL_VERBOSE,
3025 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3026 &DirEntry->NameInformation.FileName,
3027 pObjectInfo->FileId.Cell,
3028 pObjectInfo->FileId.Volume,
3029 pObjectInfo->FileId.Vnode,
3030 pObjectInfo->FileId.Unique));
3032 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3035 if( pObjectInfo->Fcb != NULL)
3038 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3039 AFS_TRACE_LEVEL_VERBOSE,
3040 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3041 &DirEntry->NameInformation.FileName,
3042 pObjectInfo->FileId.Cell,
3043 pObjectInfo->FileId.Volume,
3044 pObjectInfo->FileId.Vnode,
3045 pObjectInfo->FileId.Unique));
3047 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3053 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3058 if( !NT_SUCCESS( stIoStatus.Status))
3061 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3062 AFS_TRACE_LEVEL_ERROR,
3063 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3064 &DirEntry->NameInformation.FileName,
3065 pObjectInfo->FileId.Cell,
3066 pObjectInfo->FileId.Volume,
3067 pObjectInfo->FileId.Vnode,
3068 pObjectInfo->FileId.Unique,
3070 stIoStatus.Information));
3072 ntStatus = stIoStatus.Status;
3075 if ( bPurgeExtents &&
3076 pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3079 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3085 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3086 AFS_TRACE_LEVEL_WARNING,
3087 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3088 &DirEntry->NameInformation.FileName,
3089 pObjectInfo->FileId.Cell,
3090 pObjectInfo->FileId.Volume,
3091 pObjectInfo->FileId.Vnode,
3092 pObjectInfo->FileId.Unique));
3094 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3098 __except( EXCEPTION_EXECUTE_HANDLER)
3100 ntStatus = GetExceptionCode();
3104 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3105 &DirEntry->NameInformation.FileName,
3106 pObjectInfo->FileId.Cell,
3107 pObjectInfo->FileId.Volume,
3108 pObjectInfo->FileId.Vnode,
3109 pObjectInfo->FileId.Unique,
3112 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3115 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3119 AFSFlushExtents( pObjectInfo->Fcb,
3124 // Reacquire the Fcb to purge the cache
3127 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3128 AFS_TRACE_LEVEL_VERBOSE,
3129 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3130 &pObjectInfo->Fcb->NPFcb->Resource,
3131 PsGetCurrentThread()));
3133 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3137 // Update the metadata for the entry
3140 ntStatus = AFSUpdateMetaData( DirEntry,
3143 if( !NT_SUCCESS( ntStatus))
3146 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3147 AFS_TRACE_LEVEL_ERROR,
3148 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3149 &DirEntry->NameInformation.FileName,
3150 pObjectInfo->FileId.Cell,
3151 pObjectInfo->FileId.Volume,
3152 pObjectInfo->FileId.Vnode,
3153 pObjectInfo->FileId.Unique,
3160 // Update file sizes
3163 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3164 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3165 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3167 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3168 AFS_TRACE_LEVEL_VERBOSE,
3169 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3170 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3171 PsGetCurrentThread()));
3173 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3176 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3178 if ( pCCFileObject != NULL)
3180 CcSetFileSizes( pCCFileObject,
3181 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3184 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3185 AFS_TRACE_LEVEL_VERBOSE,
3186 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3187 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3188 PsGetCurrentThread()));
3190 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3192 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3198 // Update the metadata for the entry
3201 ntStatus = AFSUpdateMetaData( DirEntry,
3204 if( !NT_SUCCESS( ntStatus))
3207 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3208 AFS_TRACE_LEVEL_ERROR,
3209 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3210 &DirEntry->NameInformation.FileName,
3211 pObjectInfo->FileId.Cell,
3212 pObjectInfo->FileId.Volume,
3213 pObjectInfo->FileId.Vnode,
3214 pObjectInfo->FileId.Unique,
3220 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3221 AFS_TRACE_LEVEL_WARNING,
3222 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3223 &DirEntry->NameInformation.FileName,
3224 pObjectInfo->FileId.Cell,
3225 pObjectInfo->FileId.Volume,
3226 pObjectInfo->FileId.Vnode,
3227 pObjectInfo->FileId.Unique));
3230 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);