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 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1152 AFS_TRACE_LEVEL_VERBOSE,
1153 "AFSInitDirEntry FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
1154 pObjectInfoCB->FileId.Cell,
1155 pObjectInfoCB->FileId.Volume,
1156 pObjectInfoCB->FileId.Vnode,
1157 pObjectInfoCB->FileId.Unique));
1159 ClearFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1163 // This reference count is either stored into the return DirectoryCB
1164 // or released before function exit.
1167 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
1168 AFS_OBJECT_REFERENCE_DIRENTRY);
1170 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1171 AFS_TRACE_LEVEL_VERBOSE,
1172 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
1176 KeQueryTickCount( &pObjectInfoCB->LastAccessCount);
1178 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1180 ntStatus = STATUS_SUCCESS;
1182 ulEntryLength = sizeof( AFSDirectoryCB) +
1185 if( TargetName != NULL)
1188 ulEntryLength += TargetName->Length;
1191 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1195 if( pDirNode == NULL)
1198 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1201 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1202 AFS_TRACE_LEVEL_VERBOSE,
1203 "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
1206 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1207 sizeof( AFSNonPagedDirectoryCB),
1208 AFS_DIR_ENTRY_NP_TAG);
1210 if( pNonPagedDirEntry == NULL)
1213 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1216 RtlZeroMemory( pDirNode,
1219 RtlZeroMemory( pNonPagedDirEntry,
1220 sizeof( AFSNonPagedDirectoryCB));
1222 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1224 pDirNode->NonPaged = pNonPagedDirEntry;
1226 pDirNode->ObjectInformation = pObjectInfoCB;
1229 // Set valid entry and NOT_IN_PARENT flag
1232 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1234 pDirNode->FileIndex = FileIndex;
1237 // Setup the names in the entry
1240 if( FileName->Length > 0)
1243 pDirNode->NameInformation.FileName.Length = FileName->Length;
1245 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1247 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1249 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1251 pDirNode->NameInformation.FileName.Length);
1254 // Create a CRC for the file
1257 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1260 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1264 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1265 AFS_TRACE_LEVEL_VERBOSE,
1266 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1269 ParentObjectInfo->FileId.Cell,
1270 ParentObjectInfo->FileId.Volume,
1271 ParentObjectInfo->FileId.Vnode,
1272 ParentObjectInfo->FileId.Unique));
1274 if( TargetName != NULL &&
1275 TargetName->Length > 0)
1278 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1280 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1282 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1283 sizeof( AFSDirectoryCB) +
1284 pDirNode->NameInformation.FileName.Length);
1286 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1288 pDirNode->NameInformation.TargetName.Length);
1294 if( !NT_SUCCESS( ntStatus))
1297 if( pNonPagedDirEntry != NULL)
1300 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1302 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1305 if( pDirNode != NULL)
1308 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1309 AFS_TRACE_LEVEL_VERBOSE,
1310 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1313 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1319 // Dereference our object info block if we have one
1322 if( pObjectInfoCB != NULL)
1325 AFSAcquireShared( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
1328 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1329 AFS_OBJECT_REFERENCE_DIRENTRY);
1331 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1332 AFS_TRACE_LEVEL_VERBOSE,
1333 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1337 AFSReleaseResource( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
1346 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1347 IN BOOLEAN DirectoryEntry)
1350 BOOLEAN bReturn = TRUE;
1351 ACCESS_MASK stAccessMask = 0;
1354 // Get rid of anything we don't know about
1357 DesiredAccess = (DesiredAccess &
1363 ACCESS_SYSTEM_SECURITY |
1367 FILE_READ_ATTRIBUTES |
1368 FILE_WRITE_ATTRIBUTES |
1369 FILE_LIST_DIRECTORY |
1375 // Our 'read only' access mask. These are the accesses we will
1376 // allow for a read only file
1379 stAccessMask = DELETE |
1384 ACCESS_SYSTEM_SECURITY |
1388 FILE_READ_ATTRIBUTES |
1389 FILE_WRITE_ATTRIBUTES |
1391 FILE_LIST_DIRECTORY |
1395 // For a directory, add in the directory specific accesses
1401 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1406 if( FlagOn( DesiredAccess, ~stAccessMask))
1410 // A write access is set ...
1420 AFSEvaluateNode( IN GUID *AuthGroup,
1421 IN AFSDirectoryCB *DirEntry)
1424 NTSTATUS ntStatus = STATUS_SUCCESS;
1425 AFSDirEnumEntry *pDirEntry = NULL;
1426 UNICODE_STRING uniTargetName;
1431 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1436 if( !NT_SUCCESS( ntStatus))
1439 try_return( ntStatus);
1442 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1444 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1446 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1448 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1450 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1452 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1454 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1456 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1458 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1460 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1462 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1464 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1465 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1468 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1471 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1474 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1477 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1482 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1486 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1488 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1491 // If we have a target name then see if it needs updating ...
1494 if( pDirEntry->TargetNameLength > 0)
1498 // Update the target name information if needed
1501 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1503 uniTargetName.MaximumLength = uniTargetName.Length;
1505 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1507 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1510 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1511 RtlCompareUnicodeString( &uniTargetName,
1512 &DirEntry->NameInformation.TargetName,
1517 // Update the target name
1520 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1522 uniTargetName.Buffer,
1523 uniTargetName.Length);
1525 if( !NT_SUCCESS( ntStatus))
1528 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1530 try_return( ntStatus);
1534 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1539 if( pDirEntry != NULL)
1542 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1550 AFSValidateSymLink( IN GUID *AuthGroup,
1551 IN AFSDirectoryCB *DirEntry)
1554 NTSTATUS ntStatus = STATUS_SUCCESS;
1555 AFSDirEnumEntry *pDirEntry = NULL;
1556 UNICODE_STRING uniTargetName;
1561 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1566 if( !NT_SUCCESS( ntStatus))
1569 try_return( ntStatus);
1572 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1573 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1576 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1577 AFS_TRACE_LEVEL_VERBOSE_2,
1578 "AFSValidateSymLink Invalid type Status %08lX\n",
1579 STATUS_OBJECT_NAME_NOT_FOUND));
1581 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1584 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1586 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1588 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1591 // Update the target name information if needed
1594 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1596 uniTargetName.MaximumLength = uniTargetName.Length;
1598 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1600 if( uniTargetName.Length > 0)
1603 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1606 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1607 RtlCompareUnicodeString( &uniTargetName,
1608 &DirEntry->NameInformation.TargetName,
1613 // Update the target name
1616 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1618 uniTargetName.Buffer,
1619 uniTargetName.Length);
1621 if( !NT_SUCCESS( ntStatus))
1624 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1626 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1630 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1634 // If the FileType is the same then nothing to do since it IS
1638 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1641 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1643 try_return( ntStatus = STATUS_SUCCESS);
1646 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1648 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1650 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1652 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1654 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1656 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1658 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1660 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1662 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1663 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1666 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1669 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1672 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1675 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1680 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1684 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1686 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1690 if( pDirEntry != NULL)
1693 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1701 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1705 NTSTATUS ntStatus = STATUS_SUCCESS;
1706 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1707 IO_STATUS_BLOCK stIoStatus;
1709 AFSObjectInfoCB * pParentObjectInfo = NULL;
1711 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1712 AFS_TRACE_LEVEL_VERBOSE,
1713 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1714 (*ppObjectInfo)->FileType,
1715 (*ppObjectInfo)->FileId.Cell,
1716 (*ppObjectInfo)->FileId.Volume,
1717 (*ppObjectInfo)->FileId.Vnode,
1718 (*ppObjectInfo)->FileId.Unique,
1721 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1724 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1725 &(*ppObjectInfo)->ParentFileId,
1729 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1730 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1731 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1734 // We only act on the mount point itself, not the target. If the
1735 // node has been deleted then mark it as such otherwise indicate
1736 // it requires verification
1739 if( Reason == AFS_INVALIDATE_DELETED)
1741 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1746 if( Reason == AFS_INVALIDATE_FLUSHED)
1749 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1751 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1754 (*ppObjectInfo)->Expiration.QuadPart = 0;
1756 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1758 (*ppObjectInfo)->TargetFileId.Unique = 0;
1760 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1761 AFS_TRACE_LEVEL_VERBOSE,
1762 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1763 (*ppObjectInfo)->FileId.Cell,
1764 (*ppObjectInfo)->FileId.Volume,
1765 (*ppObjectInfo)->FileId.Vnode,
1766 (*ppObjectInfo)->FileId.Unique));
1768 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1771 if ( pParentObjectInfo != NULL)
1774 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1776 if( Reason == AFS_INVALIDATE_CREDS)
1778 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1781 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1782 Reason == AFS_INVALIDATE_FLUSHED)
1784 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1788 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1791 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1794 FILE_ACTION_MODIFIED);
1797 try_return( ntStatus);
1801 // Depending on the reason for invalidation then perform work on the node
1807 case AFS_INVALIDATE_DELETED:
1811 // Mark this node as invalid
1814 (*ppObjectInfo)->Links = 0;
1816 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1818 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1819 AFS_TRACE_LEVEL_VERBOSE,
1820 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1821 (*ppObjectInfo)->FileId.Cell,
1822 (*ppObjectInfo)->FileId.Volume,
1823 (*ppObjectInfo)->FileId.Vnode,
1824 (*ppObjectInfo)->FileId.Unique));
1826 if( pParentObjectInfo != NULL)
1829 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1830 AFS_TRACE_LEVEL_VERBOSE,
1831 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1832 pParentObjectInfo->FileId.Cell,
1833 pParentObjectInfo->FileId.Volume,
1834 pParentObjectInfo->FileId.Vnode,
1835 pParentObjectInfo->FileId.Unique));
1837 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1839 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1841 pParentObjectInfo->Expiration.QuadPart = 0;
1843 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1845 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1849 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1852 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1855 FILE_ACTION_REMOVED);
1858 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1861 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1867 case AFS_INVALIDATE_FLUSHED:
1870 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1871 (*ppObjectInfo)->Fcb != NULL)
1874 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1875 AFS_TRACE_LEVEL_VERBOSE,
1876 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1877 (*ppObjectInfo)->FileId.Cell,
1878 (*ppObjectInfo)->FileId.Volume,
1879 (*ppObjectInfo)->FileId.Vnode,
1880 (*ppObjectInfo)->FileId.Unique));
1882 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1883 AFS_TRACE_LEVEL_VERBOSE,
1884 "AFSInvalidateObject Flush/purge Acquiring Fcb lock %p EXCL %08lX\n",
1885 &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1886 PsGetCurrentThread()));
1888 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1891 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1892 AFS_TRACE_LEVEL_VERBOSE,
1893 "AFSInvalidateObject Flush/purge Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
1894 &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1895 PsGetCurrentThread()));
1897 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1903 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1908 if( !NT_SUCCESS( stIoStatus.Status))
1911 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1912 AFS_TRACE_LEVEL_ERROR,
1913 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1914 (*ppObjectInfo)->FileId.Cell,
1915 (*ppObjectInfo)->FileId.Volume,
1916 (*ppObjectInfo)->FileId.Vnode,
1917 (*ppObjectInfo)->FileId.Unique,
1919 stIoStatus.Information));
1921 ntStatus = stIoStatus.Status;
1925 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1928 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1934 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1935 AFS_TRACE_LEVEL_WARNING,
1936 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1937 (*ppObjectInfo)->FileId.Cell,
1938 (*ppObjectInfo)->FileId.Volume,
1939 (*ppObjectInfo)->FileId.Vnode,
1940 (*ppObjectInfo)->FileId.Unique));
1942 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1946 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
1949 ntStatus = GetExceptionCode();
1953 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1954 (*ppObjectInfo)->FileId.Cell,
1955 (*ppObjectInfo)->FileId.Volume,
1956 (*ppObjectInfo)->FileId.Vnode,
1957 (*ppObjectInfo)->FileId.Unique,
1960 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1963 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1964 AFS_TRACE_LEVEL_VERBOSE,
1965 "AFSInvalidateObject Flush/purge Releasing Fcb SectionObject lock %p EXCL %08lX\n",
1966 &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1967 PsGetCurrentThread()));
1969 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1971 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1972 AFS_TRACE_LEVEL_VERBOSE,
1973 "AFSInvalidateObject Flush/purge Releasing Fcb lock %p EXCL %08lX\n",
1974 &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1975 PsGetCurrentThread()));
1977 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->Resource);
1979 if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
1983 // Clear out the extents
1984 // Get rid of them (note this involves waiting
1985 // for any writes or reads to the cache to complete)
1988 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1993 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1996 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1999 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2000 AFS_TRACE_LEVEL_VERBOSE,
2001 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
2002 (*ppObjectInfo)->FileId.Cell,
2003 (*ppObjectInfo)->FileId.Volume,
2004 (*ppObjectInfo)->FileId.Vnode,
2005 (*ppObjectInfo)->FileId.Unique));
2007 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2010 // Fall through to the default processing
2016 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
2018 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2022 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2025 if( Reason == AFS_INVALIDATE_CREDS)
2027 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2030 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2032 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2036 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2039 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
2042 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
2045 FILE_ACTION_MODIFIED);
2047 else if ( pParentObjectInfo != NULL)
2050 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2053 FILE_ACTION_MODIFIED);
2057 // Indicate this node requires re-evaluation for the remaining reasons
2060 (*ppObjectInfo)->Expiration.QuadPart = 0;
2062 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2063 AFS_TRACE_LEVEL_VERBOSE,
2064 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2065 (*ppObjectInfo)->FileId.Cell,
2066 (*ppObjectInfo)->FileId.Volume,
2067 (*ppObjectInfo)->FileId.Vnode,
2068 (*ppObjectInfo)->FileId.Unique));
2070 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
2072 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2073 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
2074 ( Reason == AFS_INVALIDATE_CALLBACK ||
2075 Reason == AFS_INVALIDATE_EXPIRED))
2077 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
2078 AFS_INVALIDATE_DATA_VERSION)))
2081 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
2091 if ( pParentObjectInfo != NULL)
2094 AFSReleaseObjectInfo( &pParentObjectInfo);
2101 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
2104 NTSTATUS ntStatus = STATUS_SUCCESS;
2105 AFSVolumeCB *pVolumeCB = NULL;
2106 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2107 ULONGLONG ullIndex = 0;
2108 AFSObjectInfoCB *pObjectInfo = NULL;
2114 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2115 AFS_TRACE_LEVEL_VERBOSE,
2116 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
2117 InvalidateCB->FileID.Cell,
2118 InvalidateCB->FileID.Volume,
2119 InvalidateCB->FileID.Vnode,
2120 InvalidateCB->FileID.Unique,
2121 InvalidateCB->FileType,
2122 InvalidateCB->WholeVolume,
2123 InvalidateCB->Reason));
2126 // Need to locate the Fcb for the directory to purge
2129 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2130 AFS_TRACE_LEVEL_VERBOSE,
2131 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2132 &pDevExt->Specific.RDR.VolumeTreeLock,
2133 PsGetCurrentThread()));
2136 // Starve any exclusive waiters on this paticular call
2139 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2142 // Locate the volume node
2145 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2147 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2149 (AFSBTreeEntry **)&pVolumeCB);
2151 if( pVolumeCB != NULL)
2154 lCount = AFSVolumeIncrement( pVolumeCB,
2155 AFS_VOLUME_REFERENCE_INVALIDATE);
2157 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2158 AFS_TRACE_LEVEL_VERBOSE,
2159 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2164 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2166 if( !NT_SUCCESS( ntStatus) ||
2170 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2171 AFS_TRACE_LEVEL_WARNING,
2172 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2173 InvalidateCB->FileID.Cell,
2174 InvalidateCB->FileID.Volume,
2175 InvalidateCB->FileID.Vnode,
2176 InvalidateCB->FileID.Unique,
2179 try_return( ntStatus = STATUS_SUCCESS);
2183 // If this is a whole volume invalidation then go do it now
2186 if( InvalidateCB->WholeVolume)
2189 ntStatus = AFSInvalidateVolume( pVolumeCB,
2190 InvalidateCB->Reason);
2192 try_return( ntStatus);
2195 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
2198 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2201 pObjectInfo = &pVolumeCB->ObjectInformation;
2206 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2208 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2210 (AFSBTreeEntry **)&pObjectInfo);
2213 if( pObjectInfo != NULL)
2217 // Reference the node so it won't be torn down
2220 lCount = AFSObjectInfoIncrement( pObjectInfo,
2221 AFS_OBJECT_REFERENCE_INVALIDATION);
2223 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2224 AFS_TRACE_LEVEL_VERBOSE,
2225 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2230 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2232 if( !NT_SUCCESS( ntStatus) ||
2233 pObjectInfo == NULL)
2236 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2237 AFS_TRACE_LEVEL_VERBOSE,
2238 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2239 InvalidateCB->FileID.Cell,
2240 InvalidateCB->FileID.Volume,
2241 InvalidateCB->FileID.Vnode,
2242 InvalidateCB->FileID.Unique,
2245 try_return( ntStatus = STATUS_SUCCESS);
2248 AFSInvalidateObject( &pObjectInfo,
2249 InvalidateCB->Reason);
2253 if( pObjectInfo != NULL)
2256 lCount = AFSObjectInfoDecrement( pObjectInfo,
2257 AFS_OBJECT_REFERENCE_INVALIDATION);
2259 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2260 AFS_TRACE_LEVEL_VERBOSE,
2261 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2266 if ( pVolumeCB != NULL)
2269 lCount = AFSVolumeDecrement( pVolumeCB,
2270 AFS_VOLUME_REFERENCE_INVALIDATE);
2272 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2273 AFS_TRACE_LEVEL_VERBOSE,
2274 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2284 AFSIsChildOfParent( IN AFSFcb *Dcb,
2288 BOOLEAN bIsChild = FALSE;
2289 AFSFcb *pCurrentFcb = Fcb;
2290 AFSObjectInfoCB * pParentObjectInfo = NULL;
2292 while( pCurrentFcb != NULL)
2295 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2296 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2304 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2305 &pCurrentFcb->ObjectInformation->ParentFileId,
2308 if ( pParentObjectInfo != NULL)
2311 pCurrentFcb = pParentObjectInfo->Fcb;
2313 AFSReleaseObjectInfo( &pParentObjectInfo);
2327 AFSCreateHighIndex( IN AFSFileID *FileID)
2330 ULONGLONG ullIndex = 0;
2332 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2339 AFSCreateLowIndex( IN AFSFileID *FileID)
2342 ULONGLONG ullIndex = 0;
2344 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2350 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2351 IN ACCESS_MASK GrantedAccess,
2352 IN BOOLEAN DirectoryEntry)
2355 BOOLEAN bAccessGranted = TRUE;
2358 // Check if we are asking for read/write and granted only read only
2359 // NOTE: There will be more checks here
2362 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2364 AFSCheckForReadOnlyAccess( GrantedAccess,
2368 bAccessGranted = FALSE;
2371 return bAccessGranted;
2375 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2378 NTSTATUS ntStatus = STATUS_SUCCESS;
2379 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2385 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2387 if( AFSGlobalRoot == NULL)
2394 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2397 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2404 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2411 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2412 IN UNICODE_STRING *SubstituteName,
2413 IN ULONG StringIndex)
2416 NTSTATUS ntStatus = STATUS_SUCCESS;
2417 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2418 AFSSysNameCB *pSysName = NULL;
2419 ERESOURCE *pSysNameLock = NULL;
2422 UNICODE_STRING uniSysName;
2429 if( IoIs32bitProcess( NULL))
2432 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2434 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2439 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2441 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2445 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2447 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2451 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2452 AFS_TRACE_LEVEL_VERBOSE,
2453 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2455 PsGetCurrentThread()));
2457 AFSAcquireShared( pSysNameLock,
2461 // Find where we are in the list
2464 while( pSysName != NULL &&
2465 ulIndex < StringIndex)
2468 pSysName = pSysName->fLink;
2473 if( pSysName == NULL)
2476 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2477 AFS_TRACE_LEVEL_VERBOSE_2,
2478 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2480 STATUS_OBJECT_NAME_NOT_FOUND));
2482 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2485 RtlInitUnicodeString( &uniSysName,
2488 // If it is a full component of @SYS then just substitue the
2492 if( RtlCompareUnicodeString( &uniSysName,
2497 SubstituteName->Length = pSysName->SysName.Length;
2498 SubstituteName->MaximumLength = SubstituteName->Length;
2500 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2501 SubstituteName->Length,
2502 AFS_SUBST_BUFFER_TAG);
2504 if( SubstituteName->Buffer == NULL)
2507 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2510 RtlCopyMemory( SubstituteName->Buffer,
2511 pSysName->SysName.Buffer,
2512 pSysName->SysName.Length);
2519 while( ComponentName->Buffer[ usIndex] != L'@')
2525 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2526 SubstituteName->MaximumLength = SubstituteName->Length;
2528 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2529 SubstituteName->Length,
2530 AFS_SUBST_BUFFER_TAG);
2532 if( SubstituteName->Buffer == NULL)
2535 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2538 RtlCopyMemory( SubstituteName->Buffer,
2539 ComponentName->Buffer,
2540 usIndex * sizeof( WCHAR));
2542 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2543 pSysName->SysName.Buffer,
2544 pSysName->SysName.Length);
2549 AFSReleaseResource( pSysNameLock);
2556 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2557 IN OUT UNICODE_STRING *ComponentName,
2558 IN UNICODE_STRING *SubstituteName,
2559 IN OUT UNICODE_STRING *RemainingPath,
2560 IN BOOLEAN FreePathName)
2563 NTSTATUS ntStatus = STATUS_SUCCESS;
2564 UNICODE_STRING uniPathName;
2565 USHORT usPrefixNameLen = 0;
2566 SHORT sNameLenDelta = 0;
2572 // If the passed in name can handle the additional length
2573 // then just moves things around
2576 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2578 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2580 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2583 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2586 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2587 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2588 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2591 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2592 SubstituteName->Buffer,
2593 SubstituteName->Length);
2595 FullPathName->Length += sNameLenDelta;
2597 ComponentName->Length += sNameLenDelta;
2599 ComponentName->MaximumLength = ComponentName->Length;
2601 if ( RemainingPath->Buffer)
2604 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2607 try_return( ntStatus);
2611 // Need to re-allocate the buffer
2614 uniPathName.Length = FullPathName->Length -
2615 ComponentName->Length +
2616 SubstituteName->Length;
2618 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2620 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2621 uniPathName.MaximumLength,
2622 AFS_NAME_BUFFER_FOUR_TAG);
2624 if( uniPathName.Buffer == NULL)
2627 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2630 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2632 usPrefixNameLen *= sizeof( WCHAR);
2634 RtlZeroMemory( uniPathName.Buffer,
2635 uniPathName.MaximumLength);
2637 RtlCopyMemory( uniPathName.Buffer,
2638 FullPathName->Buffer,
2641 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2642 SubstituteName->Buffer,
2643 SubstituteName->Length);
2645 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2648 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2649 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2650 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2653 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2655 ComponentName->Length += sNameLenDelta;
2657 ComponentName->MaximumLength = ComponentName->Length;
2659 if ( RemainingPath->Buffer)
2662 RemainingPath->Buffer = uniPathName.Buffer
2663 + (RemainingPath->Buffer - FullPathName->Buffer)
2664 + sNameLenDelta/sizeof( WCHAR);
2669 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2672 *FullPathName = uniPathName;
2683 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2687 NTSTATUS ntStatus = STATUS_SUCCESS;
2688 AFSObjectInfoCB *pCurrentObject = NULL;
2689 AFSObjectInfoCB *pNextObject = NULL;
2695 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2696 AFS_TRACE_LEVEL_VERBOSE,
2697 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2698 VolumeCB->ObjectInformation.FileId.Cell,
2699 VolumeCB->ObjectInformation.FileId.Volume,
2700 VolumeCB->ObjectInformation.FileId.Vnode,
2701 VolumeCB->ObjectInformation.FileId.Unique,
2705 // Depending on the reason for invalidation then perform work on the node
2711 case AFS_INVALIDATE_DELETED:
2715 // Mark this volume as invalid
2718 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2720 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2726 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2730 // Invalidate the volume root directory
2733 pCurrentObject = &VolumeCB->ObjectInformation;
2735 if ( pCurrentObject )
2738 lCount = AFSObjectInfoIncrement( pCurrentObject,
2739 AFS_OBJECT_REFERENCE_INVALIDATION);
2741 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2742 AFS_TRACE_LEVEL_VERBOSE,
2743 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2747 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2749 AFSInvalidateObject( &pCurrentObject,
2752 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2755 if ( pCurrentObject)
2758 lCount = AFSObjectInfoDecrement( pCurrentObject,
2759 AFS_OBJECT_REFERENCE_INVALIDATION);
2761 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2762 AFS_TRACE_LEVEL_VERBOSE,
2763 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2770 // Apply invalidation to all other volume objects
2773 pCurrentObject = VolumeCB->ObjectInfoListHead;
2775 if ( pCurrentObject)
2779 // Reference the node so it won't be torn down
2782 lCount = AFSObjectInfoIncrement( pCurrentObject,
2783 AFS_OBJECT_REFERENCE_INVALIDATION);
2785 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2786 AFS_TRACE_LEVEL_VERBOSE,
2787 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2792 while( pCurrentObject != NULL)
2795 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2801 // Reference the node so it won't be torn down
2804 lCount = AFSObjectInfoIncrement( pNextObject,
2805 AFS_OBJECT_REFERENCE_INVALIDATION);
2807 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2808 AFS_TRACE_LEVEL_VERBOSE,
2809 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2814 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2816 AFSInvalidateObject( &pCurrentObject,
2819 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2822 if ( pCurrentObject )
2825 lCount = AFSObjectInfoDecrement( pCurrentObject,
2826 AFS_OBJECT_REFERENCE_INVALIDATION);
2828 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2829 AFS_TRACE_LEVEL_VERBOSE,
2830 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2835 pCurrentObject = pNextObject;
2838 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2845 AFSInvalidateAllVolumes( VOID)
2847 AFSVolumeCB *pVolumeCB = NULL;
2848 AFSVolumeCB *pNextVolumeCB = NULL;
2849 AFSDeviceExt *pRDRDeviceExt = NULL;
2852 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2854 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2855 AFS_TRACE_LEVEL_VERBOSE,
2856 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2857 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2858 PsGetCurrentThread()));
2860 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2863 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2868 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2869 AFS_TRACE_LEVEL_VERBOSE,
2870 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2871 pVolumeCB->ObjectInfoTree.TreeLock,
2872 PsGetCurrentThread()));
2874 lCount = AFSVolumeIncrement( pVolumeCB,
2875 AFS_VOLUME_REFERENCE_INVALIDATE);
2877 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2878 AFS_TRACE_LEVEL_VERBOSE,
2879 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2884 while( pVolumeCB != NULL)
2887 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2892 lCount = AFSVolumeIncrement( pNextVolumeCB,
2893 AFS_VOLUME_REFERENCE_INVALIDATE);
2895 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2896 AFS_TRACE_LEVEL_VERBOSE,
2897 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2902 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2904 // do I need to hold the volume lock here?
2906 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2908 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2911 lCount = AFSVolumeDecrement( pVolumeCB,
2912 AFS_VOLUME_REFERENCE_INVALIDATE);
2914 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2915 AFS_TRACE_LEVEL_VERBOSE,
2916 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2920 pVolumeCB = pNextVolumeCB;
2923 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2927 AFSVerifyEntry( IN GUID *AuthGroup,
2928 IN AFSDirectoryCB *DirEntry,
2929 IN BOOLEAN bFollowMountPoint)
2932 NTSTATUS ntStatus = STATUS_SUCCESS;
2933 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2934 AFSDirEnumEntry *pDirEnumEntry = NULL;
2935 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2936 IO_STATUS_BLOCK stIoStatus;
2941 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2942 AFS_TRACE_LEVEL_VERBOSE_2,
2943 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2944 &DirEntry->NameInformation.FileName,
2945 pObjectInfo->FileId.Cell,
2946 pObjectInfo->FileId.Volume,
2947 pObjectInfo->FileId.Vnode,
2948 pObjectInfo->FileId.Unique));
2950 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2952 bFollowMountPoint ? FALSE : TRUE,
2955 if( !NT_SUCCESS( ntStatus))
2958 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2959 AFS_TRACE_LEVEL_ERROR,
2960 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2961 &DirEntry->NameInformation.FileName,
2962 pObjectInfo->FileId.Cell,
2963 pObjectInfo->FileId.Volume,
2964 pObjectInfo->FileId.Vnode,
2965 pObjectInfo->FileId.Unique,
2968 try_return( ntStatus);
2972 // Check the data version of the file
2975 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2976 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2979 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2980 AFS_TRACE_LEVEL_VERBOSE,
2981 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
2982 pObjectInfo->DataVersion.QuadPart,
2983 &DirEntry->NameInformation.FileName,
2984 pObjectInfo->FileId.Cell,
2985 pObjectInfo->FileId.Volume,
2986 pObjectInfo->FileId.Vnode,
2987 pObjectInfo->FileId.Unique));
2990 // We are ok, just get out
2993 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2995 try_return( ntStatus = STATUS_SUCCESS);
2999 // New data version so we will need to process the node based on the type
3002 switch( pDirEnumEntry->FileType)
3005 case AFS_FILE_TYPE_MOUNTPOINT:
3009 // For a mount point we need to ensure the target is the same
3012 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
3013 &pDirEnumEntry->TargetFileId))
3019 // Update the metadata for the entry
3022 ntStatus = AFSUpdateMetaData( DirEntry,
3025 if( NT_SUCCESS( ntStatus))
3028 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3029 AFS_TRACE_LEVEL_VERBOSE,
3030 "AFSVerifyEntry MountPoint FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
3031 pObjectInfo->FileId.Cell,
3032 pObjectInfo->FileId.Volume,
3033 pObjectInfo->FileId.Vnode,
3034 pObjectInfo->FileId.Unique));
3036 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3042 case AFS_FILE_TYPE_SYMLINK:
3046 // Update the metadata for the entry
3049 ntStatus = AFSUpdateMetaData( DirEntry,
3052 if( NT_SUCCESS( ntStatus))
3055 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3056 AFS_TRACE_LEVEL_VERBOSE,
3057 "AFSVerifyEntry Symlink FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
3058 pObjectInfo->FileId.Cell,
3059 pObjectInfo->FileId.Volume,
3060 pObjectInfo->FileId.Vnode,
3061 pObjectInfo->FileId.Unique));
3063 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3069 case AFS_FILE_TYPE_FILE:
3071 FILE_OBJECT * pCCFileObject = NULL;
3073 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3076 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3077 AFS_TRACE_LEVEL_VERBOSE,
3078 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3079 &DirEntry->NameInformation.FileName,
3080 pObjectInfo->FileId.Cell,
3081 pObjectInfo->FileId.Volume,
3082 pObjectInfo->FileId.Vnode,
3083 pObjectInfo->FileId.Unique));
3085 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3088 if( pObjectInfo->Fcb != NULL)
3091 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3092 AFS_TRACE_LEVEL_VERBOSE,
3093 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3094 &DirEntry->NameInformation.FileName,
3095 pObjectInfo->FileId.Cell,
3096 pObjectInfo->FileId.Volume,
3097 pObjectInfo->FileId.Vnode,
3098 pObjectInfo->FileId.Unique));
3100 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3101 AFS_TRACE_LEVEL_VERBOSE,
3102 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3103 &pObjectInfo->Fcb->NPFcb->Resource,
3104 PsGetCurrentThread()));
3106 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3109 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3110 AFS_TRACE_LEVEL_VERBOSE,
3111 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3112 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3113 PsGetCurrentThread()));
3115 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3121 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3126 if( !NT_SUCCESS( stIoStatus.Status))
3129 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3130 AFS_TRACE_LEVEL_ERROR,
3131 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3132 &DirEntry->NameInformation.FileName,
3133 pObjectInfo->FileId.Cell,
3134 pObjectInfo->FileId.Volume,
3135 pObjectInfo->FileId.Vnode,
3136 pObjectInfo->FileId.Unique,
3138 stIoStatus.Information));
3140 ntStatus = stIoStatus.Status;
3143 if ( pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3146 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3152 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3153 AFS_TRACE_LEVEL_WARNING,
3154 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3155 &DirEntry->NameInformation.FileName,
3156 pObjectInfo->FileId.Cell,
3157 pObjectInfo->FileId.Volume,
3158 pObjectInfo->FileId.Vnode,
3159 pObjectInfo->FileId.Unique));
3161 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3165 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3167 ntStatus = GetExceptionCode();
3171 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3172 &DirEntry->NameInformation.FileName,
3173 pObjectInfo->FileId.Cell,
3174 pObjectInfo->FileId.Volume,
3175 pObjectInfo->FileId.Vnode,
3176 pObjectInfo->FileId.Unique,
3179 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3182 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3183 AFS_TRACE_LEVEL_VERBOSE,
3184 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3185 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3186 PsGetCurrentThread()));
3188 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3190 if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
3193 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3194 AFS_TRACE_LEVEL_VERBOSE,
3195 "AFSVerifyEntry Releasing Fcb lock %p EXCL %08lX\n",
3196 &pObjectInfo->Fcb->NPFcb->Resource,
3197 PsGetCurrentThread()));
3199 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3201 AFSFlushExtents( pObjectInfo->Fcb,
3205 // Acquire the Fcb to purge the cache
3208 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3209 AFS_TRACE_LEVEL_VERBOSE,
3210 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3211 &pObjectInfo->Fcb->NPFcb->Resource,
3212 PsGetCurrentThread()));
3214 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3219 // Update the metadata for the entry
3222 ntStatus = AFSUpdateMetaData( DirEntry,
3225 if( !NT_SUCCESS( ntStatus))
3228 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3229 AFS_TRACE_LEVEL_ERROR,
3230 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3231 &DirEntry->NameInformation.FileName,
3232 pObjectInfo->FileId.Cell,
3233 pObjectInfo->FileId.Volume,
3234 pObjectInfo->FileId.Vnode,
3235 pObjectInfo->FileId.Unique,
3242 // Update file sizes
3245 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3246 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3247 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3249 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3250 AFS_TRACE_LEVEL_VERBOSE,
3251 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3252 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3253 PsGetCurrentThread()));
3255 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3261 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3263 if ( pCCFileObject != NULL)
3265 CcSetFileSizes( pCCFileObject,
3266 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3269 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3272 ntStatus = GetExceptionCode();
3276 "EXCEPTION - AFSVerifyEntry CcSetFileSized failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3277 pObjectInfo->FileId.Cell,
3278 pObjectInfo->FileId.Volume,
3279 pObjectInfo->FileId.Vnode,
3280 pObjectInfo->FileId.Unique,
3284 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3285 AFS_TRACE_LEVEL_VERBOSE,
3286 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3287 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3288 PsGetCurrentThread()));
3290 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3293 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3294 AFS_TRACE_LEVEL_VERBOSE,
3295 "AFSVerifyEntry Releasing Fcb lock %p EXCL %08lX\n",
3296 &pObjectInfo->Fcb->NPFcb->Resource,
3297 PsGetCurrentThread()));
3299 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3305 // Update the metadata for the entry
3308 ntStatus = AFSUpdateMetaData( DirEntry,
3311 if( !NT_SUCCESS( ntStatus))
3314 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3315 AFS_TRACE_LEVEL_ERROR,
3316 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3317 &DirEntry->NameInformation.FileName,
3318 pObjectInfo->FileId.Cell,
3319 pObjectInfo->FileId.Volume,
3320 pObjectInfo->FileId.Vnode,
3321 pObjectInfo->FileId.Unique,
3327 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3328 AFS_TRACE_LEVEL_WARNING,
3329 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3330 &DirEntry->NameInformation.FileName,
3331 pObjectInfo->FileId.Cell,
3332 pObjectInfo->FileId.Volume,
3333 pObjectInfo->FileId.Vnode,
3334 pObjectInfo->FileId.Unique));
3338 if ( NT_SUCCESS( ntStatus))
3341 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3342 AFS_TRACE_LEVEL_VERBOSE,
3343 "AFSVerifyEntry File FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
3344 pObjectInfo->FileId.Cell,
3345 pObjectInfo->FileId.Volume,
3346 pObjectInfo->FileId.Vnode,
3347 pObjectInfo->FileId.Unique));
3349 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3354 case AFS_FILE_TYPE_DIRECTORY:
3358 // For a directory or root entry flush the content of
3359 // the directory enumeration.
3362 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3365 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3366 AFS_TRACE_LEVEL_VERBOSE_2,
3367 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3368 &DirEntry->NameInformation.FileName,
3369 pObjectInfo->FileId.Cell,
3370 pObjectInfo->FileId.Volume,
3371 pObjectInfo->FileId.Vnode,
3372 pObjectInfo->FileId.Unique));
3374 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3377 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3380 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3382 if ( !NT_SUCCESS( ntStatus))
3385 try_return( ntStatus);
3390 // Update the metadata for the entry
3393 ntStatus = AFSUpdateMetaData( DirEntry,
3396 if( NT_SUCCESS( ntStatus))
3399 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3400 AFS_TRACE_LEVEL_VERBOSE,
3401 "AFSVerifyEntry Directory FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
3402 pObjectInfo->FileId.Cell,
3403 pObjectInfo->FileId.Volume,
3404 pObjectInfo->FileId.Vnode,
3405 pObjectInfo->FileId.Unique));
3407 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3413 case AFS_FILE_TYPE_DFSLINK:
3416 UNICODE_STRING uniTargetName;
3419 // For a DFS link need to check the target name has not changed
3422 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3424 uniTargetName.MaximumLength = uniTargetName.Length;
3426 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3428 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3431 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3432 RtlCompareUnicodeString( &uniTargetName,
3433 &DirEntry->NameInformation.TargetName,
3438 // Update the target name
3441 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3443 uniTargetName.Buffer,
3444 uniTargetName.Length);
3446 if( !NT_SUCCESS( ntStatus))
3449 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3455 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3458 // Update the metadata for the entry
3461 ntStatus = AFSUpdateMetaData( DirEntry,
3464 if( NT_SUCCESS( ntStatus))
3467 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3468 AFS_TRACE_LEVEL_VERBOSE,
3469 "AFSVerifyEntry DFSLink FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
3470 pObjectInfo->FileId.Cell,
3471 pObjectInfo->FileId.Volume,
3472 pObjectInfo->FileId.Vnode,
3473 pObjectInfo->FileId.Unique));
3475 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3483 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3484 AFS_TRACE_LEVEL_WARNING,
3485 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3486 pObjectInfo->FileType,
3487 &DirEntry->NameInformation.FileName,
3488 pObjectInfo->FileId.Cell,
3489 pObjectInfo->FileId.Volume,
3490 pObjectInfo->FileId.Vnode,
3491 pObjectInfo->FileId.Unique));
3498 if( pDirEnumEntry != NULL)
3501 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3509 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3512 NTSTATUS ntStatus = STATUS_SUCCESS;
3513 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3514 ULONGLONG ullIndex = 0;
3515 AFSVolumeCB *pVolumeCB = NULL;
3521 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3522 AFS_TRACE_LEVEL_VERBOSE,
3523 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3524 VolumeStatus->Online,
3525 VolumeStatus->FileID.Cell,
3526 VolumeStatus->FileID.Volume));
3529 // Need to locate the Fcb for the directory to purge
3532 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3533 AFS_TRACE_LEVEL_VERBOSE,
3534 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3535 &pDevExt->Specific.RDR.VolumeTreeLock,
3536 PsGetCurrentThread()));
3538 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3541 // Locate the volume node
3544 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3546 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3548 (AFSBTreeEntry **)&pVolumeCB);
3550 if( pVolumeCB != NULL)
3553 lCount = AFSVolumeIncrement( pVolumeCB,
3554 AFS_VOLUME_REFERENCE_INVALIDATE);
3556 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3557 AFS_TRACE_LEVEL_VERBOSE,
3558 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3562 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3565 // Set the volume state accordingly
3568 if( VolumeStatus->Online)
3571 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3576 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3585 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3588 NTSTATUS ntStatus = STATUS_SUCCESS;
3593 if( AFSGlobalRoot == NULL)
3596 try_return( ntStatus);
3599 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3603 // Set the network state according to the information
3606 if( NetworkStatus->Online)
3609 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3614 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3617 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3628 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3632 NTSTATUS ntStatus = STATUS_SUCCESS;
3633 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3634 BOOLEAN bAcquiredLock = FALSE;
3635 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3640 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3641 AFS_TRACE_LEVEL_VERBOSE,
3642 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3643 ObjectInfo->FileId.Cell,
3644 ObjectInfo->FileId.Volume,
3645 ObjectInfo->FileId.Vnode,
3646 ObjectInfo->FileId.Unique));
3648 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3651 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3652 AFS_TRACE_LEVEL_VERBOSE,
3653 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3654 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3655 PsGetCurrentThread()));
3657 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3660 bAcquiredLock = TRUE;
3664 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3667 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3668 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3671 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3672 AFS_TRACE_LEVEL_ERROR,
3673 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3674 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3675 ObjectInfo->FileId.Cell,
3676 ObjectInfo->FileId.Volume,
3677 ObjectInfo->FileId.Vnode,
3678 ObjectInfo->FileId.Unique));
3682 // Reset the directory list information by clearing all valid entries
3685 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3687 while( pCurrentDirEntry != NULL)
3690 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3692 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3696 // If this entry has been deleted then process it here
3699 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3700 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3701 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3704 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3705 AFS_TRACE_LEVEL_VERBOSE,
3706 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3708 &pCurrentDirEntry->NameInformation.FileName));
3710 AFSDeleteDirEntry( ObjectInfo,
3716 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3718 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3719 AFS_TRACE_LEVEL_VERBOSE,
3720 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3722 pCurrentDirEntry->DirOpenReferenceCount));
3725 // We pull the short name from the parent tree since it could change below
3728 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3731 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3732 AFS_TRACE_LEVEL_VERBOSE,
3733 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3735 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3736 &pCurrentDirEntry->NameInformation.FileName));
3738 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3741 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3746 pCurrentDirEntry = pNextDirEntry;
3750 // Reget the directory contents
3753 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3756 if ( !NT_SUCCESS( ntStatus))
3758 try_return( ntStatus);
3762 // Now start again and tear down any entries not valid
3765 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3767 while( pCurrentDirEntry != NULL)
3770 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3772 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3775 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3776 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3777 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3780 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3783 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3785 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3786 AFS_TRACE_LEVEL_VERBOSE,
3787 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3789 &pCurrentDirEntry->NameInformation.FileName));
3791 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3796 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3799 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3800 AFS_TRACE_LEVEL_VERBOSE,
3801 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3803 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3804 &pCurrentDirEntry->NameInformation.FileName));
3808 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3810 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3811 AFS_TRACE_LEVEL_VERBOSE,
3812 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3814 &pCurrentDirEntry->NameInformation.FileName));
3819 pCurrentDirEntry = pNextDirEntry;
3824 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3825 AFS_TRACE_LEVEL_VERBOSE,
3826 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3828 pCurrentDirEntry->DirOpenReferenceCount));
3830 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3831 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3834 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3835 AFS_TRACE_LEVEL_VERBOSE,
3836 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3837 &pCurrentDirEntry->NameInformation.FileName,
3838 ObjectInfo->FileId.Cell,
3839 ObjectInfo->FileId.Volume,
3840 ObjectInfo->FileId.Vnode,
3841 ObjectInfo->FileId.Unique));
3843 AFSDeleteDirEntry( ObjectInfo,
3849 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3850 AFS_TRACE_LEVEL_VERBOSE,
3851 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3853 &pCurrentDirEntry->NameInformation.FileName,
3854 ObjectInfo->FileId.Cell,
3855 ObjectInfo->FileId.Volume,
3856 ObjectInfo->FileId.Vnode,
3857 ObjectInfo->FileId.Unique));
3859 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3861 AFSRemoveNameEntry( ObjectInfo,
3865 pCurrentDirEntry = pNextDirEntry;
3869 if( !AFSValidateDirList( ObjectInfo))
3872 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3881 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3889 AFSIsVolumeFID( IN AFSFileID *FileID)
3892 BOOLEAN bIsVolume = FALSE;
3894 if( FileID->Vnode == 1 &&
3895 FileID->Unique == 1)
3905 AFSIsFinalNode( IN AFSFcb *Fcb)
3908 BOOLEAN bIsFinalNode = FALSE;
3910 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3911 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3912 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3913 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3914 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3917 bIsFinalNode = TRUE;
3922 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3923 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3926 return bIsFinalNode;
3930 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3931 IN AFSDirEnumEntry *DirEnumEntry)
3934 NTSTATUS ntStatus = STATUS_SUCCESS;
3935 UNICODE_STRING uniTargetName;
3936 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3941 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3943 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3945 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3947 pObjectInfo->FileType = DirEnumEntry->FileType;
3949 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3951 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3953 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3955 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3957 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3959 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3961 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3963 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3964 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3967 pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3970 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
3973 if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
3976 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3981 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3985 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3987 pObjectInfo->Links = DirEnumEntry->Links;
3989 if( DirEnumEntry->TargetNameLength > 0 &&
3990 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3991 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3995 // Update the target name information if needed
3998 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
4000 uniTargetName.MaximumLength = uniTargetName.Length;
4002 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
4004 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4007 if( DirEntry->NameInformation.TargetName.Length == 0 ||
4008 RtlCompareUnicodeString( &uniTargetName,
4009 &DirEntry->NameInformation.TargetName,
4014 // Update the target name
4017 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
4019 uniTargetName.Buffer,
4020 uniTargetName.Length);
4022 if( !NT_SUCCESS( ntStatus))
4025 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4027 try_return( ntStatus);
4031 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4033 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
4034 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
4037 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4040 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
4041 DirEntry->NameInformation.TargetName.Buffer != NULL)
4043 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
4046 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4048 DirEntry->NameInformation.TargetName.Length = 0;
4049 DirEntry->NameInformation.TargetName.MaximumLength = 0;
4050 DirEntry->NameInformation.TargetName.Buffer = NULL;
4052 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4064 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
4066 IN BOOLEAN FastCall,
4067 IN BOOLEAN bSafeToPurge)
4070 NTSTATUS ntStatus = STATUS_SUCCESS;
4071 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4072 LARGE_INTEGER liSystemTime;
4073 AFSDirEnumEntry *pDirEnumEntry = NULL;
4074 AFSFcb *pCurrentFcb = NULL;
4075 BOOLEAN bReleaseFcb = FALSE;
4076 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
4082 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
4086 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4087 AFS_TRACE_LEVEL_VERBOSE_2,
4088 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
4089 &DirEntry->NameInformation.FileName,
4090 pObjectInfo->FileId.Cell,
4091 pObjectInfo->FileId.Volume,
4092 pObjectInfo->FileId.Vnode,
4093 pObjectInfo->FileId.Unique,
4097 // If this is a fake node then bail since the service knows nothing about it
4100 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
4103 try_return( ntStatus);
4107 // This routine ensures that the current entry is valid by:
4109 // 1) Checking that the expiration time is non-zero and after where we
4113 KeQuerySystemTime( &liSystemTime);
4115 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
4116 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
4117 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
4118 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
4121 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4122 AFS_TRACE_LEVEL_VERBOSE_2,
4123 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
4124 &DirEntry->NameInformation.FileName,
4125 pObjectInfo->FileId.Cell,
4126 pObjectInfo->FileId.Volume,
4127 pObjectInfo->FileId.Vnode,
4128 pObjectInfo->FileId.Unique));
4130 try_return( ntStatus);
4134 // This node requires updating
4137 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
4142 if( !NT_SUCCESS( ntStatus))
4145 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4146 AFS_TRACE_LEVEL_ERROR,
4147 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4149 &DirEntry->NameInformation.FileName,
4150 pObjectInfo->FileId.Cell,
4151 pObjectInfo->FileId.Volume,
4152 pObjectInfo->FileId.Vnode,
4153 pObjectInfo->FileId.Unique,
4157 // Failed validation of node so return access-denied
4160 try_return( ntStatus);
4163 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4164 AFS_TRACE_LEVEL_VERBOSE,
4165 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
4167 &DirEntry->NameInformation.FileName,
4168 pObjectInfo->FileId.Cell,
4169 pObjectInfo->FileId.Volume,
4170 pObjectInfo->FileId.Vnode,
4171 pObjectInfo->FileId.Unique,
4172 pObjectInfo->DataVersion.QuadPart,
4173 pDirEnumEntry->DataVersion.QuadPart,
4174 pDirEnumEntry->FileType));
4178 // Based on the file type, process the node
4181 switch( pDirEnumEntry->FileType)
4184 case AFS_FILE_TYPE_MOUNTPOINT:
4188 // Update the metadata for the entry
4191 ntStatus = AFSUpdateMetaData( DirEntry,
4194 if( NT_SUCCESS( ntStatus))
4197 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4198 AFS_TRACE_LEVEL_VERBOSE,
4199 "AFSValidateEntry MountPoint FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
4200 pObjectInfo->FileId.Cell,
4201 pObjectInfo->FileId.Volume,
4202 pObjectInfo->FileId.Vnode,
4203 pObjectInfo->FileId.Unique));
4205 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4211 case AFS_FILE_TYPE_SYMLINK:
4212 case AFS_FILE_TYPE_DFSLINK:
4216 // Update the metadata for the entry
4219 ntStatus = AFSUpdateMetaData( DirEntry,
4222 if( NT_SUCCESS( ntStatus))
4225 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4226 AFS_TRACE_LEVEL_VERBOSE,
4227 "AFSValidateEntry Symlink FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
4228 pObjectInfo->FileId.Cell,
4229 pObjectInfo->FileId.Volume,
4230 pObjectInfo->FileId.Vnode,
4231 pObjectInfo->FileId.Unique));
4233 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4239 case AFS_FILE_TYPE_FILE:
4242 BOOLEAN bPurgeExtents = FALSE;
4245 // For a file where the data version has become invalid we need to
4246 // fail any current extent requests and purge the cache for the file
4247 // Can't hold the Fcb resource while doing this
4250 if( pObjectInfo->Fcb != NULL &&
4251 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4252 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4255 pCurrentFcb = pObjectInfo->Fcb;
4257 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4260 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4261 AFS_TRACE_LEVEL_VERBOSE,
4262 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4263 &pCurrentFcb->NPFcb->Resource,
4264 PsGetCurrentThread()));
4266 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4272 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4273 AFS_TRACE_LEVEL_VERBOSE_2,
4274 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4275 &DirEntry->NameInformation.FileName,
4276 pObjectInfo->FileId.Cell,
4277 pObjectInfo->FileId.Volume,
4278 pObjectInfo->FileId.Vnode,
4279 pObjectInfo->FileId.Unique));
4281 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4284 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4285 AFS_TRACE_LEVEL_VERBOSE,
4286 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4287 &DirEntry->NameInformation.FileName,
4288 pObjectInfo->FileId.Cell,
4289 pObjectInfo->FileId.Volume,
4290 pObjectInfo->FileId.Vnode,
4291 pObjectInfo->FileId.Unique,
4292 pObjectInfo->DataVersion.LowPart,
4293 pDirEnumEntry->DataVersion.LowPart));
4295 bPurgeExtents = TRUE;
4301 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4303 bPurgeExtents = TRUE;
4305 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4306 AFS_TRACE_LEVEL_VERBOSE,
4307 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4308 &DirEntry->NameInformation.FileName,
4309 pObjectInfo->FileId.Cell,
4310 pObjectInfo->FileId.Volume,
4311 pObjectInfo->FileId.Vnode,
4312 pObjectInfo->FileId.Unique));
4314 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4317 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4318 AFS_TRACE_LEVEL_VERBOSE,
4319 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4320 &pCurrentFcb->NPFcb->SectionObjectResource,
4321 PsGetCurrentThread()));
4323 AFSAcquireExcl( &pCurrentFcb->NPFcb->SectionObjectResource,
4329 IO_STATUS_BLOCK stIoStatus;
4331 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4336 if( !NT_SUCCESS( stIoStatus.Status))
4339 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4340 AFS_TRACE_LEVEL_ERROR,
4341 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4342 &DirEntry->NameInformation.FileName,
4343 pObjectInfo->FileId.Cell,
4344 pObjectInfo->FileId.Volume,
4345 pObjectInfo->FileId.Vnode,
4346 pObjectInfo->FileId.Unique,
4348 stIoStatus.Information));
4350 ntStatus = stIoStatus.Status;
4353 if ( bPurgeExtents &&
4354 pCurrentFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4357 if ( !CcPurgeCacheSection( &pCurrentFcb->NPFcb->SectionObjectPointers,
4363 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4364 AFS_TRACE_LEVEL_WARNING,
4365 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4366 &DirEntry->NameInformation.FileName,
4367 pObjectInfo->FileId.Cell,
4368 pObjectInfo->FileId.Volume,
4369 pObjectInfo->FileId.Vnode,
4370 pObjectInfo->FileId.Unique));
4372 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4376 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
4378 ntStatus = GetExceptionCode();
4382 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4383 &DirEntry->NameInformation.FileName,
4384 pObjectInfo->FileId.Cell,
4385 pObjectInfo->FileId.Volume,
4386 pObjectInfo->FileId.Vnode,
4387 pObjectInfo->FileId.Unique,
4390 SetFlag( pCurrentFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4393 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4394 AFS_TRACE_LEVEL_VERBOSE,
4395 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4396 &pCurrentFcb->NPFcb->SectionObjectResource,
4397 PsGetCurrentThread()));
4399 AFSReleaseResource( &pCurrentFcb->NPFcb->SectionObjectResource);
4407 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4413 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4415 bReleaseFcb = FALSE;
4418 if ( bPurgeExtents &&
4422 if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
4424 AFSFlushExtents( pCurrentFcb,
4431 // Update the metadata for the entry but only if it is safe to do so.
4432 // If it was determined that a data version change has occurred or
4433 // that a pending data verification was required, do not update the
4434 // ObjectInfo meta data or the FileObject size information. That
4435 // way it is consistent for the next time that the data is verified
4439 if ( !(bPurgeExtents && bSafeToPurge))
4442 ntStatus = AFSUpdateMetaData( DirEntry,
4445 if( !NT_SUCCESS( ntStatus))
4448 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4449 AFS_TRACE_LEVEL_ERROR,
4450 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4451 &DirEntry->NameInformation.FileName,
4452 pObjectInfo->FileId.Cell,
4453 pObjectInfo->FileId.Volume,
4454 pObjectInfo->FileId.Vnode,
4455 pObjectInfo->FileId.Unique,
4461 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4462 AFS_TRACE_LEVEL_VERBOSE,
4463 "AFSValidateEntry File FID %08lX-%08lX-%08lX-%08lX No Purge Clearing Verify Flag\n",
4464 pObjectInfo->FileId.Cell,
4465 pObjectInfo->FileId.Volume,
4466 pObjectInfo->FileId.Vnode,
4467 pObjectInfo->FileId.Unique));
4469 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4472 // Update file sizes
4475 if( pObjectInfo->Fcb != NULL)
4477 FILE_OBJECT *pCCFileObject;
4479 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4480 AFS_TRACE_LEVEL_VERBOSE,
4481 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4482 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4483 PsGetCurrentThread()));
4485 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4491 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4493 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4494 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4495 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4497 if ( pCCFileObject != NULL)
4499 CcSetFileSizes( pCCFileObject,
4500 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4503 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
4506 ntStatus = GetExceptionCode();
4510 "EXCEPTION - AFSValidateEntry CcSetFileSizes failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4511 pObjectInfo->FileId.Cell,
4512 pObjectInfo->FileId.Volume,
4513 pObjectInfo->FileId.Vnode,
4514 pObjectInfo->FileId.Unique,
4518 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4519 AFS_TRACE_LEVEL_VERBOSE,
4520 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4521 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4522 PsGetCurrentThread()));
4524 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4530 case AFS_FILE_TYPE_DIRECTORY:
4533 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4537 // For a directory or root entry flush the content of
4538 // the directory enumeration.
4541 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4542 AFS_TRACE_LEVEL_VERBOSE,
4543 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4544 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4545 PsGetCurrentThread()));
4547 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4550 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4551 AFS_TRACE_LEVEL_VERBOSE_2,
4552 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4553 &DirEntry->NameInformation.FileName,
4554 pObjectInfo->FileId.Cell,
4555 pObjectInfo->FileId.Volume,
4556 pObjectInfo->FileId.Vnode,
4557 pObjectInfo->FileId.Unique));
4559 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4562 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4565 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4568 if( !NT_SUCCESS( ntStatus))
4571 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4572 AFS_TRACE_LEVEL_ERROR,
4573 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4574 &DirEntry->NameInformation.FileName,
4575 pObjectInfo->FileId.Cell,
4576 pObjectInfo->FileId.Volume,
4577 pObjectInfo->FileId.Vnode,
4578 pObjectInfo->FileId.Unique,
4586 // Update the metadata for the entry
4589 ntStatus = AFSUpdateMetaData( DirEntry,
4592 if( NT_SUCCESS( ntStatus))
4595 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4596 AFS_TRACE_LEVEL_VERBOSE,
4597 "AFSValidateEntry Directory FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
4598 pObjectInfo->FileId.Cell,
4599 pObjectInfo->FileId.Volume,
4600 pObjectInfo->FileId.Vnode,
4601 pObjectInfo->FileId.Unique));
4603 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4611 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4612 AFS_TRACE_LEVEL_WARNING,
4613 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4614 pObjectInfo->FileType,
4616 &DirEntry->NameInformation.FileName,
4617 pObjectInfo->FileId.Cell,
4618 pObjectInfo->FileId.Volume,
4619 pObjectInfo->FileId.Vnode,
4620 pObjectInfo->FileId.Unique));
4630 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4633 if( pDirEnumEntry != NULL)
4636 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4644 AFSInitializeSpecialShareNameList()
4647 NTSTATUS ntStatus = STATUS_SUCCESS;
4648 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4649 AFSObjectInfoCB *pObjectInfoCB = NULL;
4650 UNICODE_STRING uniShareName;
4651 ULONG ulEntryLength = 0;
4652 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4658 RtlInitUnicodeString( &uniShareName,
4661 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4664 if( pObjectInfoCB == NULL)
4667 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4670 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4671 AFS_OBJECT_REFERENCE_GLOBAL);
4673 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4674 AFS_TRACE_LEVEL_VERBOSE,
4675 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4679 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4681 ulEntryLength = sizeof( AFSDirectoryCB) +
4682 uniShareName.Length;
4684 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4688 if( pDirNode == NULL)
4691 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4692 AFS_OBJECT_REFERENCE_GLOBAL);
4694 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4695 AFS_TRACE_LEVEL_VERBOSE,
4696 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4703 AFSDeleteObjectInfo( &pObjectInfoCB);
4706 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4709 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4710 AFS_TRACE_LEVEL_VERBOSE,
4711 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4714 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4715 sizeof( AFSNonPagedDirectoryCB),
4716 AFS_DIR_ENTRY_NP_TAG);
4718 if( pNonPagedDirEntry == NULL)
4721 AFSLibExFreePoolWithTag( pDirNode,
4724 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4725 AFS_OBJECT_REFERENCE_GLOBAL);
4727 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4728 AFS_TRACE_LEVEL_VERBOSE,
4729 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4736 AFSDeleteObjectInfo( &pObjectInfoCB);
4739 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4742 RtlZeroMemory( pDirNode,
4745 RtlZeroMemory( pNonPagedDirEntry,
4746 sizeof( AFSNonPagedDirectoryCB));
4748 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4750 pDirNode->NonPaged = pNonPagedDirEntry;
4752 pDirNode->ObjectInformation = pObjectInfoCB;
4758 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4760 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4762 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4764 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4766 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4767 uniShareName.Buffer,
4768 pDirNode->NameInformation.FileName.Length);
4770 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4773 AFSSpecialShareNames = pDirNode;
4775 pLastDirNode = pDirNode;
4778 RtlInitUnicodeString( &uniShareName,
4781 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4784 if( pObjectInfoCB == NULL)
4787 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4790 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4791 AFS_OBJECT_REFERENCE_GLOBAL);
4793 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4794 AFS_TRACE_LEVEL_VERBOSE,
4795 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4799 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4801 ulEntryLength = sizeof( AFSDirectoryCB) +
4802 uniShareName.Length;
4804 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4808 if( pDirNode == NULL)
4811 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4812 AFS_OBJECT_REFERENCE_GLOBAL);
4814 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4815 AFS_TRACE_LEVEL_VERBOSE,
4816 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4823 AFSDeleteObjectInfo( &pObjectInfoCB);
4826 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4829 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4830 AFS_TRACE_LEVEL_VERBOSE,
4831 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4834 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4835 sizeof( AFSNonPagedDirectoryCB),
4836 AFS_DIR_ENTRY_NP_TAG);
4838 if( pNonPagedDirEntry == NULL)
4841 AFSLibExFreePoolWithTag( pDirNode,
4844 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4845 AFS_OBJECT_REFERENCE_GLOBAL);
4847 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4848 AFS_TRACE_LEVEL_VERBOSE,
4849 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4856 AFSDeleteObjectInfo( &pObjectInfoCB);
4859 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4862 RtlZeroMemory( pDirNode,
4865 RtlZeroMemory( pNonPagedDirEntry,
4866 sizeof( AFSNonPagedDirectoryCB));
4868 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4870 pDirNode->NonPaged = pNonPagedDirEntry;
4872 pDirNode->ObjectInformation = pObjectInfoCB;
4878 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4880 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4882 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4884 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4886 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4887 uniShareName.Buffer,
4888 pDirNode->NameInformation.FileName.Length);
4890 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4893 pLastDirNode->ListEntry.fLink = pDirNode;
4895 pDirNode->ListEntry.bLink = pLastDirNode;
4899 if( !NT_SUCCESS( ntStatus))
4902 if( AFSSpecialShareNames != NULL)
4905 pDirNode = AFSSpecialShareNames;
4907 while( pDirNode != NULL)
4910 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4912 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
4913 AFS_OBJECT_REFERENCE_GLOBAL);
4915 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4916 AFS_TRACE_LEVEL_VERBOSE,
4917 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4918 pDirNode->ObjectInformation,
4924 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4927 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4929 AFSLibExFreePoolWithTag( pDirNode->NonPaged,
4930 AFS_DIR_ENTRY_NP_TAG);
4932 AFSLibExFreePoolWithTag( pDirNode,
4935 pDirNode = pLastDirNode;
4938 AFSSpecialShareNames = NULL;
4947 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4948 IN UNICODE_STRING *SecondaryName)
4951 AFSDirectoryCB *pDirectoryCB = NULL;
4952 ULONGLONG ullHash = 0;
4953 UNICODE_STRING uniFullShareName;
4959 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4960 AFS_TRACE_LEVEL_VERBOSE_2,
4961 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4965 uniFullShareName = *ShareName;
4968 // Generate our hash value
4971 ullHash = AFSGenerateCRC( &uniFullShareName,
4975 // Loop through our special share names to see if this is one of them
4978 pDirectoryCB = AFSSpecialShareNames;
4980 while( pDirectoryCB != NULL)
4983 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4989 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4993 return pDirectoryCB;
4997 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
5001 // Block on the queue flush event
5004 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
5014 AFSWaitOnQueuedReleases()
5017 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
5020 // Block on the queue flush event
5023 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
5033 AFSIsEqualFID( IN AFSFileID *FileId1,
5034 IN AFSFileID *FileId2)
5037 BOOLEAN bIsEqual = FALSE;
5039 if( FileId1->Hash == FileId2->Hash &&
5040 FileId1->Unique == FileId2->Unique &&
5041 FileId1->Vnode == FileId2->Vnode &&
5042 FileId1->Volume == FileId2->Volume &&
5043 FileId1->Cell == FileId2->Cell)
5053 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
5056 NTSTATUS ntStatus = STATUS_SUCCESS;
5057 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
5062 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
5065 // Reset the directory list information
5068 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
5070 while( pCurrentDirEntry != NULL)
5073 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
5075 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
5076 pCurrentDirEntry->NameArrayReferenceCount <= 0)
5079 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
5080 AFS_TRACE_LEVEL_VERBOSE,
5081 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
5083 &pCurrentDirEntry->NameInformation.FileName));
5085 AFSDeleteDirEntry( ObjectInfoCB,
5091 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
5092 AFS_TRACE_LEVEL_VERBOSE,
5093 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
5095 &pCurrentDirEntry->NameInformation.FileName));
5097 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
5099 AFSRemoveNameEntry( ObjectInfoCB,
5103 pCurrentDirEntry = pNextDirEntry;
5106 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
5108 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
5110 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
5112 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
5114 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
5116 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
5118 AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
5119 AFS_TRACE_LEVEL_VERBOSE,
5120 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
5121 ObjectInfoCB->FileId.Cell,
5122 ObjectInfoCB->FileId.Volume,
5123 ObjectInfoCB->FileId.Vnode,
5124 ObjectInfoCB->FileId.Unique));
5131 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
5134 NTSTATUS ntStatus = STATUS_SUCCESS;
5135 AFSDirectoryCB *pDirGlobalDirNode = NULL;
5136 UNICODE_STRING uniFullName;
5141 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
5142 AFS_TRACE_LEVEL_VERBOSE,
5143 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
5144 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
5145 PsGetCurrentThread()));
5147 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
5150 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
5153 try_return( ntStatus);
5157 // Initialize the root information
5160 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
5163 // Enumerate the shares in the volume
5166 ntStatus = AFSEnumerateDirectory( AuthGroup,
5167 &AFSGlobalRoot->ObjectInformation,
5170 if( !NT_SUCCESS( ntStatus))
5173 try_return( ntStatus);
5176 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
5178 uniFullName.MaximumLength = PAGE_SIZE;
5179 uniFullName.Length = 0;
5181 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
5182 uniFullName.MaximumLength,
5183 AFS_GENERIC_MEMORY_12_TAG);
5185 if( uniFullName.Buffer == NULL)
5189 // Reset the directory content
5192 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
5194 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
5196 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5200 // Populate our list of entries in the NP enumeration list
5203 while( pDirGlobalDirNode != NULL)
5206 uniFullName.Buffer[ 0] = L'\\';
5207 uniFullName.Buffer[ 1] = L'\\';
5209 uniFullName.Length = 2 * sizeof( WCHAR);
5211 RtlCopyMemory( &uniFullName.Buffer[ 2],
5212 AFSServerName.Buffer,
5213 AFSServerName.Length);
5215 uniFullName.Length += AFSServerName.Length;
5217 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
5219 uniFullName.Length += sizeof( WCHAR);
5221 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
5222 pDirGlobalDirNode->NameInformation.FileName.Buffer,
5223 pDirGlobalDirNode->NameInformation.FileName.Length);
5225 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
5227 AFSAddConnectionEx( &uniFullName,
5228 RESOURCEDISPLAYTYPE_SHARE,
5231 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
5234 AFSLibExFreePoolWithTag( uniFullName.Buffer,
5235 AFS_GENERIC_MEMORY_12_TAG);
5239 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
5246 AFSIsRelativeName( IN UNICODE_STRING *Name)
5249 BOOLEAN bIsRelative = FALSE;
5251 if( Name->Length > 0 &&
5252 Name->Buffer[ 0] != L'\\')
5262 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
5264 UNICODE_STRING uniTempName;
5265 BOOLEAN bIsAbsolute = FALSE;
5268 // An absolute AFS path must begin with \afs\... or equivalent
5271 if ( Name->Length == 0 ||
5272 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
5273 Name->Buffer[ 0] != L'\\' ||
5274 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
5280 uniTempName.Length = AFSMountRootName.Length;
5281 uniTempName.MaximumLength = AFSMountRootName.Length;
5283 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5284 uniTempName.MaximumLength,
5285 AFS_NAME_BUFFER_TWO_TAG);
5287 if( uniTempName.Buffer == NULL)
5293 RtlCopyMemory( uniTempName.Buffer,
5295 AFSMountRootName.Length);
5297 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
5301 AFSExFreePoolWithTag( uniTempName.Buffer,
5302 AFS_NAME_BUFFER_TWO_TAG);
5309 AFSUpdateName( IN UNICODE_STRING *Name)
5314 while( usIndex < Name->Length/sizeof( WCHAR))
5317 if( Name->Buffer[ usIndex] == L'/')
5320 Name->Buffer[ usIndex] = L'\\';
5330 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
5331 IN OUT ULONG *Flags,
5332 IN WCHAR *NameBuffer,
5333 IN USHORT NameLength)
5336 NTSTATUS ntStatus = STATUS_SUCCESS;
5337 WCHAR *pTmpBuffer = NULL;
5343 // If we have enough space then just move in the name otherwise
5344 // allocate a new buffer
5347 if( TargetName->Length < NameLength)
5350 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5352 AFS_NAME_BUFFER_FIVE_TAG);
5354 if( pTmpBuffer == NULL)
5357 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5360 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5363 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5366 TargetName->MaximumLength = NameLength;
5368 TargetName->Buffer = pTmpBuffer;
5370 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5373 TargetName->Length = NameLength;
5375 RtlCopyMemory( TargetName->Buffer,
5377 TargetName->Length);
5380 // Update the name in the buffer
5383 AFSUpdateName( TargetName);
5394 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5399 // Depending on the type of node, set the event
5402 switch( Fcb->Header.NodeTypeCode)
5405 case AFS_DIRECTORY_FCB:
5410 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5420 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5426 // Depending on the type of node, set the event
5429 switch( Fcb->Header.NodeTypeCode)
5432 case AFS_DIRECTORY_FCB:
5437 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5439 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5449 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5452 BOOLEAN bIsInProcess = FALSE;
5457 if( ObjectInfo->Fcb == NULL)
5460 try_return( bIsInProcess);
5463 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5466 case AFS_DIRECTORY_FCB:
5471 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5474 bIsInProcess = TRUE;
5486 return bIsInProcess;
5490 AFSVerifyVolume( IN ULONGLONG ProcessId,
5491 IN AFSVolumeCB *VolumeCB)
5494 UNREFERENCED_PARAMETER(ProcessId);
5495 UNREFERENCED_PARAMETER(VolumeCB);
5496 NTSTATUS ntStatus = STATUS_SUCCESS;
5503 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5506 NTSTATUS ntStatus = STATUS_SUCCESS;
5507 AFSObjectInfoCB *pObjectInfoCB = NULL;
5508 AFSDirectoryCB *pDirNode = NULL;
5509 ULONG ulEntryLength = 0;
5510 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5516 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
5519 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5522 if( pObjectInfoCB == NULL)
5525 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5527 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5530 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5531 AFS_OBJECT_REFERENCE_PIOCTL);
5533 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5534 AFS_TRACE_LEVEL_VERBOSE,
5535 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5539 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5541 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5543 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5545 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5547 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5551 if( pDirNode == NULL)
5554 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5557 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5558 AFS_TRACE_LEVEL_VERBOSE,
5559 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5562 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5563 sizeof( AFSNonPagedDirectoryCB),
5564 AFS_DIR_ENTRY_NP_TAG);
5566 if( pNonPagedDirEntry == NULL)
5569 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5572 RtlZeroMemory( pDirNode,
5575 RtlZeroMemory( pNonPagedDirEntry,
5576 sizeof( AFSNonPagedDirectoryCB));
5578 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5580 pDirNode->NonPaged = pNonPagedDirEntry;
5582 pDirNode->ObjectInformation = pObjectInfoCB;
5584 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5590 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5592 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5594 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5596 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5598 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5599 AFSPIOCtlName.Buffer,
5600 pDirNode->NameInformation.FileName.Length);
5602 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5605 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5608 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5609 AFS_TRACE_LEVEL_WARNING,
5610 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5611 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5614 try_return( ntStatus = STATUS_REPARSE);
5619 if ( ntStatus != STATUS_SUCCESS)
5622 if ( pDirNode != NULL)
5625 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5626 AFS_TRACE_LEVEL_VERBOSE,
5627 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
5630 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5633 if( pNonPagedDirEntry != NULL)
5636 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5638 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5641 if ( pObjectInfoCB != NULL)
5644 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
5645 AFS_OBJECT_REFERENCE_PIOCTL);
5647 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5648 AFS_TRACE_LEVEL_VERBOSE,
5649 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
5656 AFSDeleteObjectInfo( &pObjectInfoCB);
5666 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5667 IN AFSDirectoryCB *DirectoryCB,
5668 IN UNICODE_STRING *ParentPathName,
5669 IN AFSNameArrayHdr *RelatedNameArray,
5671 OUT AFSFileInfoCB *FileInfo)
5674 NTSTATUS ntStatus = STATUS_SUCCESS;
5675 AFSDirEnumEntry *pDirEntry = NULL;
5676 UNICODE_STRING uniFullPathName = {0};
5677 AFSNameArrayHdr *pNameArray = NULL;
5678 AFSVolumeCB *pVolumeCB = NULL;
5679 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5680 AFSVolumeCB *pNewVolumeCB = NULL;
5681 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5682 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5683 AFSDirectoryCB *pNewParentDirEntry = NULL;
5684 WCHAR *pwchBuffer = NULL;
5685 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5686 ULONG ulNameDifference = 0;
5693 // Retrieve a target name for the entry
5696 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5699 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5702 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5704 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5709 if( !NT_SUCCESS( ntStatus) ||
5710 pDirEntry->TargetNameLength == 0)
5713 if( pDirEntry != NULL)
5716 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5719 try_return( ntStatus);
5722 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5725 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5729 // Update the target name
5732 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5733 &DirectoryCB->Flags,
5734 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5735 (USHORT)pDirEntry->TargetNameLength);
5737 if( !NT_SUCCESS( ntStatus))
5740 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5742 try_return( ntStatus);
5746 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5750 // Need to pass the full path in for parsing.
5753 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5756 uniFullPathName.Length = 0;
5757 uniFullPathName.MaximumLength = ParentPathName->Length +
5759 DirectoryCB->NameInformation.TargetName.Length;
5761 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5762 uniFullPathName.MaximumLength,
5763 AFS_NAME_BUFFER_SIX_TAG);
5765 if( uniFullPathName.Buffer == NULL)
5768 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5770 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5773 pwchBuffer = uniFullPathName.Buffer;
5775 RtlZeroMemory( uniFullPathName.Buffer,
5776 uniFullPathName.MaximumLength);
5778 RtlCopyMemory( uniFullPathName.Buffer,
5779 ParentPathName->Buffer,
5780 ParentPathName->Length);
5782 uniFullPathName.Length = ParentPathName->Length;
5784 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5785 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5788 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5790 uniFullPathName.Length += sizeof( WCHAR);
5793 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5794 DirectoryCB->NameInformation.TargetName.Buffer,
5795 DirectoryCB->NameInformation.TargetName.Length);
5797 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5799 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5800 uniParsedName.MaximumLength = uniParsedName.Length;
5802 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5804 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5807 // We populate up to the current parent
5810 if( RelatedNameArray != NULL)
5813 pNameArray = AFSInitNameArray( NULL,
5814 RelatedNameArray->MaxElementCount);
5816 if( pNameArray == NULL)
5819 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5822 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5829 pNameArray = AFSInitNameArray( NULL,
5832 if( pNameArray == NULL)
5835 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5838 ntStatus = AFSPopulateNameArray( pNameArray,
5843 if( !NT_SUCCESS( ntStatus))
5846 try_return( ntStatus);
5849 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5851 pParentDirEntry = ParentDirectoryCB;
5856 uniFullPathName.Length = 0;
5857 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5859 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5860 uniFullPathName.MaximumLength,
5861 AFS_NAME_BUFFER_SEVEN_TAG);
5863 if( uniFullPathName.Buffer == NULL)
5866 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5868 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5871 pwchBuffer = uniFullPathName.Buffer;
5873 RtlZeroMemory( uniFullPathName.Buffer,
5874 uniFullPathName.MaximumLength);
5876 RtlCopyMemory( uniFullPathName.Buffer,
5877 DirectoryCB->NameInformation.TargetName.Buffer,
5878 DirectoryCB->NameInformation.TargetName.Length);
5880 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5883 // This name should begin with the \afs server so parse it off and check it
5886 FsRtlDissectName( uniFullPathName,
5890 if( RtlCompareUnicodeString( &uniComponentName,
5895 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5897 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5898 AFS_TRACE_LEVEL_ERROR,
5899 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5902 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5905 uniFullPathName = uniRemainingPath;
5907 uniParsedName = uniFullPathName;
5909 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5911 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5917 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5920 if( pNameArray == NULL)
5923 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5926 pVolumeCB = AFSGlobalRoot;
5928 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5932 // Increment the ref count on the volume and dir entry for correct processing below
5935 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
5937 lCount = AFSVolumeIncrement( pVolumeCB,
5938 VolumeReferenceReason);
5940 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5941 AFS_TRACE_LEVEL_VERBOSE,
5942 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
5944 VolumeReferenceReason,
5947 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
5949 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5950 AFS_TRACE_LEVEL_VERBOSE,
5951 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5952 &pParentDirEntry->NameInformation.FileName,
5957 ntStatus = AFSLocateNameEntry( NULL,
5962 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5966 &NewVolumeReferenceReason,
5967 &pNewParentDirEntry,
5971 if ( pNewVolumeCB != NULL)
5974 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
5975 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
5976 // the reference on pVolumeCB that was held prior to the call.
5977 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
5978 // will be released second.
5981 lCount = AFSVolumeDecrement( pVolumeCB,
5982 VolumeReferenceReason);
5984 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5985 AFS_TRACE_LEVEL_VERBOSE,
5986 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
5988 VolumeReferenceReason,
5991 pVolumeCB = pNewVolumeCB;
5993 pNewVolumeCB = NULL;
5995 VolumeReferenceReason = NewVolumeReferenceReason;
5997 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6001 // AFSLocateNameEntry does not alter the reference count of
6002 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6003 // a reference held.
6006 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6008 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6009 AFS_TRACE_LEVEL_VERBOSE,
6010 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
6011 &pParentDirEntry->NameInformation.FileName,
6015 pParentDirEntry = pNewParentDirEntry;
6017 pNewParentDirEntry = NULL;
6019 if( !NT_SUCCESS( ntStatus) ||
6020 ntStatus == STATUS_REPARSE)
6023 try_return( ntStatus);
6027 // Store off the information
6030 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6033 // Check for the mount point being returned
6036 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
6037 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6040 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6042 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
6045 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6048 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6053 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6057 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6059 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6061 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6063 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6065 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6067 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6071 if( pDirEntry != NULL)
6074 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6077 if( pDirectoryEntry != NULL)
6080 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6082 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6083 AFS_TRACE_LEVEL_VERBOSE,
6084 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6085 &pDirectoryEntry->NameInformation.FileName,
6090 ASSERT( lCount >= 0);
6093 if ( pParentDirEntry != NULL)
6096 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6098 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6099 AFS_TRACE_LEVEL_VERBOSE,
6100 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6101 &pParentDirEntry->NameInformation.FileName,
6106 ASSERT( lCount >= 0);
6109 if( pVolumeCB != NULL)
6112 lCount = AFSVolumeDecrement( pVolumeCB,
6113 VolumeReferenceReason);
6115 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6116 AFS_TRACE_LEVEL_VERBOSE,
6117 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
6119 VolumeReferenceReason,
6123 if( pNameArray != NULL)
6126 AFSFreeNameArray( pNameArray);
6129 if( pwchBuffer != NULL)
6133 // Always free the buffer that we allocated as AFSLocateNameEntry
6134 // will not free it. If uniFullPathName.Buffer was allocated by
6135 // AFSLocateNameEntry, then we must free that as well.
6136 // Check that the uniFullPathName.Buffer in the string is not the same
6137 // offset by the length of the server name
6140 if( uniFullPathName.Length > 0 &&
6141 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6144 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6147 AFSExFreePoolWithTag( pwchBuffer, 0);
6155 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6156 IN ULONGLONG HashIndex)
6159 NTSTATUS ntStatus = STATUS_SUCCESS;
6160 AFSObjectInfoCB *pObjectInfo = NULL;
6166 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6167 sizeof( AFSObjectInfoCB),
6168 AFS_OBJECT_INFO_TAG);
6170 if( pObjectInfo == NULL)
6173 try_return( pObjectInfo);
6176 RtlZeroMemory( pObjectInfo,
6177 sizeof( AFSObjectInfoCB));
6179 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6180 sizeof( AFSNonPagedObjectInfoCB),
6181 AFS_NP_OBJECT_INFO_TAG);
6183 if( pObjectInfo->NonPagedInfo == NULL)
6186 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6188 try_return( pObjectInfo = NULL);
6191 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6193 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6195 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6197 if( ParentObjectInfo != NULL)
6200 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6202 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6204 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6206 AFSAcquireShared( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6209 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6210 AFS_OBJECT_REFERENCE_CHILD);
6212 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6213 AFS_TRACE_LEVEL_VERBOSE,
6214 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6218 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6222 // Initialize the access time
6225 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6230 ASSERT( ParentObjectInfo);
6233 // Insert the entry into the object tree and list
6236 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6238 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6241 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6246 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6247 &pObjectInfo->TreeEntry);
6249 ASSERT( NT_SUCCESS( ntStatus));
6253 // And the object list in the volume
6256 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6259 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6264 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6266 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6269 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6272 // Indicate the object is in the hash tree and linked list in the volume
6275 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6287 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6293 if ( ObjectInfo->ObjectReferenceCount == 0)
6296 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6299 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6304 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6307 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6312 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6314 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6319 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6321 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6327 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6331 LONG lCount, lCount2;
6333 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6336 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6341 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6343 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6345 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6348 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6351 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6353 ASSERT( lCount2 >= 0);
6355 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6361 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6362 IN AFSFileID *FileId,
6363 IN BOOLEAN bUpdateLastUse)
6365 DWORD ntStatus = STATUS_SUCCESS;
6367 AFSObjectInfoCB *pObjectInfo = NULL;
6370 ullIndex = AFSCreateLowIndex( FileId);
6372 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
6375 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6378 pObjectInfo = &VolumeCB->ObjectInformation;
6383 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6385 (AFSBTreeEntry **)&pObjectInfo);
6388 if ( NT_SUCCESS( ntStatus)) {
6390 lCount = AFSObjectInfoIncrement( pObjectInfo,
6391 AFS_OBJECT_REFERENCE_FIND);
6393 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6394 AFS_TRACE_LEVEL_VERBOSE,
6395 "AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
6399 if ( bUpdateLastUse)
6402 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6406 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6412 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6416 lCount = AFSObjectInfoDecrement( *ppObjectInfo,
6417 AFS_OBJECT_REFERENCE_FIND);
6419 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6420 AFS_TRACE_LEVEL_VERBOSE,
6421 "AFSReleaseObjectInfo Decrement count on object %p Cnt %d\n",
6425 *ppObjectInfo = NULL;
6429 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6431 BOOLEAN bAcquiredTreeLock = FALSE;
6432 AFSObjectInfoCB *pObjectInfo = NULL;
6433 AFSVolumeCB * pVolume = NULL;
6434 BOOLEAN bHeldInService;
6435 AFSObjectInfoCB * pParentObjectInfo = NULL;
6441 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
6445 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6446 // embedded in the VolumeCB.
6454 pVolume = (*ppObjectInfo)->VolumeCB;
6456 if( !ExIsResourceAcquiredExclusiveLite( pVolume->ObjectInfoTree.TreeLock))
6459 ASSERT( !ExIsResourceAcquiredLite( pVolume->ObjectInfoTree.TreeLock));
6461 AFSAcquireExcl( pVolume->ObjectInfoTree.TreeLock,
6464 bAcquiredTreeLock = TRUE;
6467 for ( lCount = 0; lCount < AFS_OBJECT_REFERENCE_MAX; lCount++)
6470 ASSERT( (*ppObjectInfo)->ObjectReferences[ lCount] >= 0);
6473 ASSERT( (*ppObjectInfo)->ObjectReferenceCount == 0);
6475 pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
6479 if ( pObjectInfo == NULL)
6482 try_return( NOTHING);
6485 ASSERT( *ppObjectInfo == NULL);
6487 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6490 pParentObjectInfo = AFSFindObjectInfo( pVolume,
6491 &pObjectInfo->ParentFileId,
6494 if( pParentObjectInfo != NULL)
6497 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6499 AFSAcquireShared( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6502 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6503 AFS_OBJECT_REFERENCE_CHILD);
6505 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6506 AFS_TRACE_LEVEL_VERBOSE,
6507 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6511 AFSReleaseResource( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6513 AFSReleaseObjectInfo( &pParentObjectInfo);
6518 // Remove it from the tree and list if it was inserted
6521 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6524 AFSRemoveHashEntry( &pVolume->ObjectInfoTree.TreeHead,
6525 &pObjectInfo->TreeEntry);
6528 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6531 if( pObjectInfo->ListEntry.fLink == NULL)
6534 pVolume->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6536 if( pVolume->ObjectInfoListTail != NULL)
6539 pVolume->ObjectInfoListTail->ListEntry.fLink = NULL;
6545 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6548 if( pObjectInfo->ListEntry.bLink == NULL)
6551 pVolume->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6553 if( pVolume->ObjectInfoListHead != NULL)
6556 pVolume->ObjectInfoListHead->ListEntry.bLink = NULL;
6562 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6566 bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6571 FileId = pObjectInfo->FileId;
6574 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6576 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6578 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6580 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6582 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6586 if( bAcquiredTreeLock)
6589 AFSReleaseResource( pVolume->ObjectInfoTree.TreeLock);
6593 // Release the fid in the service
6599 AFSReleaseFid( &FileId);
6607 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6608 OUT AFSDirectoryCB **TargetDirEntry)
6611 NTSTATUS ntStatus = STATUS_SUCCESS;
6612 AFSDirEnumEntry *pDirEntry = NULL;
6613 UNICODE_STRING uniFullPathName = {0};
6614 AFSNameArrayHdr *pNameArray = NULL;
6615 AFSVolumeCB *pVolumeCB = NULL;
6616 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6617 AFSVolumeCB *pNewVolumeCB = NULL;
6618 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6619 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6620 AFSDirectoryCB *pNewParentDirEntry = NULL;
6621 WCHAR *pwchBuffer = NULL;
6622 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6623 ULONG ulNameDifference = 0;
6630 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6631 DirectoryCB->ObjectInformation,
6635 if( !NT_SUCCESS( ntStatus))
6637 try_return( ntStatus);
6641 // Retrieve a target name for the entry
6644 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6647 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6650 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6652 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6657 if( !NT_SUCCESS( ntStatus) ||
6658 pDirEntry->TargetNameLength == 0)
6661 if( pDirEntry != NULL)
6664 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6667 try_return( ntStatus);
6670 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6673 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6677 // Update the target name
6680 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6681 &DirectoryCB->Flags,
6682 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6683 (USHORT)pDirEntry->TargetNameLength);
6685 if( !NT_SUCCESS( ntStatus))
6688 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6690 try_return( ntStatus);
6694 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6698 // Need to pass the full path in for parsing.
6701 uniFullPathName.Length = 0;
6702 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6704 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6705 uniFullPathName.MaximumLength,
6706 AFS_NAME_BUFFER_EIGHT_TAG);
6708 if( uniFullPathName.Buffer == NULL)
6711 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6713 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6716 pwchBuffer = uniFullPathName.Buffer;
6718 RtlZeroMemory( uniFullPathName.Buffer,
6719 uniFullPathName.MaximumLength);
6721 RtlCopyMemory( uniFullPathName.Buffer,
6722 DirectoryCB->NameInformation.TargetName.Buffer,
6723 DirectoryCB->NameInformation.TargetName.Length);
6725 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6728 // This name should begin with the \afs server so parse it off and chech it
6731 FsRtlDissectName( uniFullPathName,
6735 if( RtlCompareUnicodeString( &uniComponentName,
6741 // Try evaluating the full path
6744 uniFullPathName.Buffer = pwchBuffer;
6746 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6748 uniFullPathName.MaximumLength = uniFullPathName.Length;
6753 uniFullPathName = uniRemainingPath;
6756 uniParsedName = uniFullPathName;
6758 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6760 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6766 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6769 if( pNameArray == NULL)
6772 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6775 pVolumeCB = AFSGlobalRoot;
6777 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6779 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
6781 lCount = AFSVolumeIncrement( pVolumeCB,
6782 VolumeReferenceReason);
6784 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6785 AFS_TRACE_LEVEL_VERBOSE,
6786 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
6788 VolumeReferenceReason,
6791 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6793 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6794 AFS_TRACE_LEVEL_VERBOSE,
6795 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6796 &pParentDirEntry->NameInformation.FileName,
6801 ntStatus = AFSLocateNameEntry( NULL,
6810 &VolumeReferenceReason,
6811 &pNewParentDirEntry,
6815 if ( pNewVolumeCB != NULL)
6818 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6819 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6820 // the reference on pVolumeCB that was held prior to the call.
6821 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6822 // will be released second.
6825 lCount = AFSVolumeDecrement( pVolumeCB,
6826 VolumeReferenceReason);
6828 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6829 AFS_TRACE_LEVEL_VERBOSE,
6830 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
6832 VolumeReferenceReason,
6835 pVolumeCB = pNewVolumeCB;
6837 pNewVolumeCB = NULL;
6839 VolumeReferenceReason = NewVolumeReferenceReason;
6841 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6845 // AFSLocateNameEntry does not alter the reference count of
6846 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6847 // a reference held.
6850 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6852 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6853 AFS_TRACE_LEVEL_VERBOSE,
6854 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
6855 &pParentDirEntry->NameInformation.FileName,
6859 pParentDirEntry = pNewParentDirEntry;
6861 pNewParentDirEntry = NULL;
6863 if( !NT_SUCCESS( ntStatus) ||
6864 ntStatus == STATUS_REPARSE)
6869 try_return( ntStatus);
6873 // Pass back the target dir entry for this request
6874 // The caller must release the DirOpenReferenceCount
6877 *TargetDirEntry = pDirectoryEntry;
6879 pDirectoryEntry = NULL;
6883 if( pDirectoryEntry != NULL)
6886 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6888 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6889 AFS_TRACE_LEVEL_VERBOSE,
6890 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6891 &pDirectoryEntry->NameInformation.FileName,
6896 ASSERT( lCount >= 0);
6899 if ( pParentDirEntry != NULL)
6902 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6904 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6905 AFS_TRACE_LEVEL_VERBOSE,
6906 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6907 &pParentDirEntry->NameInformation.FileName,
6912 ASSERT( lCount >= 0);
6915 if( pDirEntry != NULL)
6918 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6921 if( pVolumeCB != NULL)
6924 lCount = AFSVolumeDecrement( pVolumeCB,
6925 VolumeReferenceReason);
6927 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6928 AFS_TRACE_LEVEL_VERBOSE,
6929 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
6931 VolumeReferenceReason,
6935 if( pNameArray != NULL)
6938 AFSFreeNameArray( pNameArray);
6941 if( pwchBuffer != NULL)
6945 // Always free the buffer that we allocated as AFSLocateNameEntry
6946 // will not free it. If uniFullPathName.Buffer was allocated by
6947 // AFSLocateNameEntry, then we must free that as well.
6948 // Check that the uniFullPathName.Buffer in the string is not the same
6949 // offset by the length of the server name
6952 if( uniFullPathName.Length > 0 &&
6953 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6956 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6959 AFSExFreePoolWithTag( pwchBuffer, 0);
6967 AFSCleanupFcb( IN AFSFcb *Fcb,
6968 IN BOOLEAN ForceFlush)
6971 NTSTATUS ntStatus = STATUS_SUCCESS;
6972 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6973 LARGE_INTEGER liTime;
6974 IO_STATUS_BLOCK stIoStatus;
6979 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6981 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6983 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6986 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6987 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6990 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6991 AFS_TRACE_LEVEL_VERBOSE,
6992 "AFSCleanupEntry Acquiring Fcb lock %p EXCL %08lX\n",
6993 &Fcb->NPFcb->Resource,
6994 PsGetCurrentThread()));
6996 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6999 if( Fcb->OpenReferenceCount > 0)
7002 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7003 AFS_TRACE_LEVEL_VERBOSE,
7004 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7005 &Fcb->NPFcb->SectionObjectResource,
7006 PsGetCurrentThread()));
7008 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
7014 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7019 if( !NT_SUCCESS( stIoStatus.Status))
7022 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7023 AFS_TRACE_LEVEL_ERROR,
7024 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7025 Fcb->ObjectInformation->FileId.Cell,
7026 Fcb->ObjectInformation->FileId.Volume,
7027 Fcb->ObjectInformation->FileId.Vnode,
7028 Fcb->ObjectInformation->FileId.Unique,
7030 stIoStatus.Information));
7032 ntStatus = stIoStatus.Status;
7035 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7038 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7044 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7045 AFS_TRACE_LEVEL_WARNING,
7046 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
7047 Fcb->ObjectInformation->FileId.Cell,
7048 Fcb->ObjectInformation->FileId.Volume,
7049 Fcb->ObjectInformation->FileId.Vnode,
7050 Fcb->ObjectInformation->FileId.Unique));
7052 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7056 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
7059 ntStatus = GetExceptionCode();
7063 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7064 Fcb->ObjectInformation->FileId.Cell,
7065 Fcb->ObjectInformation->FileId.Volume,
7066 Fcb->ObjectInformation->FileId.Vnode,
7067 Fcb->ObjectInformation->FileId.Unique,
7070 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7073 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7074 AFS_TRACE_LEVEL_VERBOSE,
7075 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7076 &Fcb->NPFcb->SectionObjectResource,
7077 PsGetCurrentThread()));
7079 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7082 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7083 AFS_TRACE_LEVEL_VERBOSE,
7084 "AFSCleanupEntry Releasing Fcb lock %p EXCL %08lX\n",
7085 &Fcb->NPFcb->Resource,
7086 PsGetCurrentThread()));
7088 AFSReleaseResource( &Fcb->NPFcb->Resource);
7090 if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
7093 // Wait for any currently running flush or release requests to complete
7096 AFSWaitOnQueuedFlushes( Fcb);
7099 // Now perform another flush on the file
7102 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7106 AFSReleaseExtentsWithFlush( Fcb,
7113 if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
7116 if( Fcb->OpenReferenceCount == 0 ||
7117 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7118 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7121 AFSTearDownFcbExtents( Fcb,
7126 try_return( ntStatus);
7129 KeQueryTickCount( &liTime);
7131 if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
7134 // First up are there dirty extents in the cache to flush?
7137 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7138 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7142 // The file has been marked as invalid. Dump it
7145 AFSTearDownFcbExtents( Fcb,
7148 else if( ForceFlush ||
7149 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7150 Fcb->Specific.File.ExtentCount) &&
7151 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7152 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7155 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7157 Fcb->OpenReferenceCount == 0)
7160 AFSReleaseExtentsWithFlush( Fcb,
7168 // If there are extents and they haven't been used recently *and*
7169 // are not being used
7173 ( 0 != Fcb->Specific.File.ExtentCount &&
7174 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7175 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7176 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7179 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7180 AFS_TRACE_LEVEL_VERBOSE,
7181 "AFSCleanupFcb Acquiring Fcb lock %p EXCL %08lX\n",
7182 &Fcb->NPFcb->Resource,
7183 PsGetCurrentThread()));
7185 if ( AFSAcquireExcl( &Fcb->NPFcb->Resource, ForceFlush) == FALSE)
7188 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7189 AFS_TRACE_LEVEL_VERBOSE,
7190 "AFSCleanupFcb Failed to Acquire Fcb lock %p EXCL %08lX\n",
7191 &Fcb->NPFcb->Resource,
7192 PsGetCurrentThread()));
7194 try_return( ntStatus = STATUS_RETRY);
7197 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7198 AFS_TRACE_LEVEL_VERBOSE,
7199 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7200 &Fcb->NPFcb->SectionObjectResource,
7201 PsGetCurrentThread()));
7203 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7209 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7214 if( !NT_SUCCESS( stIoStatus.Status))
7217 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7218 AFS_TRACE_LEVEL_ERROR,
7219 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7220 Fcb->ObjectInformation->FileId.Cell,
7221 Fcb->ObjectInformation->FileId.Volume,
7222 Fcb->ObjectInformation->FileId.Vnode,
7223 Fcb->ObjectInformation->FileId.Unique,
7225 stIoStatus.Information));
7227 ntStatus = stIoStatus.Status;
7231 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7234 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7240 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7241 AFS_TRACE_LEVEL_WARNING,
7242 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7243 Fcb->ObjectInformation->FileId.Cell,
7244 Fcb->ObjectInformation->FileId.Volume,
7245 Fcb->ObjectInformation->FileId.Vnode,
7246 Fcb->ObjectInformation->FileId.Unique));
7248 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7252 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
7255 ntStatus = GetExceptionCode();
7259 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7260 Fcb->ObjectInformation->FileId.Cell,
7261 Fcb->ObjectInformation->FileId.Volume,
7262 Fcb->ObjectInformation->FileId.Vnode,
7263 Fcb->ObjectInformation->FileId.Unique,
7267 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7268 AFS_TRACE_LEVEL_VERBOSE,
7269 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7270 &Fcb->NPFcb->SectionObjectResource,
7271 PsGetCurrentThread()));
7273 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7275 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7276 AFS_TRACE_LEVEL_VERBOSE,
7277 "AFSCleanupFcb Releasing Fcb lock %p EXCL %08lX\n",
7278 &Fcb->NPFcb->Resource,
7279 PsGetCurrentThread()));
7281 AFSReleaseResource( &Fcb->NPFcb->Resource);
7283 if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
7286 if( Fcb->OpenReferenceCount <= 0)
7290 // Tear em down we'll not be needing them again
7293 AFSTearDownFcbExtents( Fcb,
7301 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7302 AFS_TRACE_LEVEL_VERBOSE,
7303 "AFSCleanupFcb Failed to Acquire Fcb SectionObject lock %p EXCL %08lX\n",
7304 &Fcb->NPFcb->SectionObjectResource,
7305 PsGetCurrentThread()));
7307 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7308 AFS_TRACE_LEVEL_VERBOSE,
7309 "AFSCleanupFcb Releasing Fcb lock %p EXCL %08lX\n",
7310 &Fcb->NPFcb->Resource,
7311 PsGetCurrentThread()));
7313 AFSReleaseResource( &Fcb->NPFcb->Resource);
7315 ntStatus = STATUS_RETRY;
7328 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7329 IN UNICODE_STRING *NewFileName)
7332 NTSTATUS ntStatus = STATUS_SUCCESS;
7333 WCHAR *pTmpBuffer = NULL;
7338 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7341 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7344 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7346 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7348 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7352 // OK, we need to allocate a new name buffer
7355 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7356 NewFileName->Length,
7357 AFS_NAME_BUFFER_NINE_TAG);
7359 if( pTmpBuffer == NULL)
7362 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7365 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7367 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7369 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7372 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7374 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7375 NewFileName->Buffer,
7376 NewFileName->Length);
7387 AFSReadCacheFile( IN void *ReadBuffer,
7388 IN LARGE_INTEGER *ReadOffset,
7389 IN ULONG RequestedDataLength,
7390 IN OUT PULONG BytesRead)
7393 NTSTATUS ntStatus = STATUS_SUCCESS;
7396 PIO_STACK_LOCATION pIoStackLocation = NULL;
7397 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7398 FILE_OBJECT *pCacheFileObject = NULL;
7403 pCacheFileObject = AFSReferenceCacheFileObject();
7405 if( pCacheFileObject == NULL)
7407 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7410 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7413 // Initialize the event
7416 KeInitializeEvent( &kEvent,
7417 SynchronizationEvent,
7421 // Allocate an irp for this request. This could also come from a
7422 // private pool, for instance.
7425 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7431 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7435 // Build the IRP's main body
7438 pIrp->UserBuffer = ReadBuffer;
7440 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7441 pIrp->RequestorMode = KernelMode;
7442 pIrp->Flags |= IRP_READ_OPERATION;
7445 // Set up the I/O stack location.
7448 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7449 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7450 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7451 pIoStackLocation->FileObject = pCacheFileObject;
7452 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7454 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7457 // Set the completion routine.
7460 IoSetCompletionRoutine( pIrp,
7468 // Send it to the FSD
7471 ntStatus = IoCallDriver( pTargetDeviceObject,
7474 if( NT_SUCCESS( ntStatus))
7481 ntStatus = KeWaitForSingleObject( &kEvent,
7487 if( NT_SUCCESS( ntStatus))
7490 ntStatus = pIrp->IoStatus.Status;
7492 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7498 if( pCacheFileObject != NULL)
7500 AFSReleaseCacheFileObject( pCacheFileObject);
7506 if( pIrp->MdlAddress != NULL)
7509 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7512 MmUnlockPages( pIrp->MdlAddress);
7515 IoFreeMdl( pIrp->MdlAddress);
7518 pIrp->MdlAddress = NULL;
7532 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7537 UNREFERENCED_PARAMETER(Irp);
7538 UNREFERENCED_PARAMETER(DeviceObject);
7539 KEVENT *pEvent = (KEVENT *)Context;
7545 return STATUS_MORE_PROCESSING_REQUIRED;
7549 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7552 BOOLEAN bIsEmpty = FALSE;
7553 AFSDirectoryCB *pDirEntry = NULL;
7558 ASSERT( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY);
7560 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7565 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7568 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7570 while( pDirEntry != NULL)
7573 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7574 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7582 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7587 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7594 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7595 IN AFSDirectoryCB *DirEntry)
7598 NTSTATUS ntStatus = STATUS_SUCCESS;
7603 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7606 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7607 AFS_TRACE_LEVEL_VERBOSE,
7608 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7610 &DirEntry->NameInformation.FileName));
7612 try_return( ntStatus);
7615 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7618 // Remove the entry from the parent tree
7621 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7622 AFS_TRACE_LEVEL_VERBOSE,
7623 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7625 &DirEntry->NameInformation.FileName));
7627 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7630 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7631 AFS_TRACE_LEVEL_VERBOSE,
7632 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7634 &DirEntry->NameInformation.FileName));
7636 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7639 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7643 // From the short name tree
7646 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7647 AFS_TRACE_LEVEL_VERBOSE,
7648 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7650 &DirEntry->NameInformation.FileName));
7652 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7655 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7658 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7659 AFS_TRACE_LEVEL_VERBOSE,
7660 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7662 &DirEntry->NameInformation.FileName));
7664 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7666 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7677 AFSGetAuthenticationId()
7680 LARGE_INTEGER liAuthId = {0,0};
7681 NTSTATUS ntStatus = STATUS_SUCCESS;
7682 PACCESS_TOKEN hToken = NULL;
7683 PTOKEN_STATISTICS pTokenInfo = NULL;
7684 BOOLEAN bCopyOnOpen = FALSE;
7685 BOOLEAN bEffectiveOnly = FALSE;
7686 BOOLEAN bPrimaryToken = FALSE;
7687 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7692 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7695 &stImpersonationLevel);
7700 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7705 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7706 AFS_TRACE_LEVEL_ERROR,
7707 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
7709 try_return( ntStatus);
7712 bPrimaryToken = TRUE;
7715 ntStatus = SeQueryInformationToken( hToken,
7717 (PVOID *)&pTokenInfo);
7719 if( !NT_SUCCESS( ntStatus))
7722 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7723 AFS_TRACE_LEVEL_ERROR,
7724 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
7727 try_return( ntStatus);
7730 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7731 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7733 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7734 AFS_TRACE_LEVEL_VERBOSE,
7735 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7736 liAuthId.QuadPart));
7746 PsDereferenceImpersonationToken( hToken);
7751 PsDereferencePrimaryToken( hToken);
7755 if( pTokenInfo != NULL)
7758 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7766 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7770 UNREFERENCED_PARAMETER(Fcb);
7771 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7773 Fcb->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7776 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7778 Fcb->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7781 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7783 Fcb->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7786 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7788 Fcb->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7791 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7793 Fcb->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7800 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7803 BOOLEAN bIsValid = TRUE;
7805 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7807 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7809 while( pCurrentDirEntry != NULL)
7812 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7816 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7821 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7822 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7825 if( pDirEntry == NULL)
7832 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7835 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
7838 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7840 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7842 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7851 AFSReferenceCacheFileObject()
7854 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7855 FILE_OBJECT *pCacheFileObject = NULL;
7857 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7860 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7862 if( pCacheFileObject != NULL)
7864 ObReferenceObject( pCacheFileObject);
7867 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7869 return pCacheFileObject;
7873 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7876 ASSERT( CacheFileObject != NULL);
7878 ObDereferenceObject( CacheFileObject);
7884 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7887 NTSTATUS ntStatus = STATUS_SUCCESS;
7888 AFSDeviceExt *pControlDevExt = NULL;
7889 ULONG ulTimeIncrement = 0;
7895 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7897 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7899 AFSServerName = LibraryInit->AFSServerName;
7901 AFSMountRootName = LibraryInit->AFSMountRootName;
7903 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7906 // Callbacks in the framework
7909 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7911 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7913 AFSDebugTraceFnc = AFSDbgLogMsg;
7915 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7917 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7919 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
7921 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7923 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7925 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7927 if( LibraryInit->AFSCacheBaseAddress != NULL)
7930 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7932 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7934 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7938 // Initialize some flush parameters
7941 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7943 ulTimeIncrement = KeQueryTimeIncrement();
7945 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7946 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7947 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7948 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7949 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7952 // Initialize the global root entry
7955 ntStatus = AFSInitVolume( NULL,
7956 &LibraryInit->GlobalRootFid,
7957 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
7960 if( !NT_SUCCESS( ntStatus))
7963 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7964 AFS_TRACE_LEVEL_ERROR,
7965 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7968 try_return( ntStatus);
7971 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7974 if( !NT_SUCCESS( ntStatus))
7977 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7978 AFS_TRACE_LEVEL_ERROR,
7979 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7982 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7983 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7985 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7986 AFS_TRACE_LEVEL_VERBOSE,
7987 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7991 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7993 try_return( ntStatus);
7997 // Update the node type code to AFS_ROOT_ALL
8000 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
8002 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
8005 // Invalidate all known volumes since contact with the service and therefore
8006 // the file server was lost.
8009 AFSInvalidateAllVolumes();
8012 // Drop the locks acquired above
8015 AFSInitVolumeWorker( AFSGlobalRoot);
8017 lCount = AFSVolumeDecrement( AFSGlobalRoot,
8018 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
8020 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8021 AFS_TRACE_LEVEL_VERBOSE,
8022 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8026 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8028 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
8042 NTSTATUS ntStatus = STATUS_SUCCESS;
8043 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
8049 if( AFSGlobalDotDirEntry != NULL)
8052 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
8053 AFS_OBJECT_REFERENCE_GLOBAL);
8055 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8056 AFS_TRACE_LEVEL_VERBOSE,
8057 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
8058 AFSGlobalDotDirEntry->ObjectInformation,
8064 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
8067 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
8069 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry->NonPaged,
8070 AFS_DIR_ENTRY_NP_TAG);
8072 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry,
8075 AFSGlobalDotDirEntry = NULL;
8078 if( AFSGlobalDotDotDirEntry != NULL)
8081 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
8082 AFS_OBJECT_REFERENCE_GLOBAL);
8084 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8085 AFS_TRACE_LEVEL_VERBOSE,
8086 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
8087 AFSGlobalDotDotDirEntry->ObjectInformation,
8093 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
8096 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
8098 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry->NonPaged,
8099 AFS_DIR_ENTRY_NP_TAG);
8101 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry,
8104 AFSGlobalDotDotDirEntry = NULL;
8107 if( AFSSpecialShareNames != NULL)
8110 pDirNode = AFSSpecialShareNames;
8112 while( pDirNode != NULL)
8115 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
8117 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
8118 AFS_OBJECT_REFERENCE_GLOBAL);
8120 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8121 AFS_TRACE_LEVEL_VERBOSE,
8122 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
8123 pDirNode->ObjectInformation,
8129 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
8132 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
8134 AFSLibExFreePoolWithTag( pDirNode->NonPaged,
8135 AFS_DIR_ENTRY_NP_TAG);
8137 AFSLibExFreePoolWithTag( pDirNode,
8140 pDirNode = pLastDirNode;
8143 AFSSpecialShareNames = NULL;
8151 AFSDefaultLogMsg( IN ULONG Subsystem,
8157 UNREFERENCED_PARAMETER(Subsystem);
8158 UNREFERENCED_PARAMETER(Level);
8159 NTSTATUS ntStatus = STATUS_SUCCESS;
8161 char chDebugBuffer[ 256];
8166 va_start( va_args, Format);
8168 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8173 if( NT_SUCCESS( ntStatus))
8175 DbgPrint( chDebugBuffer);
8185 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8186 IN ULONG InputBufferLength,
8187 IN AFSStatusInfoCB *StatusInfo,
8188 OUT ULONG *ReturnLength)
8191 NTSTATUS ntStatus = STATUS_SUCCESS;
8192 AFSVolumeCB *pVolumeCB = NULL;
8193 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8194 AFSVolumeCB *pNewVolumeCB = NULL;
8195 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8196 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8197 AFSObjectInfoCB *pObjectInfo = NULL;
8198 ULONGLONG ullIndex = 0;
8199 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8200 AFSNameArrayHdr *pNameArray = NULL;
8201 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8202 AFSDirectoryCB *pNewParentDirEntry = NULL;
8209 // If we are given a FID then look up the entry by that, otherwise
8213 if( GetStatusInfo->FileID.Cell != 0 &&
8214 GetStatusInfo->FileID.Volume != 0 &&
8215 GetStatusInfo->FileID.Vnode != 0 &&
8216 GetStatusInfo->FileID.Unique != 0)
8219 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8222 // Locate the volume node
8225 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8227 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8229 (AFSBTreeEntry **)&pVolumeCB);
8231 if( pVolumeCB != NULL)
8234 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8236 lCount = AFSVolumeIncrement( pVolumeCB,
8237 VolumeReferenceReason);
8239 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8240 AFS_TRACE_LEVEL_VERBOSE,
8241 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
8243 VolumeReferenceReason,
8247 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8249 if( !NT_SUCCESS( ntStatus) ||
8252 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8255 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8258 pObjectInfo = &pVolumeCB->ObjectInformation;
8260 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8263 lCount = AFSObjectInfoIncrement( pObjectInfo,
8264 AFS_OBJECT_REFERENCE_STATUS);
8266 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8267 AFS_TRACE_LEVEL_VERBOSE,
8268 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8272 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8277 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
8280 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8282 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8284 (AFSBTreeEntry **)&pObjectInfo);
8286 if( pObjectInfo != NULL)
8290 // Reference the node so it won't be torn down
8293 lCount = AFSObjectInfoIncrement( pObjectInfo,
8294 AFS_OBJECT_REFERENCE_STATUS);
8296 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8297 AFS_TRACE_LEVEL_VERBOSE,
8298 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8302 KeQueryTickCount( &pObjectInfo->LastAccessCount);
8305 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8307 if( !NT_SUCCESS( ntStatus) ||
8308 pObjectInfo == NULL)
8310 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8317 if( GetStatusInfo->FileNameLength == 0 ||
8318 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8320 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8323 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8324 uniFullPathName.MaximumLength = uniFullPathName.Length;
8326 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8329 // This name should begin with the \afs server so parse it off and check it
8332 FsRtlDissectName( uniFullPathName,
8336 if( RtlCompareUnicodeString( &uniComponentName,
8340 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8341 AFS_TRACE_LEVEL_ERROR,
8342 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8345 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8348 uniFullPathName = uniRemainingPath;
8350 uniParsedName = uniFullPathName;
8356 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8359 if( pNameArray == NULL)
8361 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8364 pVolumeCB = AFSGlobalRoot;
8366 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8369 // Increment the ref count on the volume and dir entry for correct processing below
8372 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8374 lCount = AFSVolumeIncrement( pVolumeCB,
8375 VolumeReferenceReason);
8377 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8378 AFS_TRACE_LEVEL_VERBOSE,
8379 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8381 VolumeReferenceReason,
8384 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8386 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8387 AFS_TRACE_LEVEL_VERBOSE,
8388 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8389 &pParentDirEntry->NameInformation.FileName,
8394 ntStatus = AFSLocateNameEntry( NULL,
8399 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8400 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8404 &NewVolumeReferenceReason,
8405 &pNewParentDirEntry,
8409 if ( pNewVolumeCB != NULL)
8413 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8414 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8415 // the reference on pVolumeCB that was held prior to the call.
8416 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8417 // will be released second.
8420 lCount = AFSVolumeDecrement( pVolumeCB,
8421 VolumeReferenceReason);
8423 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8424 AFS_TRACE_LEVEL_VERBOSE,
8425 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8427 VolumeReferenceReason,
8430 pVolumeCB = pNewVolumeCB;
8432 pNewVolumeCB = NULL;
8434 VolumeReferenceReason = NewVolumeReferenceReason;
8436 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8440 // AFSLocateNameEntry does not alter the reference count of
8441 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8442 // a reference held.
8445 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8447 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8448 AFS_TRACE_LEVEL_VERBOSE,
8449 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8450 &pParentDirEntry->NameInformation.FileName,
8454 pParentDirEntry = pNewParentDirEntry;
8456 pNewParentDirEntry = NULL;
8458 if( !NT_SUCCESS( ntStatus) ||
8459 ntStatus == STATUS_REPARSE)
8464 try_return( ntStatus);
8467 pObjectInfo = pDirectoryEntry->ObjectInformation;
8469 AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
8472 lCount = AFSObjectInfoIncrement( pObjectInfo,
8473 AFS_OBJECT_REFERENCE_STATUS);
8475 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8476 AFS_TRACE_LEVEL_VERBOSE,
8477 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8481 AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
8485 // At this point we have an object info block, return the information
8488 StatusInfo->FileId = pObjectInfo->FileId;
8490 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8492 StatusInfo->Expiration = pObjectInfo->Expiration;
8494 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8496 StatusInfo->FileType = pObjectInfo->FileType;
8498 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8500 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8502 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8504 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8506 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8508 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8510 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8512 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8514 StatusInfo->EaSize = pObjectInfo->EaSize;
8516 StatusInfo->Links = pObjectInfo->Links;
8519 // Return the information length
8522 *ReturnLength = sizeof( AFSStatusInfoCB);
8526 if( pDirectoryEntry != NULL)
8529 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8531 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8532 AFS_TRACE_LEVEL_VERBOSE,
8533 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8534 &pDirectoryEntry->NameInformation.FileName,
8539 ASSERT( lCount >= 0);
8542 if ( pParentDirEntry != NULL)
8545 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8547 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8548 AFS_TRACE_LEVEL_VERBOSE,
8549 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8550 &pParentDirEntry->NameInformation.FileName,
8555 ASSERT( lCount >= 0);
8558 if( pVolumeCB != NULL)
8561 if( pObjectInfo != NULL)
8564 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8567 lCount = AFSObjectInfoDecrement( pObjectInfo,
8568 AFS_OBJECT_REFERENCE_STATUS);
8570 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8571 AFS_TRACE_LEVEL_VERBOSE,
8572 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8576 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8579 lCount = AFSVolumeDecrement( pVolumeCB,
8580 VolumeReferenceReason);
8582 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8583 AFS_TRACE_LEVEL_VERBOSE,
8584 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8586 VolumeReferenceReason,
8590 if( pNameArray != NULL)
8593 AFSFreeNameArray( pNameArray);
8601 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8602 IN UNICODE_STRING *ComponentName)
8605 NTSTATUS ntStatus = STATUS_SUCCESS;
8606 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8607 AFSDirectoryCB *pDirEntry = NULL;
8615 // Search for the entry in the parent
8618 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8619 AFS_TRACE_LEVEL_VERBOSE_2,
8620 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8623 ulCRC = AFSGenerateCRC( ComponentName,
8626 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8629 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8633 if( pDirEntry == NULL)
8637 // Missed so perform a case insensitive lookup
8640 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8641 AFS_TRACE_LEVEL_VERBOSE_2,
8642 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8645 ulCRC = AFSGenerateCRC( ComponentName,
8648 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8652 if( pDirEntry == NULL)
8656 // OK, if this component is a valid short name then try
8657 // a lookup in the short name tree
8660 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8661 RtlIsNameLegalDOS8Dot3( ComponentName,
8666 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8667 AFS_TRACE_LEVEL_VERBOSE_2,
8668 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8671 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8678 if( pDirEntry != NULL)
8680 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8682 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8683 AFS_TRACE_LEVEL_VERBOSE,
8684 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8685 &pDirEntry->NameInformation.FileName,
8690 ASSERT( lCount >= 0);
8693 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8695 if( pDirEntry == NULL)
8698 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8699 AFS_TRACE_LEVEL_VERBOSE_2,
8700 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8702 STATUS_OBJECT_NAME_NOT_FOUND));
8704 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8708 // We have the symlink object but previously failed to process it so return access
8712 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8713 AFS_TRACE_LEVEL_VERBOSE_2,
8714 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8717 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8719 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8721 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8722 AFS_TRACE_LEVEL_VERBOSE,
8723 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8724 &pDirEntry->NameInformation.FileName,
8729 ASSERT( lCount >= 0);
8740 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8741 OUT UNICODE_STRING *ComponentName)
8744 NTSTATUS ntStatus = STATUS_SUCCESS;
8745 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8747 uniFullPathName = *FullPathName;
8752 FsRtlDissectName( uniFullPathName,
8756 if( uniRemainingPath.Length == 0)
8761 uniFullPathName = uniRemainingPath;
8764 if( uniComponentName.Length > 0)
8766 *ComponentName = uniComponentName;
8773 AFSDumpTraceFiles_Default()
8779 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8782 BOOLEAN bIsValidName = TRUE;
8788 while( usIndex < FileName->Length/sizeof( WCHAR))
8791 if( FileName->Buffer[ usIndex] == L':' ||
8792 FileName->Buffer[ usIndex] == L'*' ||
8793 FileName->Buffer[ usIndex] == L'?' ||
8794 FileName->Buffer[ usIndex] == L'"' ||
8795 FileName->Buffer[ usIndex] == L'<' ||
8796 FileName->Buffer[ usIndex] == L'>')
8798 bIsValidName = FALSE;
8806 return bIsValidName;
8810 AFSCreateDefaultSecurityDescriptor()
8813 NTSTATUS ntStatus = STATUS_SUCCESS;
8815 ULONG ulSACLSize = 0;
8816 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8817 ULONG ulACESize = 0;
8818 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8819 ULONG ulSDLength = 0;
8820 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8821 PSID pWorldSID = NULL;
8822 ULONG *pulSubAuthority = NULL;
8823 ULONG ulWorldSIDLEngth = 0;
8828 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8830 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8832 AFS_GENERIC_MEMORY_29_TAG);
8834 if( pWorldSID == NULL)
8836 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8838 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8841 RtlZeroMemory( pWorldSID,
8844 RtlInitializeSid( pWorldSID,
8845 &SeWorldSidAuthority,
8848 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8849 *pulSubAuthority = SECURITY_WORLD_RID;
8851 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8854 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8859 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8861 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8863 AFS_GENERIC_MEMORY_29_TAG);
8868 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8870 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8873 RtlZeroMemory( pACE,
8876 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8877 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8878 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8879 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8881 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8883 SeExports->SeLowMandatorySid);
8885 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8886 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8888 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8890 AFS_GENERIC_MEMORY_29_TAG);
8895 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8897 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8900 ntStatus = RtlCreateAcl( pSACL,
8904 if( !NT_SUCCESS( ntStatus))
8907 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8910 try_return( ntStatus);
8913 ntStatus = RtlAddAce( pSACL,
8917 pACE->Header.AceSize);
8919 if( !NT_SUCCESS( ntStatus))
8922 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8925 try_return( ntStatus);
8929 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8930 sizeof( SECURITY_DESCRIPTOR),
8931 AFS_GENERIC_MEMORY_27_TAG);
8933 if( pSecurityDescr == NULL)
8936 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8938 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8941 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8942 SECURITY_DESCRIPTOR_REVISION);
8944 if( !NT_SUCCESS( ntStatus))
8947 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8950 try_return( ntStatus);
8953 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8955 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8960 if( !NT_SUCCESS( ntStatus))
8963 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8966 try_return( ntStatus);
8971 // Add in the group and owner to the SD
8974 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8976 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8980 if( !NT_SUCCESS( ntStatus))
8983 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8986 try_return( ntStatus);
8990 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8994 if( !NT_SUCCESS( ntStatus))
8997 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
9000 try_return( ntStatus);
9003 if( !RtlValidSecurityDescriptor( pSecurityDescr))
9006 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
9008 try_return( ntStatus = STATUS_INVALID_PARAMETER);
9011 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)AFSLibExAllocatePoolWithTag( NonPagedPool,
9013 AFS_GENERIC_MEMORY_27_TAG);
9015 if( pRelativeSecurityDescr == NULL)
9018 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9020 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9023 ulSDLength = PAGE_SIZE;
9025 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
9026 pRelativeSecurityDescr,
9029 if( !NT_SUCCESS( ntStatus))
9032 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
9035 try_return( ntStatus);
9038 AFSDefaultSD = pRelativeSecurityDescr;
9042 if( !NT_SUCCESS( ntStatus))
9045 if( pRelativeSecurityDescr != NULL)
9048 AFSLibExFreePoolWithTag( pRelativeSecurityDescr,
9049 AFS_GENERIC_MEMORY_27_TAG);
9053 if( pSecurityDescr != NULL)
9056 AFSLibExFreePoolWithTag( pSecurityDescr,
9057 AFS_GENERIC_MEMORY_27_TAG);
9063 AFSLibExFreePoolWithTag( pSACL,
9064 AFS_GENERIC_MEMORY_29_TAG);
9070 AFSLibExFreePoolWithTag( pACE,
9071 AFS_GENERIC_MEMORY_29_TAG);
9074 if( pWorldSID != NULL)
9077 AFSLibExFreePoolWithTag( pWorldSID,
9078 AFS_GENERIC_MEMORY_29_TAG);
9086 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
9087 OUT UNICODE_STRING *ParentPath)
9090 *ParentPath = *FullFileName;
9093 // If the final character is a \, jump over it
9096 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
9098 ParentPath->Length -= sizeof( WCHAR);
9101 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
9103 ParentPath->Length -= sizeof( WCHAR);
9107 // And the separator
9110 ParentPath->Length -= sizeof( WCHAR);
9116 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
9117 IN AFSObjectInfoCB *ObjectInfo,
9118 IN BOOLEAN WriteAccess,
9119 OUT GUID *AuthGroup)
9122 NTSTATUS ntStatus = STATUS_SUCCESS;
9123 GUID stAuthGroup, stZeroAuthGroup;
9124 BOOLEAN bFoundAuthGroup = FALSE;
9125 AFSCcb *pCcb = NULL;
9131 RtlZeroMemory( &stAuthGroup,
9134 RtlZeroMemory( &stZeroAuthGroup,
9140 if( ObjectInfo != NULL &&
9141 ObjectInfo->Fcb != NULL)
9143 pFcb = ObjectInfo->Fcb;
9150 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
9153 pCcb = Fcb->CcbListHead;
9155 while( pCcb != NULL)
9159 pCcb->GrantedAccess & FILE_WRITE_DATA)
9161 RtlCopyMemory( &stAuthGroup,
9165 bFoundAuthGroup = TRUE;
9169 else if( pCcb->GrantedAccess & FILE_READ_DATA)
9172 // At least get the read-only access
9175 RtlCopyMemory( &stAuthGroup,
9179 bFoundAuthGroup = TRUE;
9182 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9185 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9188 if( !bFoundAuthGroup)
9191 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9192 (ULONGLONG)PsGetCurrentThreadId(),
9195 if( RtlCompareMemory( &stZeroAuthGroup,
9197 sizeof( GUID)) == sizeof( GUID))
9200 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9202 try_return( ntStatus = STATUS_ACCESS_DENIED);
9206 RtlCopyMemory( AuthGroup,
9219 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9220 IN ULONG InvalidateReason)
9223 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
9224 NTSTATUS ntStatus = STATUS_SUCCESS;
9230 switch( InvalidateReason)
9233 case AFS_INVALIDATE_DELETED:
9236 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
9237 AFS_TRACE_LEVEL_VERBOSE,
9238 "AFSPerformObjectInvalidation on node type %d for FID %08lX-%08lX-%08lX-%08lX Reason DELETED\n",
9239 ObjectInfo->FileType,
9240 ObjectInfo->FileId.Cell,
9241 ObjectInfo->FileId.Volume,
9242 ObjectInfo->FileId.Vnode,
9243 ObjectInfo->FileId.Unique));
9245 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9246 ObjectInfo->Fcb != NULL)
9249 if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
9252 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9255 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9257 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9262 // Clear out the extents
9263 // And get rid of them (note this involves waiting
9264 // for any writes or reads to the cache to complete)
9267 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9270 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9274 ObjectInfo->Links = 0;
9279 case AFS_INVALIDATE_DATA_VERSION:
9282 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9283 ObjectInfo->Fcb != NULL)
9286 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
9287 AFS_TRACE_LEVEL_VERBOSE,
9288 "AFSPerformObjectInvalidation on node type %d for FID %08lX-%08lX-%08lX-%08lX Reason DATA_VERSION FCB %0p\n",
9289 ObjectInfo->FileType,
9290 ObjectInfo->FileId.Cell,
9291 ObjectInfo->FileId.Volume,
9292 ObjectInfo->FileId.Vnode,
9293 ObjectInfo->FileId.Unique,
9296 if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
9299 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9300 AFS_TRACE_LEVEL_VERBOSE,
9301 "AFSPerformObjectInvalidate Acquiring Fcb lock %p EXCL %08lX\n",
9302 &ObjectInfo->Fcb->NPFcb->Resource,
9303 PsGetCurrentThread()));
9305 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9308 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9309 AFS_TRACE_LEVEL_VERBOSE,
9310 "AFSPerformObjectInvalidation DirectIO Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9311 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9312 PsGetCurrentThread()));
9314 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9320 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9321 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9327 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9328 AFS_TRACE_LEVEL_WARNING,
9329 "AFSPerformObjectInvalidation DirectIO CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9330 ObjectInfo->FileId.Cell,
9331 ObjectInfo->FileId.Volume,
9332 ObjectInfo->FileId.Vnode,
9333 ObjectInfo->FileId.Unique));
9335 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9338 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9341 ntStatus = GetExceptionCode();
9345 "EXCEPTION - AFSPerformObjectInvalidation DirectIO FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9346 ObjectInfo->FileId.Cell,
9347 ObjectInfo->FileId.Volume,
9348 ObjectInfo->FileId.Vnode,
9349 ObjectInfo->FileId.Unique,
9352 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9355 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9356 AFS_TRACE_LEVEL_VERBOSE,
9357 "AFSPerformObjectInvalidation DirectIO Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9358 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9359 PsGetCurrentThread()));
9361 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9363 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9364 AFS_TRACE_LEVEL_VERBOSE,
9365 "AFSPerformObjectInvalidation DirectIO Releasing Fcb lock %p EXCL %08lX\n",
9366 &ObjectInfo->Fcb->NPFcb->Resource,
9367 PsGetCurrentThread()));
9369 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9375 ULONG ulProcessCount = 0;
9377 LARGE_INTEGER liCurrentOffset = {0,0};
9378 LARGE_INTEGER liFlushLength = {0,0};
9379 ULONG ulFlushLength = 0;
9380 BOOLEAN bLocked = FALSE;
9381 BOOLEAN bExtentsLocked = FALSE;
9382 BOOLEAN bCleanExtents = FALSE;
9384 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9385 AFS_TRACE_LEVEL_VERBOSE,
9386 "AFSPerformObjectInvalidate Acquiring Fcb lock %p EXCL %08lX\n",
9387 &ObjectInfo->Fcb->NPFcb->Resource,
9388 PsGetCurrentThread()));
9390 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9395 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9396 AFS_TRACE_LEVEL_VERBOSE,
9397 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9398 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9399 PsGetCurrentThread()));
9401 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9404 bExtentsLocked = TRUE;
9407 // There are several possibilities here:
9409 // 0. If there are no extents or all of the extents are dirty, do nothing.
9411 // 1. There could be nothing dirty and an open reference count of zero
9412 // in which case we can just tear down all of the extents without
9413 // holding any resources.
9415 // 2. There could be nothing dirty and a non-zero open reference count
9416 // in which case we can issue a CcPurge against the entire file
9417 // while holding just the Fcb Resource.
9419 // 3. There can be dirty extents in which case we need to identify
9420 // the non-dirty ranges and then perform a CcPurge on just the
9421 // non-dirty ranges while holding just the Fcb Resource.
9424 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9427 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9430 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9432 bExtentsLocked = FALSE;
9434 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9437 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9441 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9447 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9448 AFS_TRACE_LEVEL_VERBOSE,
9449 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9450 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9451 PsGetCurrentThread()));
9453 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9459 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9460 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9466 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9467 AFS_TRACE_LEVEL_WARNING,
9468 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9469 ObjectInfo->FileId.Cell,
9470 ObjectInfo->FileId.Volume,
9471 ObjectInfo->FileId.Vnode,
9472 ObjectInfo->FileId.Unique));
9474 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9479 bCleanExtents = TRUE;
9482 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9485 ntStatus = GetExceptionCode();
9489 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9490 ObjectInfo->FileId.Cell,
9491 ObjectInfo->FileId.Volume,
9492 ObjectInfo->FileId.Vnode,
9493 ObjectInfo->FileId.Unique,
9496 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9499 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9500 AFS_TRACE_LEVEL_VERBOSE,
9501 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9502 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9503 PsGetCurrentThread()));
9505 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9507 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9515 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9517 bExtentsLocked = FALSE;
9519 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9520 AFS_TRACE_LEVEL_VERBOSE,
9521 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9522 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9523 PsGetCurrentThread()));
9525 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9529 // Must build a list of non-dirty ranges from the beginning of the file
9530 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9531 // ranges. In all but the most extreme random data write scenario there will
9532 // be significantly fewer.
9534 // For each range we need offset and size.
9537 AFSByteRange * ByteRangeList = NULL;
9538 ULONG ulByteRangeCount = 0;
9540 BOOLEAN bPurgeOnClose = FALSE;
9545 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9548 if ( ByteRangeList != NULL ||
9549 ulByteRangeCount == 0)
9552 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9559 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9561 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9562 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9563 &ByteRangeList[ulIndex].FileOffset,
9568 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9569 AFS_TRACE_LEVEL_WARNING,
9570 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9571 ObjectInfo->FileId.Cell,
9572 ObjectInfo->FileId.Volume,
9573 ObjectInfo->FileId.Vnode,
9574 ObjectInfo->FileId.Unique));
9576 bPurgeOnClose = TRUE;
9581 bCleanExtents = TRUE;
9584 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9586 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9588 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9595 // We couldn't allocate the memory to build the purge list
9596 // so just walk the extent list while holding the ExtentsList Resource.
9597 // This could deadlock but we do not have much choice.
9600 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9602 bExtentsLocked = TRUE;
9604 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9608 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9612 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9614 while( ulProcessCount < ulCount)
9616 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9618 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9620 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9621 &pEntry->FileOffset,
9626 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9627 AFS_TRACE_LEVEL_WARNING,
9628 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9629 ObjectInfo->FileId.Cell,
9630 ObjectInfo->FileId.Volume,
9631 ObjectInfo->FileId.Vnode,
9632 ObjectInfo->FileId.Unique));
9634 bPurgeOnClose = TRUE;
9639 bCleanExtents = TRUE;
9643 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9646 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9648 while( liFlushLength.QuadPart > 0)
9651 if( liFlushLength.QuadPart > 512 * 1024000)
9653 ulFlushLength = 512 * 1024000;
9657 ulFlushLength = liFlushLength.LowPart;
9660 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9666 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9667 AFS_TRACE_LEVEL_WARNING,
9668 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9669 ObjectInfo->FileId.Cell,
9670 ObjectInfo->FileId.Volume,
9671 ObjectInfo->FileId.Vnode,
9672 ObjectInfo->FileId.Unique));
9674 bPurgeOnClose = TRUE;
9679 bCleanExtents = TRUE;
9682 liFlushLength.QuadPart -= ulFlushLength;
9686 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9694 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9700 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9701 AFS_TRACE_LEVEL_WARNING,
9702 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9703 ObjectInfo->FileId.Cell,
9704 ObjectInfo->FileId.Volume,
9705 ObjectInfo->FileId.Vnode,
9706 ObjectInfo->FileId.Unique));
9708 bPurgeOnClose = TRUE;
9713 bCleanExtents = TRUE;
9720 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9724 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9727 ntStatus = GetExceptionCode();
9731 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9732 ObjectInfo->FileId.Cell,
9733 ObjectInfo->FileId.Volume,
9734 ObjectInfo->FileId.Vnode,
9735 ObjectInfo->FileId.Unique,
9739 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9740 AFS_TRACE_LEVEL_VERBOSE,
9741 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9742 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9743 PsGetCurrentThread()));
9745 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9747 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9753 if ( bExtentsLocked)
9756 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9762 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9768 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9779 // Destroy the reference passed in by the caller to AFSInvalidateObject
9780 // or AFSQueueInvalidateObject
9783 AFSAcquireShared( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
9786 lCount = AFSObjectInfoDecrement( ObjectInfo,
9787 AFS_OBJECT_REFERENCE_INVALIDATION);
9789 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9790 AFS_TRACE_LEVEL_VERBOSE,
9791 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",
9795 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
9802 AFSIgnoreReparsePointToFile( void)
9804 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
9805 BOOLEAN bIgnoreReparsePoint;
9809 bIgnoreReparsePoint = BooleanFlagOn( pDeviceExt->Specific.RDR.ReparsePointPolicy,
9810 AFS_REPARSE_POINT_TO_FILE_AS_FILE);
9813 return bIgnoreReparsePoint;