2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2012, 2013 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
16 * nor the names of their contributors may be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission from Kernel Drivers, LLC and Your File System, Inc.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 // File: AFSGeneric.cpp
37 #include "AFSCommon.h"
40 // Function: AFSExceptionFilter
44 // This function is the exception handler
48 // A status is returned for the function
52 AFSExceptionFilter( IN CHAR *FunctionString,
54 IN PEXCEPTION_POINTERS ExceptPtrs)
57 UNREFERENCED_PARAMETER(Code);
58 PEXCEPTION_RECORD ExceptRec;
64 ExceptRec = ExceptPtrs->ExceptionRecord;
66 Context = ExceptPtrs->ContextRecord;
70 "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
74 ExceptRec->ExceptionCode,
75 ExceptRec->ExceptionAddress,
76 (void *)AFSExceptionFilter));
78 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
80 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
81 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
83 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
85 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
88 KeBugCheck( (ULONG)-2);
96 __except( EXCEPTION_EXECUTE_HANDLER)
102 return EXCEPTION_EXECUTE_HANDLER;
106 // Function: AFSLibExAllocatePoolWithTag()
108 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
109 // is configured on, then bugcheck the system if
110 // a memory allocation fails. The routine should be
111 // used for all memory allocations that are to be freed
112 // when the library is unloaded. Memory allocations that
113 // are to survive library unload and reload should be
114 // performed using AFSExAllocatePoolWithTag() which is
115 // provided by the AFS Framework.
118 // POOL_TYPE PoolType - Paged or NonPaged
119 // SIZE_T NumberOfBytes - requested allocation size
120 // ULONG Tag - Pool Allocation Tag to be applied for tracking
123 // void * - the memory allocation
127 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
128 IN SIZE_T NumberOfBytes,
132 void *pBuffer = NULL;
134 pBuffer = ExAllocatePoolWithTag( PoolType,
141 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
144 KeBugCheck( (ULONG)-2);
151 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
155 PsGetCurrentThread()));
165 // Function: AFSAcquireExcl()
167 // Purpose: Called to acquire a resource exclusive with optional wait
170 // PERESOURCE Resource - Resource to acquire
171 // BOOLEAN Wait - Whether to block
174 // BOOLEAN - Whether the mask was acquired
178 AFSAcquireExcl( IN PERESOURCE Resource,
182 BOOLEAN bStatus = FALSE;
185 // Normal kernel APCs must be disabled before calling
186 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
189 KeEnterCriticalRegion();
191 bStatus = ExAcquireResourceExclusiveLite( Resource,
197 KeLeaveCriticalRegion();
204 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
208 BOOLEAN bStatus = FALSE;
210 KeEnterCriticalRegion();
212 bStatus = ExAcquireSharedStarveExclusive( Resource,
218 KeLeaveCriticalRegion();
225 // Function: AFSAcquireShared()
227 // Purpose: Called to acquire a resource shared with optional wait
230 // PERESOURCE Resource - Resource to acquire
231 // BOOLEAN Wait - Whether to block
234 // BOOLEAN - Whether the mask was acquired
238 AFSAcquireShared( IN PERESOURCE Resource,
242 BOOLEAN bStatus = FALSE;
244 KeEnterCriticalRegion();
246 bStatus = ExAcquireResourceSharedLite( Resource,
252 KeLeaveCriticalRegion();
259 // Function: AFSReleaseResource()
261 // Purpose: Called to release a resource
264 // PERESOURCE Resource - Resource to release
271 AFSReleaseResource( IN PERESOURCE Resource)
274 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
275 AFS_TRACE_LEVEL_VERBOSE,
276 "AFSReleaseResource Releasing lock %p Thread %08lX\n",
278 PsGetCurrentThread()));
280 ExReleaseResourceLite( Resource);
282 KeLeaveCriticalRegion();
288 AFSConvertToShared( IN PERESOURCE Resource)
291 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
292 AFS_TRACE_LEVEL_VERBOSE,
293 "AFSConvertToShared Converting lock %p Thread %08lX\n",
295 PsGetCurrentThread()));
297 ExConvertExclusiveToSharedLite( Resource);
303 // Function: AFSCompleteRequest
307 // This function completes irps
311 // A status is returned for the function
315 AFSCompleteRequest( IN PIRP Irp,
319 Irp->IoStatus.Status = Status;
321 IoCompleteRequest( Irp,
328 // Function: AFSGenerateCRC
332 // Given a device and filename this function generates a CRC
336 // A status is returned for the function
340 AFSGenerateCRC( IN PUNICODE_STRING FileName,
341 IN BOOLEAN UpperCaseName)
345 NTSTATUS ntStatus = STATUS_SUCCESS;
347 ntStatus = RtlHashUnicodeString( FileName,
349 HASH_STRING_ALGORITHM_DEFAULT,
352 if( !NT_SUCCESS( ntStatus))
361 AFSLockSystemBuffer( IN PIRP Irp,
365 void *pAddress = NULL;
367 if( Irp->MdlAddress != NULL)
370 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
373 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
376 pAddress = Irp->AssociatedIrp.SystemBuffer;
378 else if( Irp->UserBuffer != NULL)
381 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
387 if( Irp->MdlAddress != NULL)
391 // Lock the new Mdl in memory.
396 PIO_STACK_LOCATION pIoStack;
397 pIoStack = IoGetCurrentIrpStackLocation( Irp);
400 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
401 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
403 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
406 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
409 AFSDumpTraceFilesFnc();
411 IoFreeMdl( Irp->MdlAddress );
412 Irp->MdlAddress = NULL;
422 AFSLockUserBuffer( IN void *UserBuffer,
423 IN ULONG BufferLength,
427 NTSTATUS ntStatus = STATUS_SUCCESS;
428 void *pAddress = NULL;
434 pMdl = IoAllocateMdl( UserBuffer,
443 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
447 // Lock the new Mdl in memory.
453 MmProbeAndLockPages( pMdl,
457 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
460 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
463 AFSDumpTraceFilesFnc();
485 AFSMapToService( IN PIRP Irp,
489 NTSTATUS ntStatus = STATUS_SUCCESS;
490 void *pMappedBuffer = NULL;
491 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
497 if( pDevExt->Specific.Control.ServiceProcess == NULL)
500 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
503 if( Irp->MdlAddress == NULL)
506 if( AFSLockSystemBuffer( Irp,
510 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
515 // Attach to the service process for mapping
518 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
519 (PRKAPC_STATE)&stApcState);
521 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
528 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
535 return pMappedBuffer;
539 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
543 NTSTATUS ntStatus = STATUS_SUCCESS;
544 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
550 if( pDevExt->Specific.Control.ServiceProcess == NULL)
553 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
560 // Attach to the service process for mapping
563 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
564 (PRKAPC_STATE)&stApcState);
566 MmUnmapLockedPages( MappedBuffer,
569 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
581 AFSInitializeLibraryDevice()
584 NTSTATUS ntStatus = STATUS_SUCCESS;
585 AFSDeviceExt *pDeviceExt = NULL;
590 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
593 // The PIOCtl file name
596 RtlInitUnicodeString( &AFSPIOCtlName,
597 AFS_PIOCTL_FILE_INTERFACE_NAME);
600 // And the global root share name
603 RtlInitUnicodeString( &AFSGlobalRootName,
604 AFS_GLOBAL_ROOT_SHARE_NAME);
612 AFSRemoveLibraryDevice()
615 NTSTATUS ntStatus = STATUS_SUCCESS;
626 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
630 UNREFERENCED_PARAMETER(DeviceObject);
631 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
633 AFSCompleteRequest( Irp,
640 AFSInitializeGlobalDirectoryEntries()
643 NTSTATUS ntStatus = STATUS_SUCCESS;
644 AFSDirectoryCB *pDirNode = NULL;
645 ULONG ulEntryLength = 0;
646 AFSObjectInfoCB *pObjectInfoCB = NULL;
647 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
654 // Initialize the global . entry
657 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
660 if( pObjectInfoCB == NULL)
663 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
664 AFS_TRACE_LEVEL_ERROR,
665 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
668 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
671 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
672 AFS_OBJECT_REFERENCE_GLOBAL);
674 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
675 AFS_TRACE_LEVEL_VERBOSE,
676 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
680 ntStatus = STATUS_SUCCESS;
682 ulEntryLength = sizeof( AFSDirectoryCB) +
685 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
689 if( pDirNode == NULL)
692 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
693 AFS_OBJECT_REFERENCE_GLOBAL);
695 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
696 AFS_TRACE_LEVEL_VERBOSE,
697 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
704 AFSDeleteObjectInfo( &pObjectInfoCB);
707 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
708 AFS_TRACE_LEVEL_ERROR,
709 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n"));
711 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
714 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
715 AFS_TRACE_LEVEL_VERBOSE,
716 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocated %p\n",
719 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
720 sizeof( AFSNonPagedDirectoryCB),
721 AFS_DIR_ENTRY_NP_TAG);
723 if( pNonPagedDirEntry == NULL)
726 AFSLibExFreePoolWithTag( pDirNode,
729 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
730 AFS_OBJECT_REFERENCE_GLOBAL);
732 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
733 AFS_TRACE_LEVEL_VERBOSE,
734 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
741 AFSDeleteObjectInfo( &pObjectInfoCB);
744 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
745 AFS_TRACE_LEVEL_ERROR,
746 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n"));
748 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
751 RtlZeroMemory( pDirNode,
754 RtlZeroMemory( pNonPagedDirEntry,
755 sizeof( AFSNonPagedDirectoryCB));
757 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
759 pDirNode->NonPaged = pNonPagedDirEntry;
761 pDirNode->ObjectInformation = pObjectInfoCB;
767 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
769 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
772 // Setup the names in the entry
775 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
777 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
779 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
781 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
784 // Populate the rest of the data
787 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
789 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
791 AFSGlobalDotDirEntry = pDirNode;
797 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
800 if( pObjectInfoCB == NULL)
803 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
804 AFS_TRACE_LEVEL_ERROR,
805 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
808 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
811 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
812 AFS_OBJECT_REFERENCE_GLOBAL);
814 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
815 AFS_TRACE_LEVEL_VERBOSE,
816 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
820 ntStatus = STATUS_SUCCESS;
822 ulEntryLength = sizeof( AFSDirectoryCB) +
823 ( 2 * sizeof( WCHAR));
825 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
829 if( pDirNode == NULL)
832 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
833 AFS_TRACE_LEVEL_ERROR,
834 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocation failure\n"));
836 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
837 AFS_OBJECT_REFERENCE_GLOBAL);
839 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
840 AFS_TRACE_LEVEL_VERBOSE,
841 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
848 AFSDeleteObjectInfo( &pObjectInfoCB);
851 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
854 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
855 AFS_TRACE_LEVEL_VERBOSE,
856 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocated %p\n",
859 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
860 sizeof( AFSNonPagedDirectoryCB),
861 AFS_DIR_ENTRY_NP_TAG);
863 if( pNonPagedDirEntry == NULL)
866 AFSLibExFreePoolWithTag( pDirNode,
869 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
870 AFS_OBJECT_REFERENCE_GLOBAL);
872 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
873 AFS_TRACE_LEVEL_VERBOSE,
874 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
881 AFSDeleteObjectInfo( &pObjectInfoCB);
884 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
887 RtlZeroMemory( pDirNode,
890 RtlZeroMemory( pNonPagedDirEntry,
891 sizeof( AFSNonPagedDirectoryCB));
893 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
895 pDirNode->NonPaged = pNonPagedDirEntry;
897 pDirNode->ObjectInformation = pObjectInfoCB;
903 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
905 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
908 // Setup the names in the entry
911 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
913 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
915 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
917 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
919 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
922 // Populate the rest of the data
925 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
927 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
929 AFSGlobalDotDotDirEntry = pDirNode;
933 if( !NT_SUCCESS( ntStatus))
936 if( AFSGlobalDotDirEntry != NULL)
939 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
940 AFS_OBJECT_REFERENCE_GLOBAL);
942 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
943 AFS_TRACE_LEVEL_VERBOSE,
944 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
945 AFSGlobalDotDirEntry->ObjectInformation,
951 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
954 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
956 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry->NonPaged,
957 AFS_DIR_ENTRY_NP_TAG);
959 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry,
962 AFSGlobalDotDirEntry = NULL;
965 if( AFSGlobalDotDotDirEntry != NULL)
968 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
969 AFS_OBJECT_REFERENCE_GLOBAL);
971 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
972 AFS_TRACE_LEVEL_VERBOSE,
973 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
974 AFSGlobalDotDotDirEntry->ObjectInformation,
980 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
983 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
985 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry->NonPaged,
986 AFS_DIR_ENTRY_NP_TAG);
988 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry,
991 AFSGlobalDotDotDirEntry = NULL;
1000 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
1001 IN PUNICODE_STRING FileName,
1002 IN PUNICODE_STRING TargetName,
1003 IN AFSDirEnumEntry *DirEnumEntry,
1007 AFSDirectoryCB *pDirNode = NULL;
1008 NTSTATUS ntStatus = STATUS_SUCCESS;
1009 ULONG ulEntryLength = 0;
1010 AFSObjectInfoCB *pObjectInfoCB = NULL;
1011 ULONGLONG ullIndex = 0;
1012 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
1018 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1019 AFS_TRACE_LEVEL_VERBOSE,
1020 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
1022 ParentObjectInfo->FileId.Cell,
1023 ParentObjectInfo->FileId.Volume,
1024 ParentObjectInfo->FileId.Vnode,
1025 ParentObjectInfo->FileId.Unique));
1028 // First thing is to locate/create our object information block
1032 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
1035 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
1037 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
1039 (AFSBTreeEntry **)&pObjectInfoCB);
1041 if( !NT_SUCCESS( ntStatus))
1045 // Allocate our object info cb
1048 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
1051 if( pObjectInfoCB == NULL)
1054 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1056 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1059 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1060 AFS_TRACE_LEVEL_VERBOSE,
1061 "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
1067 // If we allocated the object information cb then set the information
1070 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1072 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1074 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1076 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1078 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1079 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1082 pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1085 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
1088 if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1091 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1096 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1101 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1102 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1106 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1107 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1108 pObjectInfoCB->TargetFileId.Unique == 0 &&
1109 (TargetName == NULL || TargetName->Length == 0))
1113 // This will ensure we perform a validation on the node
1116 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1119 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1122 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1125 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1128 if ( BooleanFlagOn( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY))
1131 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1133 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1135 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1137 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1139 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1141 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1143 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1145 pObjectInfoCB->Links = DirEnumEntry->Links;
1147 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1149 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1151 ClearFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1155 // This reference count is either stored into the return DirectoryCB
1156 // or released before function exit.
1159 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
1160 AFS_OBJECT_REFERENCE_DIRENTRY);
1162 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1163 AFS_TRACE_LEVEL_VERBOSE,
1164 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
1168 KeQueryTickCount( &pObjectInfoCB->LastAccessCount);
1170 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1172 ntStatus = STATUS_SUCCESS;
1174 ulEntryLength = sizeof( AFSDirectoryCB) +
1177 if( TargetName != NULL)
1180 ulEntryLength += TargetName->Length;
1183 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1187 if( pDirNode == NULL)
1190 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1193 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1194 AFS_TRACE_LEVEL_VERBOSE,
1195 "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
1198 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1199 sizeof( AFSNonPagedDirectoryCB),
1200 AFS_DIR_ENTRY_NP_TAG);
1202 if( pNonPagedDirEntry == NULL)
1205 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1208 RtlZeroMemory( pDirNode,
1211 RtlZeroMemory( pNonPagedDirEntry,
1212 sizeof( AFSNonPagedDirectoryCB));
1214 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1216 pDirNode->NonPaged = pNonPagedDirEntry;
1218 pDirNode->ObjectInformation = pObjectInfoCB;
1221 // Set valid entry and NOT_IN_PARENT flag
1224 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1226 pDirNode->FileIndex = FileIndex;
1229 // Setup the names in the entry
1232 if( FileName->Length > 0)
1235 pDirNode->NameInformation.FileName.Length = FileName->Length;
1237 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1239 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1241 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1243 pDirNode->NameInformation.FileName.Length);
1246 // Create a CRC for the file
1249 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1252 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1256 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1257 AFS_TRACE_LEVEL_VERBOSE,
1258 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1261 ParentObjectInfo->FileId.Cell,
1262 ParentObjectInfo->FileId.Volume,
1263 ParentObjectInfo->FileId.Vnode,
1264 ParentObjectInfo->FileId.Unique));
1266 if( TargetName != NULL &&
1267 TargetName->Length > 0)
1270 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1272 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1274 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1275 sizeof( AFSDirectoryCB) +
1276 pDirNode->NameInformation.FileName.Length);
1278 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1280 pDirNode->NameInformation.TargetName.Length);
1286 if( !NT_SUCCESS( ntStatus))
1289 if( pNonPagedDirEntry != NULL)
1292 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1294 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1297 if( pDirNode != NULL)
1300 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1301 AFS_TRACE_LEVEL_VERBOSE,
1302 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1305 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1311 // Dereference our object info block if we have one
1314 if( pObjectInfoCB != NULL)
1317 AFSAcquireShared( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
1320 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1321 AFS_OBJECT_REFERENCE_DIRENTRY);
1323 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1324 AFS_TRACE_LEVEL_VERBOSE,
1325 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1329 AFSReleaseResource( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
1338 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1339 IN BOOLEAN DirectoryEntry)
1342 BOOLEAN bReturn = TRUE;
1343 ACCESS_MASK stAccessMask = 0;
1346 // Get rid of anything we don't know about
1349 DesiredAccess = (DesiredAccess &
1355 ACCESS_SYSTEM_SECURITY |
1359 FILE_READ_ATTRIBUTES |
1360 FILE_WRITE_ATTRIBUTES |
1361 FILE_LIST_DIRECTORY |
1367 // Our 'read only' access mask. These are the accesses we will
1368 // allow for a read only file
1371 stAccessMask = DELETE |
1376 ACCESS_SYSTEM_SECURITY |
1380 FILE_READ_ATTRIBUTES |
1381 FILE_WRITE_ATTRIBUTES |
1383 FILE_LIST_DIRECTORY |
1387 // For a directory, add in the directory specific accesses
1393 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1398 if( FlagOn( DesiredAccess, ~stAccessMask))
1402 // A write access is set ...
1412 AFSEvaluateNode( IN GUID *AuthGroup,
1413 IN AFSDirectoryCB *DirEntry)
1416 NTSTATUS ntStatus = STATUS_SUCCESS;
1417 AFSDirEnumEntry *pDirEntry = NULL;
1418 UNICODE_STRING uniTargetName;
1423 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1428 if( !NT_SUCCESS( ntStatus))
1431 try_return( ntStatus);
1434 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1436 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1438 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1440 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1442 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1444 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1446 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1448 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1450 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1452 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1454 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1456 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1457 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1460 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1463 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1466 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1469 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1474 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1478 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1480 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1483 // If we have a target name then see if it needs updating ...
1486 if( pDirEntry->TargetNameLength > 0)
1490 // Update the target name information if needed
1493 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1495 uniTargetName.MaximumLength = uniTargetName.Length;
1497 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1499 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1502 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1503 RtlCompareUnicodeString( &uniTargetName,
1504 &DirEntry->NameInformation.TargetName,
1509 // Update the target name
1512 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1514 uniTargetName.Buffer,
1515 uniTargetName.Length);
1517 if( !NT_SUCCESS( ntStatus))
1520 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1522 try_return( ntStatus);
1526 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1531 if( pDirEntry != NULL)
1534 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1542 AFSValidateSymLink( IN GUID *AuthGroup,
1543 IN AFSDirectoryCB *DirEntry)
1546 NTSTATUS ntStatus = STATUS_SUCCESS;
1547 AFSDirEnumEntry *pDirEntry = NULL;
1548 UNICODE_STRING uniTargetName;
1553 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1558 if( !NT_SUCCESS( ntStatus))
1561 try_return( ntStatus);
1564 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1565 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1568 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1569 AFS_TRACE_LEVEL_VERBOSE_2,
1570 "AFSValidateSymLink Invalid type Status %08lX\n",
1571 STATUS_OBJECT_NAME_NOT_FOUND));
1573 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1576 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1578 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1580 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1583 // Update the target name information if needed
1586 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1588 uniTargetName.MaximumLength = uniTargetName.Length;
1590 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1592 if( uniTargetName.Length > 0)
1595 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1598 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1599 RtlCompareUnicodeString( &uniTargetName,
1600 &DirEntry->NameInformation.TargetName,
1605 // Update the target name
1608 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1610 uniTargetName.Buffer,
1611 uniTargetName.Length);
1613 if( !NT_SUCCESS( ntStatus))
1616 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1618 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1622 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1626 // If the FileType is the same then nothing to do since it IS
1630 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1633 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1635 try_return( ntStatus = STATUS_SUCCESS);
1638 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1640 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1642 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1644 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1646 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1648 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1650 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1652 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1654 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1655 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1658 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1661 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1664 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1667 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1672 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1676 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1678 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1682 if( pDirEntry != NULL)
1685 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1693 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1697 NTSTATUS ntStatus = STATUS_SUCCESS;
1698 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1699 IO_STATUS_BLOCK stIoStatus;
1701 AFSObjectInfoCB * pParentObjectInfo = NULL;
1703 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1704 AFS_TRACE_LEVEL_VERBOSE,
1705 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1706 (*ppObjectInfo)->FileType,
1707 (*ppObjectInfo)->FileId.Cell,
1708 (*ppObjectInfo)->FileId.Volume,
1709 (*ppObjectInfo)->FileId.Vnode,
1710 (*ppObjectInfo)->FileId.Unique,
1713 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1716 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1717 &(*ppObjectInfo)->ParentFileId,
1721 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1722 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1723 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1726 // We only act on the mount point itself, not the target. If the
1727 // node has been deleted then mark it as such otherwise indicate
1728 // it requires verification
1731 if( Reason == AFS_INVALIDATE_DELETED)
1733 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1738 if( Reason == AFS_INVALIDATE_FLUSHED)
1741 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1743 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1746 (*ppObjectInfo)->Expiration.QuadPart = 0;
1748 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1750 (*ppObjectInfo)->TargetFileId.Unique = 0;
1752 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1753 AFS_TRACE_LEVEL_VERBOSE,
1754 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1755 (*ppObjectInfo)->FileId.Cell,
1756 (*ppObjectInfo)->FileId.Volume,
1757 (*ppObjectInfo)->FileId.Vnode,
1758 (*ppObjectInfo)->FileId.Unique));
1760 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1763 if ( pParentObjectInfo != NULL)
1766 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1768 if( Reason == AFS_INVALIDATE_CREDS)
1770 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1773 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1774 Reason == AFS_INVALIDATE_FLUSHED)
1776 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1780 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1783 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1786 FILE_ACTION_MODIFIED);
1789 try_return( ntStatus);
1793 // Depending on the reason for invalidation then perform work on the node
1799 case AFS_INVALIDATE_DELETED:
1803 // Mark this node as invalid
1806 (*ppObjectInfo)->Links = 0;
1808 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1810 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1811 AFS_TRACE_LEVEL_VERBOSE,
1812 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1813 (*ppObjectInfo)->FileId.Cell,
1814 (*ppObjectInfo)->FileId.Volume,
1815 (*ppObjectInfo)->FileId.Vnode,
1816 (*ppObjectInfo)->FileId.Unique));
1818 if( pParentObjectInfo != NULL)
1821 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1822 AFS_TRACE_LEVEL_VERBOSE,
1823 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1824 pParentObjectInfo->FileId.Cell,
1825 pParentObjectInfo->FileId.Volume,
1826 pParentObjectInfo->FileId.Vnode,
1827 pParentObjectInfo->FileId.Unique));
1829 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1831 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1833 pParentObjectInfo->Expiration.QuadPart = 0;
1835 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1837 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1841 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1844 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1847 FILE_ACTION_REMOVED);
1850 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1853 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1859 case AFS_INVALIDATE_FLUSHED:
1862 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1863 (*ppObjectInfo)->Fcb != NULL)
1866 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1867 AFS_TRACE_LEVEL_VERBOSE,
1868 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1869 (*ppObjectInfo)->FileId.Cell,
1870 (*ppObjectInfo)->FileId.Volume,
1871 (*ppObjectInfo)->FileId.Vnode,
1872 (*ppObjectInfo)->FileId.Unique));
1874 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1875 AFS_TRACE_LEVEL_VERBOSE,
1876 "AFSInvalidateObject Flush/purge Acquiring Fcb lock %p EXCL %08lX\n",
1877 &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1878 PsGetCurrentThread()));
1880 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1883 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1884 AFS_TRACE_LEVEL_VERBOSE,
1885 "AFSInvalidateObject Flush/purge Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
1886 &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1887 PsGetCurrentThread()));
1889 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1895 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1900 if( !NT_SUCCESS( stIoStatus.Status))
1903 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1904 AFS_TRACE_LEVEL_ERROR,
1905 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1906 (*ppObjectInfo)->FileId.Cell,
1907 (*ppObjectInfo)->FileId.Volume,
1908 (*ppObjectInfo)->FileId.Vnode,
1909 (*ppObjectInfo)->FileId.Unique,
1911 stIoStatus.Information));
1913 ntStatus = stIoStatus.Status;
1917 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1920 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1926 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1927 AFS_TRACE_LEVEL_WARNING,
1928 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1929 (*ppObjectInfo)->FileId.Cell,
1930 (*ppObjectInfo)->FileId.Volume,
1931 (*ppObjectInfo)->FileId.Vnode,
1932 (*ppObjectInfo)->FileId.Unique));
1934 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1938 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
1941 ntStatus = GetExceptionCode();
1945 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1946 (*ppObjectInfo)->FileId.Cell,
1947 (*ppObjectInfo)->FileId.Volume,
1948 (*ppObjectInfo)->FileId.Vnode,
1949 (*ppObjectInfo)->FileId.Unique,
1952 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1955 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1956 AFS_TRACE_LEVEL_VERBOSE,
1957 "AFSInvalidateObject Flush/purge Releasing Fcb SectionObject lock %p EXCL %08lX\n",
1958 &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1959 PsGetCurrentThread()));
1961 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1963 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1964 AFS_TRACE_LEVEL_VERBOSE,
1965 "AFSInvalidateObject Flush/purge Releasing Fcb lock %p EXCL %08lX\n",
1966 &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1967 PsGetCurrentThread()));
1969 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->Resource);
1971 if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
1975 // Clear out the extents
1976 // Get rid of them (note this involves waiting
1977 // for any writes or reads to the cache to complete)
1980 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1985 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1988 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1991 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1992 AFS_TRACE_LEVEL_VERBOSE,
1993 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1994 (*ppObjectInfo)->FileId.Cell,
1995 (*ppObjectInfo)->FileId.Volume,
1996 (*ppObjectInfo)->FileId.Vnode,
1997 (*ppObjectInfo)->FileId.Unique));
1999 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2002 // Fall through to the default processing
2008 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
2010 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2014 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2017 if( Reason == AFS_INVALIDATE_CREDS)
2019 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2022 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2024 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2028 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2031 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
2034 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
2037 FILE_ACTION_MODIFIED);
2039 else if ( pParentObjectInfo != NULL)
2042 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2045 FILE_ACTION_MODIFIED);
2049 // Indicate this node requires re-evaluation for the remaining reasons
2052 (*ppObjectInfo)->Expiration.QuadPart = 0;
2054 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2055 AFS_TRACE_LEVEL_VERBOSE,
2056 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2057 (*ppObjectInfo)->FileId.Cell,
2058 (*ppObjectInfo)->FileId.Volume,
2059 (*ppObjectInfo)->FileId.Vnode,
2060 (*ppObjectInfo)->FileId.Unique));
2062 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
2064 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2065 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
2066 ( Reason == AFS_INVALIDATE_CALLBACK ||
2067 Reason == AFS_INVALIDATE_EXPIRED))
2069 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
2070 AFS_INVALIDATE_DATA_VERSION)))
2073 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
2083 if ( pParentObjectInfo != NULL)
2086 AFSReleaseObjectInfo( &pParentObjectInfo);
2093 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
2096 NTSTATUS ntStatus = STATUS_SUCCESS;
2097 AFSVolumeCB *pVolumeCB = NULL;
2098 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2099 ULONGLONG ullIndex = 0;
2100 AFSObjectInfoCB *pObjectInfo = NULL;
2106 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2107 AFS_TRACE_LEVEL_VERBOSE,
2108 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
2109 InvalidateCB->FileID.Cell,
2110 InvalidateCB->FileID.Volume,
2111 InvalidateCB->FileID.Vnode,
2112 InvalidateCB->FileID.Unique,
2113 InvalidateCB->FileType,
2114 InvalidateCB->WholeVolume,
2115 InvalidateCB->Reason));
2118 // Need to locate the Fcb for the directory to purge
2121 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2122 AFS_TRACE_LEVEL_VERBOSE,
2123 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2124 &pDevExt->Specific.RDR.VolumeTreeLock,
2125 PsGetCurrentThread()));
2128 // Starve any exclusive waiters on this paticular call
2131 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2134 // Locate the volume node
2137 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2139 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2141 (AFSBTreeEntry **)&pVolumeCB);
2143 if( pVolumeCB != NULL)
2146 lCount = AFSVolumeIncrement( pVolumeCB,
2147 AFS_VOLUME_REFERENCE_INVALIDATE);
2149 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2150 AFS_TRACE_LEVEL_VERBOSE,
2151 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2156 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2158 if( !NT_SUCCESS( ntStatus) ||
2162 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2163 AFS_TRACE_LEVEL_WARNING,
2164 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2165 InvalidateCB->FileID.Cell,
2166 InvalidateCB->FileID.Volume,
2167 InvalidateCB->FileID.Vnode,
2168 InvalidateCB->FileID.Unique,
2171 try_return( ntStatus = STATUS_SUCCESS);
2175 // If this is a whole volume invalidation then go do it now
2178 if( InvalidateCB->WholeVolume)
2181 ntStatus = AFSInvalidateVolume( pVolumeCB,
2182 InvalidateCB->Reason);
2184 try_return( ntStatus);
2187 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
2190 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2193 pObjectInfo = &pVolumeCB->ObjectInformation;
2198 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2200 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2202 (AFSBTreeEntry **)&pObjectInfo);
2205 if( pObjectInfo != NULL)
2209 // Reference the node so it won't be torn down
2212 lCount = AFSObjectInfoIncrement( pObjectInfo,
2213 AFS_OBJECT_REFERENCE_INVALIDATION);
2215 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2216 AFS_TRACE_LEVEL_VERBOSE,
2217 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2222 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2224 if( !NT_SUCCESS( ntStatus) ||
2225 pObjectInfo == NULL)
2228 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2229 AFS_TRACE_LEVEL_VERBOSE,
2230 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2231 InvalidateCB->FileID.Cell,
2232 InvalidateCB->FileID.Volume,
2233 InvalidateCB->FileID.Vnode,
2234 InvalidateCB->FileID.Unique,
2237 try_return( ntStatus = STATUS_SUCCESS);
2240 AFSInvalidateObject( &pObjectInfo,
2241 InvalidateCB->Reason);
2245 if( pObjectInfo != NULL)
2248 lCount = AFSObjectInfoDecrement( pObjectInfo,
2249 AFS_OBJECT_REFERENCE_INVALIDATION);
2251 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2252 AFS_TRACE_LEVEL_VERBOSE,
2253 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2258 if ( pVolumeCB != NULL)
2261 lCount = AFSVolumeDecrement( pVolumeCB,
2262 AFS_VOLUME_REFERENCE_INVALIDATE);
2264 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2265 AFS_TRACE_LEVEL_VERBOSE,
2266 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2276 AFSIsChildOfParent( IN AFSFcb *Dcb,
2280 BOOLEAN bIsChild = FALSE;
2281 AFSFcb *pCurrentFcb = Fcb;
2282 AFSObjectInfoCB * pParentObjectInfo = NULL;
2284 while( pCurrentFcb != NULL)
2287 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2288 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2296 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2297 &pCurrentFcb->ObjectInformation->ParentFileId,
2300 if ( pParentObjectInfo != NULL)
2303 pCurrentFcb = pParentObjectInfo->Fcb;
2305 AFSReleaseObjectInfo( &pParentObjectInfo);
2319 AFSCreateHighIndex( IN AFSFileID *FileID)
2322 ULONGLONG ullIndex = 0;
2324 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2331 AFSCreateLowIndex( IN AFSFileID *FileID)
2334 ULONGLONG ullIndex = 0;
2336 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2342 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2343 IN ACCESS_MASK GrantedAccess,
2344 IN BOOLEAN DirectoryEntry)
2347 BOOLEAN bAccessGranted = TRUE;
2350 // Check if we are asking for read/write and granted only read only
2351 // NOTE: There will be more checks here
2354 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2356 AFSCheckForReadOnlyAccess( GrantedAccess,
2360 bAccessGranted = FALSE;
2363 return bAccessGranted;
2367 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2370 NTSTATUS ntStatus = STATUS_SUCCESS;
2371 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2377 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2379 if( AFSGlobalRoot == NULL)
2386 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2389 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2396 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2403 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2404 IN UNICODE_STRING *SubstituteName,
2405 IN ULONG StringIndex)
2408 NTSTATUS ntStatus = STATUS_SUCCESS;
2409 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2410 AFSSysNameCB *pSysName = NULL;
2411 ERESOURCE *pSysNameLock = NULL;
2414 UNICODE_STRING uniSysName;
2421 if( IoIs32bitProcess( NULL))
2424 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2426 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2431 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2433 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2437 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2439 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2443 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2444 AFS_TRACE_LEVEL_VERBOSE,
2445 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2447 PsGetCurrentThread()));
2449 AFSAcquireShared( pSysNameLock,
2453 // Find where we are in the list
2456 while( pSysName != NULL &&
2457 ulIndex < StringIndex)
2460 pSysName = pSysName->fLink;
2465 if( pSysName == NULL)
2468 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2469 AFS_TRACE_LEVEL_VERBOSE_2,
2470 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2472 STATUS_OBJECT_NAME_NOT_FOUND));
2474 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2477 RtlInitUnicodeString( &uniSysName,
2480 // If it is a full component of @SYS then just substitue the
2484 if( RtlCompareUnicodeString( &uniSysName,
2489 SubstituteName->Length = pSysName->SysName.Length;
2490 SubstituteName->MaximumLength = SubstituteName->Length;
2492 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2493 SubstituteName->Length,
2494 AFS_SUBST_BUFFER_TAG);
2496 if( SubstituteName->Buffer == NULL)
2499 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2502 RtlCopyMemory( SubstituteName->Buffer,
2503 pSysName->SysName.Buffer,
2504 pSysName->SysName.Length);
2511 while( ComponentName->Buffer[ usIndex] != L'@')
2517 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2518 SubstituteName->MaximumLength = SubstituteName->Length;
2520 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2521 SubstituteName->Length,
2522 AFS_SUBST_BUFFER_TAG);
2524 if( SubstituteName->Buffer == NULL)
2527 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2530 RtlCopyMemory( SubstituteName->Buffer,
2531 ComponentName->Buffer,
2532 usIndex * sizeof( WCHAR));
2534 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2535 pSysName->SysName.Buffer,
2536 pSysName->SysName.Length);
2541 AFSReleaseResource( pSysNameLock);
2548 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2549 IN OUT UNICODE_STRING *ComponentName,
2550 IN UNICODE_STRING *SubstituteName,
2551 IN OUT UNICODE_STRING *RemainingPath,
2552 IN BOOLEAN FreePathName)
2555 NTSTATUS ntStatus = STATUS_SUCCESS;
2556 UNICODE_STRING uniPathName;
2557 USHORT usPrefixNameLen = 0;
2558 SHORT sNameLenDelta = 0;
2564 // If the passed in name can handle the additional length
2565 // then just moves things around
2568 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2570 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2572 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2575 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2578 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2579 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2580 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2583 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2584 SubstituteName->Buffer,
2585 SubstituteName->Length);
2587 FullPathName->Length += sNameLenDelta;
2589 ComponentName->Length += sNameLenDelta;
2591 ComponentName->MaximumLength = ComponentName->Length;
2593 if ( RemainingPath->Buffer)
2596 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2599 try_return( ntStatus);
2603 // Need to re-allocate the buffer
2606 uniPathName.Length = FullPathName->Length -
2607 ComponentName->Length +
2608 SubstituteName->Length;
2610 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2612 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2613 uniPathName.MaximumLength,
2614 AFS_NAME_BUFFER_FOUR_TAG);
2616 if( uniPathName.Buffer == NULL)
2619 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2622 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2624 usPrefixNameLen *= sizeof( WCHAR);
2626 RtlZeroMemory( uniPathName.Buffer,
2627 uniPathName.MaximumLength);
2629 RtlCopyMemory( uniPathName.Buffer,
2630 FullPathName->Buffer,
2633 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2634 SubstituteName->Buffer,
2635 SubstituteName->Length);
2637 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2640 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2641 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2642 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2645 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2647 ComponentName->Length += sNameLenDelta;
2649 ComponentName->MaximumLength = ComponentName->Length;
2651 if ( RemainingPath->Buffer)
2654 RemainingPath->Buffer = uniPathName.Buffer
2655 + (RemainingPath->Buffer - FullPathName->Buffer)
2656 + sNameLenDelta/sizeof( WCHAR);
2661 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2664 *FullPathName = uniPathName;
2675 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2679 NTSTATUS ntStatus = STATUS_SUCCESS;
2680 AFSObjectInfoCB *pCurrentObject = NULL;
2681 AFSObjectInfoCB *pNextObject = NULL;
2687 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2688 AFS_TRACE_LEVEL_VERBOSE,
2689 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2690 VolumeCB->ObjectInformation.FileId.Cell,
2691 VolumeCB->ObjectInformation.FileId.Volume,
2692 VolumeCB->ObjectInformation.FileId.Vnode,
2693 VolumeCB->ObjectInformation.FileId.Unique,
2697 // Depending on the reason for invalidation then perform work on the node
2703 case AFS_INVALIDATE_DELETED:
2707 // Mark this volume as invalid
2710 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2712 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2718 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2722 // Invalidate the volume root directory
2725 pCurrentObject = &VolumeCB->ObjectInformation;
2727 if ( pCurrentObject )
2730 lCount = AFSObjectInfoIncrement( pCurrentObject,
2731 AFS_OBJECT_REFERENCE_INVALIDATION);
2733 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2734 AFS_TRACE_LEVEL_VERBOSE,
2735 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2739 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2741 AFSInvalidateObject( &pCurrentObject,
2744 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2747 if ( pCurrentObject)
2750 lCount = AFSObjectInfoDecrement( pCurrentObject,
2751 AFS_OBJECT_REFERENCE_INVALIDATION);
2753 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2754 AFS_TRACE_LEVEL_VERBOSE,
2755 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2762 // Apply invalidation to all other volume objects
2765 pCurrentObject = VolumeCB->ObjectInfoListHead;
2767 if ( pCurrentObject)
2771 // Reference the node so it won't be torn down
2774 lCount = AFSObjectInfoIncrement( pCurrentObject,
2775 AFS_OBJECT_REFERENCE_INVALIDATION);
2777 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2778 AFS_TRACE_LEVEL_VERBOSE,
2779 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2784 while( pCurrentObject != NULL)
2787 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2793 // Reference the node so it won't be torn down
2796 lCount = AFSObjectInfoIncrement( pNextObject,
2797 AFS_OBJECT_REFERENCE_INVALIDATION);
2799 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2800 AFS_TRACE_LEVEL_VERBOSE,
2801 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2806 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2808 AFSInvalidateObject( &pCurrentObject,
2811 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2814 if ( pCurrentObject )
2817 lCount = AFSObjectInfoDecrement( pCurrentObject,
2818 AFS_OBJECT_REFERENCE_INVALIDATION);
2820 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2821 AFS_TRACE_LEVEL_VERBOSE,
2822 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2827 pCurrentObject = pNextObject;
2830 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2837 AFSInvalidateAllVolumes( VOID)
2839 AFSVolumeCB *pVolumeCB = NULL;
2840 AFSVolumeCB *pNextVolumeCB = NULL;
2841 AFSDeviceExt *pRDRDeviceExt = NULL;
2844 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2846 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2847 AFS_TRACE_LEVEL_VERBOSE,
2848 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2849 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2850 PsGetCurrentThread()));
2852 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2855 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2860 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2861 AFS_TRACE_LEVEL_VERBOSE,
2862 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2863 pVolumeCB->ObjectInfoTree.TreeLock,
2864 PsGetCurrentThread()));
2866 lCount = AFSVolumeIncrement( pVolumeCB,
2867 AFS_VOLUME_REFERENCE_INVALIDATE);
2869 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2870 AFS_TRACE_LEVEL_VERBOSE,
2871 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2876 while( pVolumeCB != NULL)
2879 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2884 lCount = AFSVolumeIncrement( pNextVolumeCB,
2885 AFS_VOLUME_REFERENCE_INVALIDATE);
2887 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2888 AFS_TRACE_LEVEL_VERBOSE,
2889 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2894 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2896 // do I need to hold the volume lock here?
2898 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2900 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2903 lCount = AFSVolumeDecrement( pVolumeCB,
2904 AFS_VOLUME_REFERENCE_INVALIDATE);
2906 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2907 AFS_TRACE_LEVEL_VERBOSE,
2908 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2912 pVolumeCB = pNextVolumeCB;
2915 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2919 AFSVerifyEntry( IN GUID *AuthGroup,
2920 IN AFSDirectoryCB *DirEntry,
2921 IN BOOLEAN bFollowMountPoint)
2924 NTSTATUS ntStatus = STATUS_SUCCESS;
2925 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2926 AFSDirEnumEntry *pDirEnumEntry = NULL;
2927 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2928 IO_STATUS_BLOCK stIoStatus;
2933 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2934 AFS_TRACE_LEVEL_VERBOSE_2,
2935 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2936 &DirEntry->NameInformation.FileName,
2937 pObjectInfo->FileId.Cell,
2938 pObjectInfo->FileId.Volume,
2939 pObjectInfo->FileId.Vnode,
2940 pObjectInfo->FileId.Unique));
2942 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2944 bFollowMountPoint ? FALSE : TRUE,
2947 if( !NT_SUCCESS( ntStatus))
2950 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2951 AFS_TRACE_LEVEL_ERROR,
2952 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2953 &DirEntry->NameInformation.FileName,
2954 pObjectInfo->FileId.Cell,
2955 pObjectInfo->FileId.Volume,
2956 pObjectInfo->FileId.Vnode,
2957 pObjectInfo->FileId.Unique,
2960 try_return( ntStatus);
2964 // Check the data version of the file
2967 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2968 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2971 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2972 AFS_TRACE_LEVEL_VERBOSE,
2973 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2974 pObjectInfo->DataVersion.QuadPart,
2975 &DirEntry->NameInformation.FileName,
2976 pObjectInfo->FileId.Cell,
2977 pObjectInfo->FileId.Volume,
2978 pObjectInfo->FileId.Vnode,
2979 pObjectInfo->FileId.Unique));
2982 // We are ok, just get out
2985 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2987 try_return( ntStatus = STATUS_SUCCESS);
2991 // New data version so we will need to process the node based on the type
2994 switch( pDirEnumEntry->FileType)
2997 case AFS_FILE_TYPE_MOUNTPOINT:
3001 // For a mount point we need to ensure the target is the same
3004 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
3005 &pDirEnumEntry->TargetFileId))
3011 // Update the metadata for the entry
3014 ntStatus = AFSUpdateMetaData( DirEntry,
3017 if( NT_SUCCESS( ntStatus))
3020 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3026 case AFS_FILE_TYPE_SYMLINK:
3030 // Update the metadata for the entry
3033 ntStatus = AFSUpdateMetaData( DirEntry,
3036 if( NT_SUCCESS( ntStatus))
3039 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3045 case AFS_FILE_TYPE_FILE:
3047 FILE_OBJECT * pCCFileObject = NULL;
3049 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3052 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3053 AFS_TRACE_LEVEL_VERBOSE,
3054 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3055 &DirEntry->NameInformation.FileName,
3056 pObjectInfo->FileId.Cell,
3057 pObjectInfo->FileId.Volume,
3058 pObjectInfo->FileId.Vnode,
3059 pObjectInfo->FileId.Unique));
3061 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3064 if( pObjectInfo->Fcb != NULL)
3067 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3068 AFS_TRACE_LEVEL_VERBOSE,
3069 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3070 &DirEntry->NameInformation.FileName,
3071 pObjectInfo->FileId.Cell,
3072 pObjectInfo->FileId.Volume,
3073 pObjectInfo->FileId.Vnode,
3074 pObjectInfo->FileId.Unique));
3076 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3077 AFS_TRACE_LEVEL_VERBOSE,
3078 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3079 &pObjectInfo->Fcb->NPFcb->Resource,
3080 PsGetCurrentThread()));
3082 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3085 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3086 AFS_TRACE_LEVEL_VERBOSE,
3087 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3088 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3089 PsGetCurrentThread()));
3091 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3097 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3102 if( !NT_SUCCESS( stIoStatus.Status))
3105 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3106 AFS_TRACE_LEVEL_ERROR,
3107 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3108 &DirEntry->NameInformation.FileName,
3109 pObjectInfo->FileId.Cell,
3110 pObjectInfo->FileId.Volume,
3111 pObjectInfo->FileId.Vnode,
3112 pObjectInfo->FileId.Unique,
3114 stIoStatus.Information));
3116 ntStatus = stIoStatus.Status;
3119 if ( pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3122 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3128 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3129 AFS_TRACE_LEVEL_WARNING,
3130 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3131 &DirEntry->NameInformation.FileName,
3132 pObjectInfo->FileId.Cell,
3133 pObjectInfo->FileId.Volume,
3134 pObjectInfo->FileId.Vnode,
3135 pObjectInfo->FileId.Unique));
3137 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3141 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3143 ntStatus = GetExceptionCode();
3147 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3148 &DirEntry->NameInformation.FileName,
3149 pObjectInfo->FileId.Cell,
3150 pObjectInfo->FileId.Volume,
3151 pObjectInfo->FileId.Vnode,
3152 pObjectInfo->FileId.Unique,
3155 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3158 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3159 AFS_TRACE_LEVEL_VERBOSE,
3160 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3161 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3162 PsGetCurrentThread()));
3164 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3166 if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
3169 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3170 AFS_TRACE_LEVEL_VERBOSE,
3171 "AFSVerifyEntry Releasing Fcb lock %p EXCL %08lX\n",
3172 &pObjectInfo->Fcb->NPFcb->Resource,
3173 PsGetCurrentThread()));
3175 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3177 AFSFlushExtents( pObjectInfo->Fcb,
3181 // Acquire the Fcb to purge the cache
3184 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3185 AFS_TRACE_LEVEL_VERBOSE,
3186 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3187 &pObjectInfo->Fcb->NPFcb->Resource,
3188 PsGetCurrentThread()));
3190 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3195 // Update the metadata for the entry
3198 ntStatus = AFSUpdateMetaData( DirEntry,
3201 if( !NT_SUCCESS( ntStatus))
3204 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3205 AFS_TRACE_LEVEL_ERROR,
3206 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3207 &DirEntry->NameInformation.FileName,
3208 pObjectInfo->FileId.Cell,
3209 pObjectInfo->FileId.Volume,
3210 pObjectInfo->FileId.Vnode,
3211 pObjectInfo->FileId.Unique,
3218 // Update file sizes
3221 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3222 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3223 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3225 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3226 AFS_TRACE_LEVEL_VERBOSE,
3227 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3228 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3229 PsGetCurrentThread()));
3231 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3237 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3239 if ( pCCFileObject != NULL)
3241 CcSetFileSizes( pCCFileObject,
3242 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3245 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3248 ntStatus = GetExceptionCode();
3252 "EXCEPTION - AFSVerifyEntry CcSetFileSized failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3253 pObjectInfo->FileId.Cell,
3254 pObjectInfo->FileId.Volume,
3255 pObjectInfo->FileId.Vnode,
3256 pObjectInfo->FileId.Unique,
3260 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3261 AFS_TRACE_LEVEL_VERBOSE,
3262 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3263 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3264 PsGetCurrentThread()));
3266 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3269 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3270 AFS_TRACE_LEVEL_VERBOSE,
3271 "AFSVerifyEntry Releasing Fcb lock %p EXCL %08lX\n",
3272 &pObjectInfo->Fcb->NPFcb->Resource,
3273 PsGetCurrentThread()));
3275 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3281 // Update the metadata for the entry
3284 ntStatus = AFSUpdateMetaData( DirEntry,
3287 if( !NT_SUCCESS( ntStatus))
3290 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3291 AFS_TRACE_LEVEL_ERROR,
3292 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3293 &DirEntry->NameInformation.FileName,
3294 pObjectInfo->FileId.Cell,
3295 pObjectInfo->FileId.Volume,
3296 pObjectInfo->FileId.Vnode,
3297 pObjectInfo->FileId.Unique,
3303 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3304 AFS_TRACE_LEVEL_WARNING,
3305 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3306 &DirEntry->NameInformation.FileName,
3307 pObjectInfo->FileId.Cell,
3308 pObjectInfo->FileId.Volume,
3309 pObjectInfo->FileId.Vnode,
3310 pObjectInfo->FileId.Unique));
3314 if ( NT_SUCCESS( ntStatus))
3317 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3322 case AFS_FILE_TYPE_DIRECTORY:
3326 // For a directory or root entry flush the content of
3327 // the directory enumeration.
3330 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3333 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3334 AFS_TRACE_LEVEL_VERBOSE_2,
3335 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3336 &DirEntry->NameInformation.FileName,
3337 pObjectInfo->FileId.Cell,
3338 pObjectInfo->FileId.Volume,
3339 pObjectInfo->FileId.Vnode,
3340 pObjectInfo->FileId.Unique));
3342 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3345 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3348 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3350 if ( !NT_SUCCESS( ntStatus))
3353 try_return( ntStatus);
3358 // Update the metadata for the entry
3361 ntStatus = AFSUpdateMetaData( DirEntry,
3364 if( NT_SUCCESS( ntStatus))
3367 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3373 case AFS_FILE_TYPE_DFSLINK:
3376 UNICODE_STRING uniTargetName;
3379 // For a DFS link need to check the target name has not changed
3382 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3384 uniTargetName.MaximumLength = uniTargetName.Length;
3386 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3388 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3391 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3392 RtlCompareUnicodeString( &uniTargetName,
3393 &DirEntry->NameInformation.TargetName,
3398 // Update the target name
3401 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3403 uniTargetName.Buffer,
3404 uniTargetName.Length);
3406 if( !NT_SUCCESS( ntStatus))
3409 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3415 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3418 // Update the metadata for the entry
3421 ntStatus = AFSUpdateMetaData( DirEntry,
3424 if( NT_SUCCESS( ntStatus))
3427 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3435 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3436 AFS_TRACE_LEVEL_WARNING,
3437 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3438 pObjectInfo->FileType,
3439 &DirEntry->NameInformation.FileName,
3440 pObjectInfo->FileId.Cell,
3441 pObjectInfo->FileId.Volume,
3442 pObjectInfo->FileId.Vnode,
3443 pObjectInfo->FileId.Unique));
3450 if( pDirEnumEntry != NULL)
3453 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3461 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3464 NTSTATUS ntStatus = STATUS_SUCCESS;
3465 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3466 ULONGLONG ullIndex = 0;
3467 AFSVolumeCB *pVolumeCB = NULL;
3473 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3474 AFS_TRACE_LEVEL_VERBOSE,
3475 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3476 VolumeStatus->Online,
3477 VolumeStatus->FileID.Cell,
3478 VolumeStatus->FileID.Volume));
3481 // Need to locate the Fcb for the directory to purge
3484 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3485 AFS_TRACE_LEVEL_VERBOSE,
3486 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3487 &pDevExt->Specific.RDR.VolumeTreeLock,
3488 PsGetCurrentThread()));
3490 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3493 // Locate the volume node
3496 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3498 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3500 (AFSBTreeEntry **)&pVolumeCB);
3502 if( pVolumeCB != NULL)
3505 lCount = AFSVolumeIncrement( pVolumeCB,
3506 AFS_VOLUME_REFERENCE_INVALIDATE);
3508 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3509 AFS_TRACE_LEVEL_VERBOSE,
3510 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3514 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3517 // Set the volume state accordingly
3520 if( VolumeStatus->Online)
3523 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3528 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3537 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3540 NTSTATUS ntStatus = STATUS_SUCCESS;
3545 if( AFSGlobalRoot == NULL)
3548 try_return( ntStatus);
3551 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3555 // Set the network state according to the information
3558 if( NetworkStatus->Online)
3561 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3566 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3569 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3580 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3584 NTSTATUS ntStatus = STATUS_SUCCESS;
3585 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3586 BOOLEAN bAcquiredLock = FALSE;
3587 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3592 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3593 AFS_TRACE_LEVEL_VERBOSE,
3594 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3595 ObjectInfo->FileId.Cell,
3596 ObjectInfo->FileId.Volume,
3597 ObjectInfo->FileId.Vnode,
3598 ObjectInfo->FileId.Unique));
3600 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3603 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3604 AFS_TRACE_LEVEL_VERBOSE,
3605 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3606 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3607 PsGetCurrentThread()));
3609 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3612 bAcquiredLock = TRUE;
3616 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3619 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3620 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3623 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3624 AFS_TRACE_LEVEL_ERROR,
3625 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3626 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3627 ObjectInfo->FileId.Cell,
3628 ObjectInfo->FileId.Volume,
3629 ObjectInfo->FileId.Vnode,
3630 ObjectInfo->FileId.Unique));
3634 // Reset the directory list information by clearing all valid entries
3637 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3639 while( pCurrentDirEntry != NULL)
3642 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3644 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3648 // If this entry has been deleted then process it here
3651 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3652 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3653 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3656 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3657 AFS_TRACE_LEVEL_VERBOSE,
3658 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3660 &pCurrentDirEntry->NameInformation.FileName));
3662 AFSDeleteDirEntry( ObjectInfo,
3668 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3670 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3671 AFS_TRACE_LEVEL_VERBOSE,
3672 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3674 pCurrentDirEntry->DirOpenReferenceCount));
3677 // We pull the short name from the parent tree since it could change below
3680 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3683 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3684 AFS_TRACE_LEVEL_VERBOSE,
3685 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3687 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3688 &pCurrentDirEntry->NameInformation.FileName));
3690 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3693 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3698 pCurrentDirEntry = pNextDirEntry;
3702 // Reget the directory contents
3705 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3708 if ( !NT_SUCCESS( ntStatus))
3710 try_return( ntStatus);
3714 // Now start again and tear down any entries not valid
3717 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3719 while( pCurrentDirEntry != NULL)
3722 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3724 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3727 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3728 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3729 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3732 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3735 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3737 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3738 AFS_TRACE_LEVEL_VERBOSE,
3739 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3741 &pCurrentDirEntry->NameInformation.FileName));
3743 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3748 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3751 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3752 AFS_TRACE_LEVEL_VERBOSE,
3753 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3755 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3756 &pCurrentDirEntry->NameInformation.FileName));
3760 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3762 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3763 AFS_TRACE_LEVEL_VERBOSE,
3764 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3766 &pCurrentDirEntry->NameInformation.FileName));
3771 pCurrentDirEntry = pNextDirEntry;
3776 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3777 AFS_TRACE_LEVEL_VERBOSE,
3778 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3780 pCurrentDirEntry->DirOpenReferenceCount));
3782 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3783 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3786 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3787 AFS_TRACE_LEVEL_VERBOSE,
3788 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3789 &pCurrentDirEntry->NameInformation.FileName,
3790 ObjectInfo->FileId.Cell,
3791 ObjectInfo->FileId.Volume,
3792 ObjectInfo->FileId.Vnode,
3793 ObjectInfo->FileId.Unique));
3795 AFSDeleteDirEntry( ObjectInfo,
3801 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3802 AFS_TRACE_LEVEL_VERBOSE,
3803 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3805 &pCurrentDirEntry->NameInformation.FileName,
3806 ObjectInfo->FileId.Cell,
3807 ObjectInfo->FileId.Volume,
3808 ObjectInfo->FileId.Vnode,
3809 ObjectInfo->FileId.Unique));
3811 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3813 AFSRemoveNameEntry( ObjectInfo,
3817 pCurrentDirEntry = pNextDirEntry;
3821 if( !AFSValidateDirList( ObjectInfo))
3824 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3833 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3841 AFSIsVolumeFID( IN AFSFileID *FileID)
3844 BOOLEAN bIsVolume = FALSE;
3846 if( FileID->Vnode == 1 &&
3847 FileID->Unique == 1)
3857 AFSIsFinalNode( IN AFSFcb *Fcb)
3860 BOOLEAN bIsFinalNode = FALSE;
3862 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3863 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3864 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3865 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3866 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3869 bIsFinalNode = TRUE;
3874 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3875 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3878 return bIsFinalNode;
3882 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3883 IN AFSDirEnumEntry *DirEnumEntry)
3886 NTSTATUS ntStatus = STATUS_SUCCESS;
3887 UNICODE_STRING uniTargetName;
3888 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3893 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3895 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3897 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3899 pObjectInfo->FileType = DirEnumEntry->FileType;
3901 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3903 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3905 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3907 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3909 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3911 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3913 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3915 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3916 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3919 pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3922 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
3925 if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
3928 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3933 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3937 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3939 pObjectInfo->Links = DirEnumEntry->Links;
3941 if( DirEnumEntry->TargetNameLength > 0 &&
3942 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3943 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3947 // Update the target name information if needed
3950 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3952 uniTargetName.MaximumLength = uniTargetName.Length;
3954 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3956 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3959 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3960 RtlCompareUnicodeString( &uniTargetName,
3961 &DirEntry->NameInformation.TargetName,
3966 // Update the target name
3969 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3971 uniTargetName.Buffer,
3972 uniTargetName.Length);
3974 if( !NT_SUCCESS( ntStatus))
3977 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3979 try_return( ntStatus);
3983 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3985 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
3986 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
3989 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3992 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3993 DirEntry->NameInformation.TargetName.Buffer != NULL)
3995 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
3998 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4000 DirEntry->NameInformation.TargetName.Length = 0;
4001 DirEntry->NameInformation.TargetName.MaximumLength = 0;
4002 DirEntry->NameInformation.TargetName.Buffer = NULL;
4004 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4016 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
4018 IN BOOLEAN FastCall,
4019 IN BOOLEAN bSafeToPurge)
4022 NTSTATUS ntStatus = STATUS_SUCCESS;
4023 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4024 LARGE_INTEGER liSystemTime;
4025 AFSDirEnumEntry *pDirEnumEntry = NULL;
4026 AFSFcb *pCurrentFcb = NULL;
4027 BOOLEAN bReleaseFcb = FALSE;
4028 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
4034 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
4038 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4039 AFS_TRACE_LEVEL_VERBOSE_2,
4040 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
4041 &DirEntry->NameInformation.FileName,
4042 pObjectInfo->FileId.Cell,
4043 pObjectInfo->FileId.Volume,
4044 pObjectInfo->FileId.Vnode,
4045 pObjectInfo->FileId.Unique,
4049 // If this is a fake node then bail since the service knows nothing about it
4052 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
4055 try_return( ntStatus);
4059 // This routine ensures that the current entry is valid by:
4061 // 1) Checking that the expiration time is non-zero and after where we
4065 KeQuerySystemTime( &liSystemTime);
4067 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
4068 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
4069 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
4070 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
4073 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4074 AFS_TRACE_LEVEL_VERBOSE_2,
4075 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
4076 &DirEntry->NameInformation.FileName,
4077 pObjectInfo->FileId.Cell,
4078 pObjectInfo->FileId.Volume,
4079 pObjectInfo->FileId.Vnode,
4080 pObjectInfo->FileId.Unique));
4082 try_return( ntStatus);
4086 // This node requires updating
4089 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
4094 if( !NT_SUCCESS( ntStatus))
4097 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4098 AFS_TRACE_LEVEL_ERROR,
4099 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4101 &DirEntry->NameInformation.FileName,
4102 pObjectInfo->FileId.Cell,
4103 pObjectInfo->FileId.Volume,
4104 pObjectInfo->FileId.Vnode,
4105 pObjectInfo->FileId.Unique,
4109 // Failed validation of node so return access-denied
4112 try_return( ntStatus);
4115 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4116 AFS_TRACE_LEVEL_VERBOSE,
4117 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
4119 &DirEntry->NameInformation.FileName,
4120 pObjectInfo->FileId.Cell,
4121 pObjectInfo->FileId.Volume,
4122 pObjectInfo->FileId.Vnode,
4123 pObjectInfo->FileId.Unique,
4124 pObjectInfo->DataVersion.QuadPart,
4125 pDirEnumEntry->DataVersion.QuadPart,
4126 pDirEnumEntry->FileType));
4130 // Based on the file type, process the node
4133 switch( pDirEnumEntry->FileType)
4136 case AFS_FILE_TYPE_MOUNTPOINT:
4140 // Update the metadata for the entry
4143 ntStatus = AFSUpdateMetaData( DirEntry,
4146 if( NT_SUCCESS( ntStatus))
4149 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4155 case AFS_FILE_TYPE_SYMLINK:
4156 case AFS_FILE_TYPE_DFSLINK:
4160 // Update the metadata for the entry
4163 ntStatus = AFSUpdateMetaData( DirEntry,
4166 if( NT_SUCCESS( ntStatus))
4169 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4175 case AFS_FILE_TYPE_FILE:
4178 BOOLEAN bPurgeExtents = FALSE;
4181 // For a file where the data version has become invalid we need to
4182 // fail any current extent requests and purge the cache for the file
4183 // Can't hold the Fcb resource while doing this
4186 if( pObjectInfo->Fcb != NULL &&
4187 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4188 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4191 pCurrentFcb = pObjectInfo->Fcb;
4193 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4196 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4197 AFS_TRACE_LEVEL_VERBOSE,
4198 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4199 &pCurrentFcb->NPFcb->Resource,
4200 PsGetCurrentThread()));
4202 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4208 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4209 AFS_TRACE_LEVEL_VERBOSE_2,
4210 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4211 &DirEntry->NameInformation.FileName,
4212 pObjectInfo->FileId.Cell,
4213 pObjectInfo->FileId.Volume,
4214 pObjectInfo->FileId.Vnode,
4215 pObjectInfo->FileId.Unique));
4217 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4220 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4221 AFS_TRACE_LEVEL_VERBOSE,
4222 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4223 &DirEntry->NameInformation.FileName,
4224 pObjectInfo->FileId.Cell,
4225 pObjectInfo->FileId.Volume,
4226 pObjectInfo->FileId.Vnode,
4227 pObjectInfo->FileId.Unique,
4228 pObjectInfo->DataVersion.LowPart,
4229 pDirEnumEntry->DataVersion.LowPart));
4231 bPurgeExtents = TRUE;
4237 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4239 bPurgeExtents = TRUE;
4241 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4242 AFS_TRACE_LEVEL_VERBOSE,
4243 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4244 &DirEntry->NameInformation.FileName,
4245 pObjectInfo->FileId.Cell,
4246 pObjectInfo->FileId.Volume,
4247 pObjectInfo->FileId.Vnode,
4248 pObjectInfo->FileId.Unique));
4250 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4253 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4254 AFS_TRACE_LEVEL_VERBOSE,
4255 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4256 &pCurrentFcb->NPFcb->SectionObjectResource,
4257 PsGetCurrentThread()));
4259 AFSAcquireExcl( &pCurrentFcb->NPFcb->SectionObjectResource,
4265 IO_STATUS_BLOCK stIoStatus;
4267 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4272 if( !NT_SUCCESS( stIoStatus.Status))
4275 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4276 AFS_TRACE_LEVEL_ERROR,
4277 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4278 &DirEntry->NameInformation.FileName,
4279 pObjectInfo->FileId.Cell,
4280 pObjectInfo->FileId.Volume,
4281 pObjectInfo->FileId.Vnode,
4282 pObjectInfo->FileId.Unique,
4284 stIoStatus.Information));
4286 ntStatus = stIoStatus.Status;
4289 if ( bPurgeExtents &&
4290 pCurrentFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4293 if ( !CcPurgeCacheSection( &pCurrentFcb->NPFcb->SectionObjectPointers,
4299 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4300 AFS_TRACE_LEVEL_WARNING,
4301 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4302 &DirEntry->NameInformation.FileName,
4303 pObjectInfo->FileId.Cell,
4304 pObjectInfo->FileId.Volume,
4305 pObjectInfo->FileId.Vnode,
4306 pObjectInfo->FileId.Unique));
4308 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4312 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
4314 ntStatus = GetExceptionCode();
4318 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4319 &DirEntry->NameInformation.FileName,
4320 pObjectInfo->FileId.Cell,
4321 pObjectInfo->FileId.Volume,
4322 pObjectInfo->FileId.Vnode,
4323 pObjectInfo->FileId.Unique,
4326 SetFlag( pCurrentFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4329 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4330 AFS_TRACE_LEVEL_VERBOSE,
4331 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4332 &pCurrentFcb->NPFcb->SectionObjectResource,
4333 PsGetCurrentThread()));
4335 AFSReleaseResource( &pCurrentFcb->NPFcb->SectionObjectResource);
4343 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4349 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4351 bReleaseFcb = FALSE;
4354 if ( bPurgeExtents &&
4358 if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
4360 AFSFlushExtents( pCurrentFcb,
4367 // Update the metadata for the entry but only if it is safe to do so.
4368 // If it was determined that a data version change has occurred or
4369 // that a pending data verification was required, do not update the
4370 // ObjectInfo meta data or the FileObject size information. That
4371 // way it is consistent for the next time that the data is verified
4375 if ( !(bPurgeExtents && bSafeToPurge))
4378 ntStatus = AFSUpdateMetaData( DirEntry,
4381 if( !NT_SUCCESS( ntStatus))
4384 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4385 AFS_TRACE_LEVEL_ERROR,
4386 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4387 &DirEntry->NameInformation.FileName,
4388 pObjectInfo->FileId.Cell,
4389 pObjectInfo->FileId.Volume,
4390 pObjectInfo->FileId.Vnode,
4391 pObjectInfo->FileId.Unique,
4397 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4400 // Update file sizes
4403 if( pObjectInfo->Fcb != NULL)
4405 FILE_OBJECT *pCCFileObject;
4407 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4408 AFS_TRACE_LEVEL_VERBOSE,
4409 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4410 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4411 PsGetCurrentThread()));
4413 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4419 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4421 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4422 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4423 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4425 if ( pCCFileObject != NULL)
4427 CcSetFileSizes( pCCFileObject,
4428 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4431 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
4434 ntStatus = GetExceptionCode();
4438 "EXCEPTION - AFSValidateEntry CcSetFileSizes failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4439 pObjectInfo->FileId.Cell,
4440 pObjectInfo->FileId.Volume,
4441 pObjectInfo->FileId.Vnode,
4442 pObjectInfo->FileId.Unique,
4446 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4447 AFS_TRACE_LEVEL_VERBOSE,
4448 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4449 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4450 PsGetCurrentThread()));
4452 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4458 case AFS_FILE_TYPE_DIRECTORY:
4461 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4465 // For a directory or root entry flush the content of
4466 // the directory enumeration.
4469 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4470 AFS_TRACE_LEVEL_VERBOSE,
4471 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4472 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4473 PsGetCurrentThread()));
4475 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4478 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4479 AFS_TRACE_LEVEL_VERBOSE_2,
4480 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4481 &DirEntry->NameInformation.FileName,
4482 pObjectInfo->FileId.Cell,
4483 pObjectInfo->FileId.Volume,
4484 pObjectInfo->FileId.Vnode,
4485 pObjectInfo->FileId.Unique));
4487 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4490 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4493 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4496 if( !NT_SUCCESS( ntStatus))
4499 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4500 AFS_TRACE_LEVEL_ERROR,
4501 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4502 &DirEntry->NameInformation.FileName,
4503 pObjectInfo->FileId.Cell,
4504 pObjectInfo->FileId.Volume,
4505 pObjectInfo->FileId.Vnode,
4506 pObjectInfo->FileId.Unique,
4514 // Update the metadata for the entry
4517 ntStatus = AFSUpdateMetaData( DirEntry,
4520 if( NT_SUCCESS( ntStatus))
4523 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4531 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4532 AFS_TRACE_LEVEL_WARNING,
4533 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4534 pObjectInfo->FileType,
4536 &DirEntry->NameInformation.FileName,
4537 pObjectInfo->FileId.Cell,
4538 pObjectInfo->FileId.Volume,
4539 pObjectInfo->FileId.Vnode,
4540 pObjectInfo->FileId.Unique));
4550 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4553 if( pDirEnumEntry != NULL)
4556 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4564 AFSInitializeSpecialShareNameList()
4567 NTSTATUS ntStatus = STATUS_SUCCESS;
4568 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4569 AFSObjectInfoCB *pObjectInfoCB = NULL;
4570 UNICODE_STRING uniShareName;
4571 ULONG ulEntryLength = 0;
4572 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4578 RtlInitUnicodeString( &uniShareName,
4581 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4584 if( pObjectInfoCB == NULL)
4587 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4590 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4591 AFS_OBJECT_REFERENCE_GLOBAL);
4593 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4594 AFS_TRACE_LEVEL_VERBOSE,
4595 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4599 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4601 ulEntryLength = sizeof( AFSDirectoryCB) +
4602 uniShareName.Length;
4604 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4608 if( pDirNode == NULL)
4611 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4612 AFS_OBJECT_REFERENCE_GLOBAL);
4614 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4615 AFS_TRACE_LEVEL_VERBOSE,
4616 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4623 AFSDeleteObjectInfo( &pObjectInfoCB);
4626 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4629 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4630 AFS_TRACE_LEVEL_VERBOSE,
4631 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4634 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4635 sizeof( AFSNonPagedDirectoryCB),
4636 AFS_DIR_ENTRY_NP_TAG);
4638 if( pNonPagedDirEntry == NULL)
4641 AFSLibExFreePoolWithTag( pDirNode,
4644 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4645 AFS_OBJECT_REFERENCE_GLOBAL);
4647 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4648 AFS_TRACE_LEVEL_VERBOSE,
4649 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4656 AFSDeleteObjectInfo( &pObjectInfoCB);
4659 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4662 RtlZeroMemory( pDirNode,
4665 RtlZeroMemory( pNonPagedDirEntry,
4666 sizeof( AFSNonPagedDirectoryCB));
4668 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4670 pDirNode->NonPaged = pNonPagedDirEntry;
4672 pDirNode->ObjectInformation = pObjectInfoCB;
4678 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4680 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4682 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4684 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4686 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4687 uniShareName.Buffer,
4688 pDirNode->NameInformation.FileName.Length);
4690 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4693 AFSSpecialShareNames = pDirNode;
4695 pLastDirNode = pDirNode;
4698 RtlInitUnicodeString( &uniShareName,
4701 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4704 if( pObjectInfoCB == NULL)
4707 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4710 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4711 AFS_OBJECT_REFERENCE_GLOBAL);
4713 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4714 AFS_TRACE_LEVEL_VERBOSE,
4715 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4719 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4721 ulEntryLength = sizeof( AFSDirectoryCB) +
4722 uniShareName.Length;
4724 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4728 if( pDirNode == NULL)
4731 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4732 AFS_OBJECT_REFERENCE_GLOBAL);
4734 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4735 AFS_TRACE_LEVEL_VERBOSE,
4736 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4743 AFSDeleteObjectInfo( &pObjectInfoCB);
4746 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4749 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4750 AFS_TRACE_LEVEL_VERBOSE,
4751 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4754 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4755 sizeof( AFSNonPagedDirectoryCB),
4756 AFS_DIR_ENTRY_NP_TAG);
4758 if( pNonPagedDirEntry == NULL)
4761 AFSLibExFreePoolWithTag( pDirNode,
4764 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4765 AFS_OBJECT_REFERENCE_GLOBAL);
4767 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4768 AFS_TRACE_LEVEL_VERBOSE,
4769 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4776 AFSDeleteObjectInfo( &pObjectInfoCB);
4779 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4782 RtlZeroMemory( pDirNode,
4785 RtlZeroMemory( pNonPagedDirEntry,
4786 sizeof( AFSNonPagedDirectoryCB));
4788 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4790 pDirNode->NonPaged = pNonPagedDirEntry;
4792 pDirNode->ObjectInformation = pObjectInfoCB;
4798 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4800 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4802 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4804 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4806 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4807 uniShareName.Buffer,
4808 pDirNode->NameInformation.FileName.Length);
4810 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4813 pLastDirNode->ListEntry.fLink = pDirNode;
4815 pDirNode->ListEntry.bLink = pLastDirNode;
4819 if( !NT_SUCCESS( ntStatus))
4822 if( AFSSpecialShareNames != NULL)
4825 pDirNode = AFSSpecialShareNames;
4827 while( pDirNode != NULL)
4830 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4832 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
4833 AFS_OBJECT_REFERENCE_GLOBAL);
4835 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4836 AFS_TRACE_LEVEL_VERBOSE,
4837 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4838 pDirNode->ObjectInformation,
4844 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4847 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4849 AFSLibExFreePoolWithTag( pDirNode->NonPaged,
4850 AFS_DIR_ENTRY_NP_TAG);
4852 AFSLibExFreePoolWithTag( pDirNode,
4855 pDirNode = pLastDirNode;
4858 AFSSpecialShareNames = NULL;
4867 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4868 IN UNICODE_STRING *SecondaryName)
4871 AFSDirectoryCB *pDirectoryCB = NULL;
4872 ULONGLONG ullHash = 0;
4873 UNICODE_STRING uniFullShareName;
4879 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4880 AFS_TRACE_LEVEL_VERBOSE_2,
4881 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4885 uniFullShareName = *ShareName;
4888 // Generate our hash value
4891 ullHash = AFSGenerateCRC( &uniFullShareName,
4895 // Loop through our special share names to see if this is one of them
4898 pDirectoryCB = AFSSpecialShareNames;
4900 while( pDirectoryCB != NULL)
4903 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4909 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4913 return pDirectoryCB;
4917 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4921 // Block on the queue flush event
4924 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4934 AFSWaitOnQueuedReleases()
4937 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4940 // Block on the queue flush event
4943 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4953 AFSIsEqualFID( IN AFSFileID *FileId1,
4954 IN AFSFileID *FileId2)
4957 BOOLEAN bIsEqual = FALSE;
4959 if( FileId1->Hash == FileId2->Hash &&
4960 FileId1->Unique == FileId2->Unique &&
4961 FileId1->Vnode == FileId2->Vnode &&
4962 FileId1->Volume == FileId2->Volume &&
4963 FileId1->Cell == FileId2->Cell)
4973 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4976 NTSTATUS ntStatus = STATUS_SUCCESS;
4977 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4982 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4985 // Reset the directory list information
4988 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4990 while( pCurrentDirEntry != NULL)
4993 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4995 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
4996 pCurrentDirEntry->NameArrayReferenceCount <= 0)
4999 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
5000 AFS_TRACE_LEVEL_VERBOSE,
5001 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
5003 &pCurrentDirEntry->NameInformation.FileName));
5005 AFSDeleteDirEntry( ObjectInfoCB,
5011 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
5012 AFS_TRACE_LEVEL_VERBOSE,
5013 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
5015 &pCurrentDirEntry->NameInformation.FileName));
5017 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
5019 AFSRemoveNameEntry( ObjectInfoCB,
5023 pCurrentDirEntry = pNextDirEntry;
5026 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
5028 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
5030 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
5032 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
5034 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
5036 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
5038 AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
5039 AFS_TRACE_LEVEL_VERBOSE,
5040 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
5041 ObjectInfoCB->FileId.Cell,
5042 ObjectInfoCB->FileId.Volume,
5043 ObjectInfoCB->FileId.Vnode,
5044 ObjectInfoCB->FileId.Unique));
5051 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
5054 NTSTATUS ntStatus = STATUS_SUCCESS;
5055 AFSDirectoryCB *pDirGlobalDirNode = NULL;
5056 UNICODE_STRING uniFullName;
5061 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
5062 AFS_TRACE_LEVEL_VERBOSE,
5063 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
5064 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
5065 PsGetCurrentThread()));
5067 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
5070 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
5073 try_return( ntStatus);
5077 // Initialize the root information
5080 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
5083 // Enumerate the shares in the volume
5086 ntStatus = AFSEnumerateDirectory( AuthGroup,
5087 &AFSGlobalRoot->ObjectInformation,
5090 if( !NT_SUCCESS( ntStatus))
5093 try_return( ntStatus);
5096 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
5098 uniFullName.MaximumLength = PAGE_SIZE;
5099 uniFullName.Length = 0;
5101 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
5102 uniFullName.MaximumLength,
5103 AFS_GENERIC_MEMORY_12_TAG);
5105 if( uniFullName.Buffer == NULL)
5109 // Reset the directory content
5112 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
5114 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
5116 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5120 // Populate our list of entries in the NP enumeration list
5123 while( pDirGlobalDirNode != NULL)
5126 uniFullName.Buffer[ 0] = L'\\';
5127 uniFullName.Buffer[ 1] = L'\\';
5129 uniFullName.Length = 2 * sizeof( WCHAR);
5131 RtlCopyMemory( &uniFullName.Buffer[ 2],
5132 AFSServerName.Buffer,
5133 AFSServerName.Length);
5135 uniFullName.Length += AFSServerName.Length;
5137 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
5139 uniFullName.Length += sizeof( WCHAR);
5141 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
5142 pDirGlobalDirNode->NameInformation.FileName.Buffer,
5143 pDirGlobalDirNode->NameInformation.FileName.Length);
5145 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
5147 AFSAddConnectionEx( &uniFullName,
5148 RESOURCEDISPLAYTYPE_SHARE,
5151 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
5154 AFSLibExFreePoolWithTag( uniFullName.Buffer,
5155 AFS_GENERIC_MEMORY_12_TAG);
5159 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
5166 AFSIsRelativeName( IN UNICODE_STRING *Name)
5169 BOOLEAN bIsRelative = FALSE;
5171 if( Name->Length > 0 &&
5172 Name->Buffer[ 0] != L'\\')
5182 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
5184 UNICODE_STRING uniTempName;
5185 BOOLEAN bIsAbsolute = FALSE;
5188 // An absolute AFS path must begin with \afs\... or equivalent
5191 if ( Name->Length == 0 ||
5192 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
5193 Name->Buffer[ 0] != L'\\' ||
5194 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
5200 uniTempName.Length = AFSMountRootName.Length;
5201 uniTempName.MaximumLength = AFSMountRootName.Length;
5203 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5204 uniTempName.MaximumLength,
5205 AFS_NAME_BUFFER_TWO_TAG);
5207 if( uniTempName.Buffer == NULL)
5213 RtlCopyMemory( uniTempName.Buffer,
5215 AFSMountRootName.Length);
5217 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
5221 AFSExFreePoolWithTag( uniTempName.Buffer,
5222 AFS_NAME_BUFFER_TWO_TAG);
5229 AFSUpdateName( IN UNICODE_STRING *Name)
5234 while( usIndex < Name->Length/sizeof( WCHAR))
5237 if( Name->Buffer[ usIndex] == L'/')
5240 Name->Buffer[ usIndex] = L'\\';
5250 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
5251 IN OUT ULONG *Flags,
5252 IN WCHAR *NameBuffer,
5253 IN USHORT NameLength)
5256 NTSTATUS ntStatus = STATUS_SUCCESS;
5257 WCHAR *pTmpBuffer = NULL;
5263 // If we have enough space then just move in the name otherwise
5264 // allocate a new buffer
5267 if( TargetName->Length < NameLength)
5270 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5272 AFS_NAME_BUFFER_FIVE_TAG);
5274 if( pTmpBuffer == NULL)
5277 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5280 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5283 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5286 TargetName->MaximumLength = NameLength;
5288 TargetName->Buffer = pTmpBuffer;
5290 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5293 TargetName->Length = NameLength;
5295 RtlCopyMemory( TargetName->Buffer,
5297 TargetName->Length);
5300 // Update the name in the buffer
5303 AFSUpdateName( TargetName);
5314 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5319 // Depending on the type of node, set the event
5322 switch( Fcb->Header.NodeTypeCode)
5325 case AFS_DIRECTORY_FCB:
5330 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5340 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5346 // Depending on the type of node, set the event
5349 switch( Fcb->Header.NodeTypeCode)
5352 case AFS_DIRECTORY_FCB:
5357 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5359 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5369 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5372 BOOLEAN bIsInProcess = FALSE;
5377 if( ObjectInfo->Fcb == NULL)
5380 try_return( bIsInProcess);
5383 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5386 case AFS_DIRECTORY_FCB:
5391 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5394 bIsInProcess = TRUE;
5406 return bIsInProcess;
5410 AFSVerifyVolume( IN ULONGLONG ProcessId,
5411 IN AFSVolumeCB *VolumeCB)
5414 UNREFERENCED_PARAMETER(ProcessId);
5415 UNREFERENCED_PARAMETER(VolumeCB);
5416 NTSTATUS ntStatus = STATUS_SUCCESS;
5423 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5426 NTSTATUS ntStatus = STATUS_SUCCESS;
5427 AFSObjectInfoCB *pObjectInfoCB = NULL;
5428 AFSDirectoryCB *pDirNode = NULL;
5429 ULONG ulEntryLength = 0;
5430 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5436 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
5439 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5442 if( pObjectInfoCB == NULL)
5445 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5447 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5450 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5451 AFS_OBJECT_REFERENCE_PIOCTL);
5453 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5454 AFS_TRACE_LEVEL_VERBOSE,
5455 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5459 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5461 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5463 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5465 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5467 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5471 if( pDirNode == NULL)
5474 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5477 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5478 AFS_TRACE_LEVEL_VERBOSE,
5479 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5482 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5483 sizeof( AFSNonPagedDirectoryCB),
5484 AFS_DIR_ENTRY_NP_TAG);
5486 if( pNonPagedDirEntry == NULL)
5489 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5492 RtlZeroMemory( pDirNode,
5495 RtlZeroMemory( pNonPagedDirEntry,
5496 sizeof( AFSNonPagedDirectoryCB));
5498 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5500 pDirNode->NonPaged = pNonPagedDirEntry;
5502 pDirNode->ObjectInformation = pObjectInfoCB;
5504 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5510 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5512 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5514 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5516 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5518 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5519 AFSPIOCtlName.Buffer,
5520 pDirNode->NameInformation.FileName.Length);
5522 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5525 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5528 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5529 AFS_TRACE_LEVEL_WARNING,
5530 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5531 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5534 try_return( ntStatus = STATUS_REPARSE);
5539 if ( ntStatus != STATUS_SUCCESS)
5542 if ( pDirNode != NULL)
5545 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5546 AFS_TRACE_LEVEL_VERBOSE,
5547 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
5550 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5553 if( pNonPagedDirEntry != NULL)
5556 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5558 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5561 if ( pObjectInfoCB != NULL)
5564 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
5565 AFS_OBJECT_REFERENCE_PIOCTL);
5567 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5568 AFS_TRACE_LEVEL_VERBOSE,
5569 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
5576 AFSDeleteObjectInfo( &pObjectInfoCB);
5586 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5587 IN AFSDirectoryCB *DirectoryCB,
5588 IN UNICODE_STRING *ParentPathName,
5589 IN AFSNameArrayHdr *RelatedNameArray,
5591 OUT AFSFileInfoCB *FileInfo)
5594 NTSTATUS ntStatus = STATUS_SUCCESS;
5595 AFSDirEnumEntry *pDirEntry = NULL;
5596 UNICODE_STRING uniFullPathName = {0};
5597 AFSNameArrayHdr *pNameArray = NULL;
5598 AFSVolumeCB *pVolumeCB = NULL;
5599 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5600 AFSVolumeCB *pNewVolumeCB = NULL;
5601 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5602 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5603 AFSDirectoryCB *pNewParentDirEntry = NULL;
5604 WCHAR *pwchBuffer = NULL;
5605 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5606 ULONG ulNameDifference = 0;
5613 // Retrieve a target name for the entry
5616 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5619 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5622 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5624 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5629 if( !NT_SUCCESS( ntStatus) ||
5630 pDirEntry->TargetNameLength == 0)
5633 if( pDirEntry != NULL)
5636 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5639 try_return( ntStatus);
5642 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5645 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5649 // Update the target name
5652 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5653 &DirectoryCB->Flags,
5654 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5655 (USHORT)pDirEntry->TargetNameLength);
5657 if( !NT_SUCCESS( ntStatus))
5660 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5662 try_return( ntStatus);
5666 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5670 // Need to pass the full path in for parsing.
5673 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5676 uniFullPathName.Length = 0;
5677 uniFullPathName.MaximumLength = ParentPathName->Length +
5679 DirectoryCB->NameInformation.TargetName.Length;
5681 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5682 uniFullPathName.MaximumLength,
5683 AFS_NAME_BUFFER_SIX_TAG);
5685 if( uniFullPathName.Buffer == NULL)
5688 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5690 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5693 pwchBuffer = uniFullPathName.Buffer;
5695 RtlZeroMemory( uniFullPathName.Buffer,
5696 uniFullPathName.MaximumLength);
5698 RtlCopyMemory( uniFullPathName.Buffer,
5699 ParentPathName->Buffer,
5700 ParentPathName->Length);
5702 uniFullPathName.Length = ParentPathName->Length;
5704 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5705 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5708 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5710 uniFullPathName.Length += sizeof( WCHAR);
5713 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5714 DirectoryCB->NameInformation.TargetName.Buffer,
5715 DirectoryCB->NameInformation.TargetName.Length);
5717 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5719 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5720 uniParsedName.MaximumLength = uniParsedName.Length;
5722 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5724 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5727 // We populate up to the current parent
5730 if( RelatedNameArray != NULL)
5733 pNameArray = AFSInitNameArray( NULL,
5734 RelatedNameArray->MaxElementCount);
5736 if( pNameArray == NULL)
5739 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5742 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5749 pNameArray = AFSInitNameArray( NULL,
5752 if( pNameArray == NULL)
5755 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5758 ntStatus = AFSPopulateNameArray( pNameArray,
5763 if( !NT_SUCCESS( ntStatus))
5766 try_return( ntStatus);
5769 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5771 pParentDirEntry = ParentDirectoryCB;
5776 uniFullPathName.Length = 0;
5777 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5779 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5780 uniFullPathName.MaximumLength,
5781 AFS_NAME_BUFFER_SEVEN_TAG);
5783 if( uniFullPathName.Buffer == NULL)
5786 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5788 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5791 pwchBuffer = uniFullPathName.Buffer;
5793 RtlZeroMemory( uniFullPathName.Buffer,
5794 uniFullPathName.MaximumLength);
5796 RtlCopyMemory( uniFullPathName.Buffer,
5797 DirectoryCB->NameInformation.TargetName.Buffer,
5798 DirectoryCB->NameInformation.TargetName.Length);
5800 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5803 // This name should begin with the \afs server so parse it off and check it
5806 FsRtlDissectName( uniFullPathName,
5810 if( RtlCompareUnicodeString( &uniComponentName,
5815 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5817 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5818 AFS_TRACE_LEVEL_ERROR,
5819 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5822 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5825 uniFullPathName = uniRemainingPath;
5827 uniParsedName = uniFullPathName;
5829 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5831 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5837 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5840 if( pNameArray == NULL)
5843 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5846 pVolumeCB = AFSGlobalRoot;
5848 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5852 // Increment the ref count on the volume and dir entry for correct processing below
5855 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
5857 lCount = AFSVolumeIncrement( pVolumeCB,
5858 VolumeReferenceReason);
5860 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5861 AFS_TRACE_LEVEL_VERBOSE,
5862 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
5864 VolumeReferenceReason,
5867 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
5869 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5870 AFS_TRACE_LEVEL_VERBOSE,
5871 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5872 &pParentDirEntry->NameInformation.FileName,
5877 ntStatus = AFSLocateNameEntry( NULL,
5882 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5886 &NewVolumeReferenceReason,
5887 &pNewParentDirEntry,
5891 if ( pNewVolumeCB != NULL)
5894 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
5895 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
5896 // the reference on pVolumeCB that was held prior to the call.
5897 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
5898 // will be released second.
5901 lCount = AFSVolumeDecrement( pVolumeCB,
5902 VolumeReferenceReason);
5904 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5905 AFS_TRACE_LEVEL_VERBOSE,
5906 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
5908 VolumeReferenceReason,
5911 pVolumeCB = pNewVolumeCB;
5913 pNewVolumeCB = NULL;
5915 VolumeReferenceReason = NewVolumeReferenceReason;
5917 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5921 // AFSLocateNameEntry does not alter the reference count of
5922 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
5923 // a reference held.
5926 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
5928 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5929 AFS_TRACE_LEVEL_VERBOSE,
5930 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
5931 &pParentDirEntry->NameInformation.FileName,
5935 pParentDirEntry = pNewParentDirEntry;
5937 pNewParentDirEntry = NULL;
5939 if( !NT_SUCCESS( ntStatus) ||
5940 ntStatus == STATUS_REPARSE)
5943 try_return( ntStatus);
5947 // Store off the information
5950 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5953 // Check for the mount point being returned
5956 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
5957 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5960 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5962 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
5965 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
5968 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
5973 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5977 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5979 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5981 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5983 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5985 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5987 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5991 if( pDirEntry != NULL)
5994 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
5997 if( pDirectoryEntry != NULL)
6000 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6002 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6003 AFS_TRACE_LEVEL_VERBOSE,
6004 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6005 &pDirectoryEntry->NameInformation.FileName,
6010 ASSERT( lCount >= 0);
6013 if ( pParentDirEntry != NULL)
6016 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6018 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6019 AFS_TRACE_LEVEL_VERBOSE,
6020 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6021 &pParentDirEntry->NameInformation.FileName,
6026 ASSERT( lCount >= 0);
6029 if( pVolumeCB != NULL)
6032 lCount = AFSVolumeDecrement( pVolumeCB,
6033 VolumeReferenceReason);
6035 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6036 AFS_TRACE_LEVEL_VERBOSE,
6037 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
6039 VolumeReferenceReason,
6043 if( pNameArray != NULL)
6046 AFSFreeNameArray( pNameArray);
6049 if( pwchBuffer != NULL)
6053 // Always free the buffer that we allocated as AFSLocateNameEntry
6054 // will not free it. If uniFullPathName.Buffer was allocated by
6055 // AFSLocateNameEntry, then we must free that as well.
6056 // Check that the uniFullPathName.Buffer in the string is not the same
6057 // offset by the length of the server name
6060 if( uniFullPathName.Length > 0 &&
6061 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6064 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6067 AFSExFreePoolWithTag( pwchBuffer, 0);
6075 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6076 IN ULONGLONG HashIndex)
6079 NTSTATUS ntStatus = STATUS_SUCCESS;
6080 AFSObjectInfoCB *pObjectInfo = NULL;
6086 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6087 sizeof( AFSObjectInfoCB),
6088 AFS_OBJECT_INFO_TAG);
6090 if( pObjectInfo == NULL)
6093 try_return( pObjectInfo);
6096 RtlZeroMemory( pObjectInfo,
6097 sizeof( AFSObjectInfoCB));
6099 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6100 sizeof( AFSNonPagedObjectInfoCB),
6101 AFS_NP_OBJECT_INFO_TAG);
6103 if( pObjectInfo->NonPagedInfo == NULL)
6106 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6108 try_return( pObjectInfo = NULL);
6111 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6113 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6115 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6117 if( ParentObjectInfo != NULL)
6120 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6122 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6124 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6126 AFSAcquireShared( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6129 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6130 AFS_OBJECT_REFERENCE_CHILD);
6132 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6133 AFS_TRACE_LEVEL_VERBOSE,
6134 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6138 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6142 // Initialize the access time
6145 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6150 ASSERT( ParentObjectInfo);
6153 // Insert the entry into the object tree and list
6156 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6158 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6161 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6166 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6167 &pObjectInfo->TreeEntry);
6169 ASSERT( NT_SUCCESS( ntStatus));
6173 // And the object list in the volume
6176 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6179 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6184 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6186 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6189 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6192 // Indicate the object is in the hash tree and linked list in the volume
6195 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6207 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6213 if ( ObjectInfo->ObjectReferenceCount == 0)
6216 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6219 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6224 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6227 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6232 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6234 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6239 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6241 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6247 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6251 LONG lCount, lCount2;
6253 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6256 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6261 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6263 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6265 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6268 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6271 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6273 ASSERT( lCount2 >= 0);
6275 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6281 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6282 IN AFSFileID *FileId,
6283 IN BOOLEAN bUpdateLastUse)
6285 DWORD ntStatus = STATUS_SUCCESS;
6287 AFSObjectInfoCB *pObjectInfo = NULL;
6290 ullIndex = AFSCreateLowIndex( FileId);
6292 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
6295 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6298 pObjectInfo = &VolumeCB->ObjectInformation;
6303 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6305 (AFSBTreeEntry **)&pObjectInfo);
6308 if ( NT_SUCCESS( ntStatus)) {
6310 lCount = AFSObjectInfoIncrement( pObjectInfo,
6311 AFS_OBJECT_REFERENCE_FIND);
6313 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6314 AFS_TRACE_LEVEL_VERBOSE,
6315 "AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
6319 if ( bUpdateLastUse)
6322 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6326 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6332 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6336 lCount = AFSObjectInfoDecrement( *ppObjectInfo,
6337 AFS_OBJECT_REFERENCE_FIND);
6339 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6340 AFS_TRACE_LEVEL_VERBOSE,
6341 "AFSReleaseObjectInfo Decrement count on object %p Cnt %d\n",
6345 *ppObjectInfo = NULL;
6349 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6351 BOOLEAN bAcquiredTreeLock = FALSE;
6352 AFSObjectInfoCB *pObjectInfo = NULL;
6353 AFSVolumeCB * pVolume = NULL;
6354 BOOLEAN bHeldInService;
6355 AFSObjectInfoCB * pParentObjectInfo = NULL;
6361 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
6365 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6366 // embedded in the VolumeCB.
6374 pVolume = (*ppObjectInfo)->VolumeCB;
6376 if( !ExIsResourceAcquiredExclusiveLite( pVolume->ObjectInfoTree.TreeLock))
6379 ASSERT( !ExIsResourceAcquiredLite( pVolume->ObjectInfoTree.TreeLock));
6381 AFSAcquireExcl( pVolume->ObjectInfoTree.TreeLock,
6384 bAcquiredTreeLock = TRUE;
6387 for ( lCount = 0; lCount < AFS_OBJECT_REFERENCE_MAX; lCount++)
6390 ASSERT( (*ppObjectInfo)->ObjectReferences[ lCount] >= 0);
6393 ASSERT( (*ppObjectInfo)->ObjectReferenceCount == 0);
6395 pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
6399 if ( pObjectInfo == NULL)
6402 try_return( NOTHING);
6405 ASSERT( *ppObjectInfo == NULL);
6407 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6410 pParentObjectInfo = AFSFindObjectInfo( pVolume,
6411 &pObjectInfo->ParentFileId,
6414 if( pParentObjectInfo != NULL)
6417 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6419 AFSAcquireShared( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6422 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6423 AFS_OBJECT_REFERENCE_CHILD);
6425 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6426 AFS_TRACE_LEVEL_VERBOSE,
6427 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6431 AFSReleaseResource( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6433 AFSReleaseObjectInfo( &pParentObjectInfo);
6438 // Remove it from the tree and list if it was inserted
6441 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6444 AFSRemoveHashEntry( &pVolume->ObjectInfoTree.TreeHead,
6445 &pObjectInfo->TreeEntry);
6448 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6451 if( pObjectInfo->ListEntry.fLink == NULL)
6454 pVolume->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6456 if( pVolume->ObjectInfoListTail != NULL)
6459 pVolume->ObjectInfoListTail->ListEntry.fLink = NULL;
6465 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6468 if( pObjectInfo->ListEntry.bLink == NULL)
6471 pVolume->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6473 if( pVolume->ObjectInfoListHead != NULL)
6476 pVolume->ObjectInfoListHead->ListEntry.bLink = NULL;
6482 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6486 bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6491 FileId = pObjectInfo->FileId;
6494 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6496 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6498 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6500 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6502 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6506 if( bAcquiredTreeLock)
6509 AFSReleaseResource( pVolume->ObjectInfoTree.TreeLock);
6513 // Release the fid in the service
6519 AFSReleaseFid( &FileId);
6527 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6528 OUT AFSDirectoryCB **TargetDirEntry)
6531 NTSTATUS ntStatus = STATUS_SUCCESS;
6532 AFSDirEnumEntry *pDirEntry = NULL;
6533 UNICODE_STRING uniFullPathName = {0};
6534 AFSNameArrayHdr *pNameArray = NULL;
6535 AFSVolumeCB *pVolumeCB = NULL;
6536 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6537 AFSVolumeCB *pNewVolumeCB = NULL;
6538 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6539 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6540 AFSDirectoryCB *pNewParentDirEntry = NULL;
6541 WCHAR *pwchBuffer = NULL;
6542 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6543 ULONG ulNameDifference = 0;
6550 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6551 DirectoryCB->ObjectInformation,
6555 if( !NT_SUCCESS( ntStatus))
6557 try_return( ntStatus);
6561 // Retrieve a target name for the entry
6564 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6567 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6570 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6572 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6577 if( !NT_SUCCESS( ntStatus) ||
6578 pDirEntry->TargetNameLength == 0)
6581 if( pDirEntry != NULL)
6584 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6587 try_return( ntStatus);
6590 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6593 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6597 // Update the target name
6600 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6601 &DirectoryCB->Flags,
6602 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6603 (USHORT)pDirEntry->TargetNameLength);
6605 if( !NT_SUCCESS( ntStatus))
6608 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6610 try_return( ntStatus);
6614 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6618 // Need to pass the full path in for parsing.
6621 uniFullPathName.Length = 0;
6622 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6624 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6625 uniFullPathName.MaximumLength,
6626 AFS_NAME_BUFFER_EIGHT_TAG);
6628 if( uniFullPathName.Buffer == NULL)
6631 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6633 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6636 pwchBuffer = uniFullPathName.Buffer;
6638 RtlZeroMemory( uniFullPathName.Buffer,
6639 uniFullPathName.MaximumLength);
6641 RtlCopyMemory( uniFullPathName.Buffer,
6642 DirectoryCB->NameInformation.TargetName.Buffer,
6643 DirectoryCB->NameInformation.TargetName.Length);
6645 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6648 // This name should begin with the \afs server so parse it off and chech it
6651 FsRtlDissectName( uniFullPathName,
6655 if( RtlCompareUnicodeString( &uniComponentName,
6661 // Try evaluating the full path
6664 uniFullPathName.Buffer = pwchBuffer;
6666 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6668 uniFullPathName.MaximumLength = uniFullPathName.Length;
6673 uniFullPathName = uniRemainingPath;
6676 uniParsedName = uniFullPathName;
6678 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6680 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6686 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6689 if( pNameArray == NULL)
6692 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6695 pVolumeCB = AFSGlobalRoot;
6697 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6699 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
6701 lCount = AFSVolumeIncrement( pVolumeCB,
6702 VolumeReferenceReason);
6704 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6705 AFS_TRACE_LEVEL_VERBOSE,
6706 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
6708 VolumeReferenceReason,
6711 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6713 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6714 AFS_TRACE_LEVEL_VERBOSE,
6715 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6716 &pParentDirEntry->NameInformation.FileName,
6721 ntStatus = AFSLocateNameEntry( NULL,
6730 &VolumeReferenceReason,
6731 &pNewParentDirEntry,
6735 if ( pNewVolumeCB != NULL)
6738 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6739 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6740 // the reference on pVolumeCB that was held prior to the call.
6741 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6742 // will be released second.
6745 lCount = AFSVolumeDecrement( pVolumeCB,
6746 VolumeReferenceReason);
6748 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6749 AFS_TRACE_LEVEL_VERBOSE,
6750 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
6752 VolumeReferenceReason,
6755 pVolumeCB = pNewVolumeCB;
6757 pNewVolumeCB = NULL;
6759 VolumeReferenceReason = NewVolumeReferenceReason;
6761 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6765 // AFSLocateNameEntry does not alter the reference count of
6766 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6767 // a reference held.
6770 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6772 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6773 AFS_TRACE_LEVEL_VERBOSE,
6774 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
6775 &pParentDirEntry->NameInformation.FileName,
6779 pParentDirEntry = pNewParentDirEntry;
6781 pNewParentDirEntry = NULL;
6783 if( !NT_SUCCESS( ntStatus) ||
6784 ntStatus == STATUS_REPARSE)
6789 try_return( ntStatus);
6793 // Pass back the target dir entry for this request
6794 // The caller must release the DirOpenReferenceCount
6797 *TargetDirEntry = pDirectoryEntry;
6799 pDirectoryEntry = NULL;
6803 if( pDirectoryEntry != NULL)
6806 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6808 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6809 AFS_TRACE_LEVEL_VERBOSE,
6810 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6811 &pDirectoryEntry->NameInformation.FileName,
6816 ASSERT( lCount >= 0);
6819 if ( pParentDirEntry != NULL)
6822 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6824 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6825 AFS_TRACE_LEVEL_VERBOSE,
6826 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6827 &pParentDirEntry->NameInformation.FileName,
6832 ASSERT( lCount >= 0);
6835 if( pDirEntry != NULL)
6838 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6841 if( pVolumeCB != NULL)
6844 lCount = AFSVolumeDecrement( pVolumeCB,
6845 VolumeReferenceReason);
6847 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6848 AFS_TRACE_LEVEL_VERBOSE,
6849 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
6851 VolumeReferenceReason,
6855 if( pNameArray != NULL)
6858 AFSFreeNameArray( pNameArray);
6861 if( pwchBuffer != NULL)
6865 // Always free the buffer that we allocated as AFSLocateNameEntry
6866 // will not free it. If uniFullPathName.Buffer was allocated by
6867 // AFSLocateNameEntry, then we must free that as well.
6868 // Check that the uniFullPathName.Buffer in the string is not the same
6869 // offset by the length of the server name
6872 if( uniFullPathName.Length > 0 &&
6873 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6876 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6879 AFSExFreePoolWithTag( pwchBuffer, 0);
6887 AFSCleanupFcb( IN AFSFcb *Fcb,
6888 IN BOOLEAN ForceFlush)
6891 NTSTATUS ntStatus = STATUS_SUCCESS;
6892 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6893 LARGE_INTEGER liTime;
6894 IO_STATUS_BLOCK stIoStatus;
6899 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6901 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6903 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6906 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6907 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6910 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
6911 AFS_TRACE_LEVEL_VERBOSE,
6912 "AFSCleanupEntry Acquiring Fcb lock %p EXCL %08lX\n",
6913 &Fcb->NPFcb->Resource,
6914 PsGetCurrentThread()));
6916 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6919 if( Fcb->OpenReferenceCount > 0)
6922 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
6923 AFS_TRACE_LEVEL_VERBOSE,
6924 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
6925 &Fcb->NPFcb->SectionObjectResource,
6926 PsGetCurrentThread()));
6928 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
6934 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6939 if( !NT_SUCCESS( stIoStatus.Status))
6942 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6943 AFS_TRACE_LEVEL_ERROR,
6944 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6945 Fcb->ObjectInformation->FileId.Cell,
6946 Fcb->ObjectInformation->FileId.Volume,
6947 Fcb->ObjectInformation->FileId.Vnode,
6948 Fcb->ObjectInformation->FileId.Unique,
6950 stIoStatus.Information));
6952 ntStatus = stIoStatus.Status;
6955 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
6958 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6964 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
6965 AFS_TRACE_LEVEL_WARNING,
6966 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
6967 Fcb->ObjectInformation->FileId.Cell,
6968 Fcb->ObjectInformation->FileId.Volume,
6969 Fcb->ObjectInformation->FileId.Vnode,
6970 Fcb->ObjectInformation->FileId.Unique));
6972 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6976 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
6979 ntStatus = GetExceptionCode();
6983 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
6984 Fcb->ObjectInformation->FileId.Cell,
6985 Fcb->ObjectInformation->FileId.Volume,
6986 Fcb->ObjectInformation->FileId.Vnode,
6987 Fcb->ObjectInformation->FileId.Unique,
6990 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
6993 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
6994 AFS_TRACE_LEVEL_VERBOSE,
6995 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
6996 &Fcb->NPFcb->SectionObjectResource,
6997 PsGetCurrentThread()));
6999 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7002 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7003 AFS_TRACE_LEVEL_VERBOSE,
7004 "AFSCleanupEntry Releasing Fcb lock %p EXCL %08lX\n",
7005 &Fcb->NPFcb->Resource,
7006 PsGetCurrentThread()));
7008 AFSReleaseResource( &Fcb->NPFcb->Resource);
7010 if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
7013 // Wait for any currently running flush or release requests to complete
7016 AFSWaitOnQueuedFlushes( Fcb);
7019 // Now perform another flush on the file
7022 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7026 AFSReleaseExtentsWithFlush( Fcb,
7033 if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
7036 if( Fcb->OpenReferenceCount == 0 ||
7037 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7038 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7041 AFSTearDownFcbExtents( Fcb,
7046 try_return( ntStatus);
7049 KeQueryTickCount( &liTime);
7051 if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
7054 // First up are there dirty extents in the cache to flush?
7057 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7058 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7062 // The file has been marked as invalid. Dump it
7065 AFSTearDownFcbExtents( Fcb,
7068 else if( ForceFlush ||
7069 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7070 Fcb->Specific.File.ExtentCount) &&
7071 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7072 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7075 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7077 Fcb->OpenReferenceCount == 0)
7080 AFSReleaseExtentsWithFlush( Fcb,
7088 // If there are extents and they haven't been used recently *and*
7089 // are not being used
7093 ( 0 != Fcb->Specific.File.ExtentCount &&
7094 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7095 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7096 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7099 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7100 AFS_TRACE_LEVEL_VERBOSE,
7101 "AFSCleanupFcb Acquiring Fcb lock %p EXCL %08lX\n",
7102 &Fcb->NPFcb->Resource,
7103 PsGetCurrentThread()));
7105 if ( AFSAcquireExcl( &Fcb->NPFcb->Resource, ForceFlush) == FALSE)
7108 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7109 AFS_TRACE_LEVEL_VERBOSE,
7110 "AFSCleanupFcb Failed to Acquire Fcb lock %p EXCL %08lX\n",
7111 &Fcb->NPFcb->Resource,
7112 PsGetCurrentThread()));
7114 try_return( ntStatus = STATUS_RETRY);
7117 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7118 AFS_TRACE_LEVEL_VERBOSE,
7119 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7120 &Fcb->NPFcb->SectionObjectResource,
7121 PsGetCurrentThread()));
7123 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7129 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7134 if( !NT_SUCCESS( stIoStatus.Status))
7137 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7138 AFS_TRACE_LEVEL_ERROR,
7139 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7140 Fcb->ObjectInformation->FileId.Cell,
7141 Fcb->ObjectInformation->FileId.Volume,
7142 Fcb->ObjectInformation->FileId.Vnode,
7143 Fcb->ObjectInformation->FileId.Unique,
7145 stIoStatus.Information));
7147 ntStatus = stIoStatus.Status;
7151 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7154 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7160 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7161 AFS_TRACE_LEVEL_WARNING,
7162 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7163 Fcb->ObjectInformation->FileId.Cell,
7164 Fcb->ObjectInformation->FileId.Volume,
7165 Fcb->ObjectInformation->FileId.Vnode,
7166 Fcb->ObjectInformation->FileId.Unique));
7168 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7172 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
7175 ntStatus = GetExceptionCode();
7179 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7180 Fcb->ObjectInformation->FileId.Cell,
7181 Fcb->ObjectInformation->FileId.Volume,
7182 Fcb->ObjectInformation->FileId.Vnode,
7183 Fcb->ObjectInformation->FileId.Unique,
7187 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7188 AFS_TRACE_LEVEL_VERBOSE,
7189 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7190 &Fcb->NPFcb->SectionObjectResource,
7191 PsGetCurrentThread()));
7193 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7195 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7196 AFS_TRACE_LEVEL_VERBOSE,
7197 "AFSCleanupFcb Releasing Fcb lock %p EXCL %08lX\n",
7198 &Fcb->NPFcb->Resource,
7199 PsGetCurrentThread()));
7201 AFSReleaseResource( &Fcb->NPFcb->Resource);
7203 if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
7206 if( Fcb->OpenReferenceCount <= 0)
7210 // Tear em down we'll not be needing them again
7213 AFSTearDownFcbExtents( Fcb,
7221 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7222 AFS_TRACE_LEVEL_VERBOSE,
7223 "AFSCleanupFcb Failed to Acquire Fcb SectionObject lock %p EXCL %08lX\n",
7224 &Fcb->NPFcb->SectionObjectResource,
7225 PsGetCurrentThread()));
7227 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7228 AFS_TRACE_LEVEL_VERBOSE,
7229 "AFSCleanupFcb Releasing Fcb lock %p EXCL %08lX\n",
7230 &Fcb->NPFcb->Resource,
7231 PsGetCurrentThread()));
7233 AFSReleaseResource( &Fcb->NPFcb->Resource);
7235 ntStatus = STATUS_RETRY;
7248 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7249 IN UNICODE_STRING *NewFileName)
7252 NTSTATUS ntStatus = STATUS_SUCCESS;
7253 WCHAR *pTmpBuffer = NULL;
7258 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7261 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7264 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7266 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7268 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7272 // OK, we need to allocate a new name buffer
7275 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7276 NewFileName->Length,
7277 AFS_NAME_BUFFER_NINE_TAG);
7279 if( pTmpBuffer == NULL)
7282 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7285 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7287 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7289 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7292 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7294 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7295 NewFileName->Buffer,
7296 NewFileName->Length);
7307 AFSReadCacheFile( IN void *ReadBuffer,
7308 IN LARGE_INTEGER *ReadOffset,
7309 IN ULONG RequestedDataLength,
7310 IN OUT PULONG BytesRead)
7313 NTSTATUS ntStatus = STATUS_SUCCESS;
7316 PIO_STACK_LOCATION pIoStackLocation = NULL;
7317 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7318 FILE_OBJECT *pCacheFileObject = NULL;
7323 pCacheFileObject = AFSReferenceCacheFileObject();
7325 if( pCacheFileObject == NULL)
7327 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7330 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7333 // Initialize the event
7336 KeInitializeEvent( &kEvent,
7337 SynchronizationEvent,
7341 // Allocate an irp for this request. This could also come from a
7342 // private pool, for instance.
7345 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7351 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7355 // Build the IRP's main body
7358 pIrp->UserBuffer = ReadBuffer;
7360 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7361 pIrp->RequestorMode = KernelMode;
7362 pIrp->Flags |= IRP_READ_OPERATION;
7365 // Set up the I/O stack location.
7368 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7369 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7370 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7371 pIoStackLocation->FileObject = pCacheFileObject;
7372 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7374 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7377 // Set the completion routine.
7380 IoSetCompletionRoutine( pIrp,
7388 // Send it to the FSD
7391 ntStatus = IoCallDriver( pTargetDeviceObject,
7394 if( NT_SUCCESS( ntStatus))
7401 ntStatus = KeWaitForSingleObject( &kEvent,
7407 if( NT_SUCCESS( ntStatus))
7410 ntStatus = pIrp->IoStatus.Status;
7412 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7418 if( pCacheFileObject != NULL)
7420 AFSReleaseCacheFileObject( pCacheFileObject);
7426 if( pIrp->MdlAddress != NULL)
7429 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7432 MmUnlockPages( pIrp->MdlAddress);
7435 IoFreeMdl( pIrp->MdlAddress);
7438 pIrp->MdlAddress = NULL;
7452 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7457 UNREFERENCED_PARAMETER(Irp);
7458 UNREFERENCED_PARAMETER(DeviceObject);
7459 KEVENT *pEvent = (KEVENT *)Context;
7465 return STATUS_MORE_PROCESSING_REQUIRED;
7469 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7472 BOOLEAN bIsEmpty = FALSE;
7473 AFSDirectoryCB *pDirEntry = NULL;
7478 ASSERT( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY);
7480 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7485 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7488 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7490 while( pDirEntry != NULL)
7493 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7494 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7502 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7507 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7514 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7515 IN AFSDirectoryCB *DirEntry)
7518 NTSTATUS ntStatus = STATUS_SUCCESS;
7523 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7526 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7527 AFS_TRACE_LEVEL_VERBOSE,
7528 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7530 &DirEntry->NameInformation.FileName));
7532 try_return( ntStatus);
7535 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7538 // Remove the entry from the parent tree
7541 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7542 AFS_TRACE_LEVEL_VERBOSE,
7543 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7545 &DirEntry->NameInformation.FileName));
7547 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7550 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7551 AFS_TRACE_LEVEL_VERBOSE,
7552 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7554 &DirEntry->NameInformation.FileName));
7556 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7559 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7563 // From the short name tree
7566 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7567 AFS_TRACE_LEVEL_VERBOSE,
7568 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7570 &DirEntry->NameInformation.FileName));
7572 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7575 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7578 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7579 AFS_TRACE_LEVEL_VERBOSE,
7580 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7582 &DirEntry->NameInformation.FileName));
7584 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7586 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7597 AFSGetAuthenticationId()
7600 LARGE_INTEGER liAuthId = {0,0};
7601 NTSTATUS ntStatus = STATUS_SUCCESS;
7602 PACCESS_TOKEN hToken = NULL;
7603 PTOKEN_STATISTICS pTokenInfo = NULL;
7604 BOOLEAN bCopyOnOpen = FALSE;
7605 BOOLEAN bEffectiveOnly = FALSE;
7606 BOOLEAN bPrimaryToken = FALSE;
7607 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7612 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7615 &stImpersonationLevel);
7620 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7625 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7626 AFS_TRACE_LEVEL_ERROR,
7627 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n"));
7629 try_return( ntStatus);
7632 bPrimaryToken = TRUE;
7635 ntStatus = SeQueryInformationToken( hToken,
7637 (PVOID *)&pTokenInfo);
7639 if( !NT_SUCCESS( ntStatus))
7642 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7643 AFS_TRACE_LEVEL_ERROR,
7644 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n",
7647 try_return( ntStatus);
7650 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7651 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7653 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7654 AFS_TRACE_LEVEL_VERBOSE,
7655 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7656 liAuthId.QuadPart));
7666 PsDereferenceImpersonationToken( hToken);
7671 PsDereferencePrimaryToken( hToken);
7675 if( pTokenInfo != NULL)
7678 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7686 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7690 UNREFERENCED_PARAMETER(Fcb);
7691 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7693 Fcb->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7696 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7698 Fcb->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7701 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7703 Fcb->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7706 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7708 Fcb->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7711 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7713 Fcb->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7720 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7723 BOOLEAN bIsValid = TRUE;
7725 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7727 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7729 while( pCurrentDirEntry != NULL)
7732 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7736 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7741 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7742 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7745 if( pDirEntry == NULL)
7752 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7755 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
7758 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7760 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7762 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7771 AFSReferenceCacheFileObject()
7774 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7775 FILE_OBJECT *pCacheFileObject = NULL;
7777 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7780 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7782 if( pCacheFileObject != NULL)
7784 ObReferenceObject( pCacheFileObject);
7787 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7789 return pCacheFileObject;
7793 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7796 ASSERT( CacheFileObject != NULL);
7798 ObDereferenceObject( CacheFileObject);
7804 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7807 NTSTATUS ntStatus = STATUS_SUCCESS;
7808 AFSDeviceExt *pControlDevExt = NULL;
7809 ULONG ulTimeIncrement = 0;
7815 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7817 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7819 AFSServerName = LibraryInit->AFSServerName;
7821 AFSMountRootName = LibraryInit->AFSMountRootName;
7823 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7826 // Callbacks in the framework
7829 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7831 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7833 AFSDebugTraceFnc = AFSDbgLogMsg;
7835 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7837 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7839 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
7841 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7843 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7845 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7847 if( LibraryInit->AFSCacheBaseAddress != NULL)
7850 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7852 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7854 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7858 // Initialize some flush parameters
7861 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7863 ulTimeIncrement = KeQueryTimeIncrement();
7865 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7866 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
7867 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7868 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
7869 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7872 // Initialize the global root entry
7875 ntStatus = AFSInitVolume( NULL,
7876 &LibraryInit->GlobalRootFid,
7877 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
7880 if( !NT_SUCCESS( ntStatus))
7883 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7884 AFS_TRACE_LEVEL_ERROR,
7885 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7888 try_return( ntStatus);
7891 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7894 if( !NT_SUCCESS( ntStatus))
7897 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7898 AFS_TRACE_LEVEL_ERROR,
7899 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7902 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7903 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7905 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7906 AFS_TRACE_LEVEL_VERBOSE,
7907 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7911 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7913 try_return( ntStatus);
7917 // Update the node type code to AFS_ROOT_ALL
7920 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7922 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7925 // Invalidate all known volumes since contact with the service and therefore
7926 // the file server was lost.
7929 AFSInvalidateAllVolumes();
7932 // Drop the locks acquired above
7935 AFSInitVolumeWorker( AFSGlobalRoot);
7937 lCount = AFSVolumeDecrement( AFSGlobalRoot,
7938 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
7940 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7941 AFS_TRACE_LEVEL_VERBOSE,
7942 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
7946 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7948 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7962 NTSTATUS ntStatus = STATUS_SUCCESS;
7963 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7969 if( AFSGlobalDotDirEntry != NULL)
7972 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
7973 AFS_OBJECT_REFERENCE_GLOBAL);
7975 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7976 AFS_TRACE_LEVEL_VERBOSE,
7977 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
7978 AFSGlobalDotDirEntry->ObjectInformation,
7984 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
7987 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7989 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry->NonPaged,
7990 AFS_DIR_ENTRY_NP_TAG);
7992 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry,
7995 AFSGlobalDotDirEntry = NULL;
7998 if( AFSGlobalDotDotDirEntry != NULL)
8001 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
8002 AFS_OBJECT_REFERENCE_GLOBAL);
8004 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8005 AFS_TRACE_LEVEL_VERBOSE,
8006 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
8007 AFSGlobalDotDotDirEntry->ObjectInformation,
8013 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
8016 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
8018 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry->NonPaged,
8019 AFS_DIR_ENTRY_NP_TAG);
8021 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry,
8024 AFSGlobalDotDotDirEntry = NULL;
8027 if( AFSSpecialShareNames != NULL)
8030 pDirNode = AFSSpecialShareNames;
8032 while( pDirNode != NULL)
8035 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
8037 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
8038 AFS_OBJECT_REFERENCE_GLOBAL);
8040 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8041 AFS_TRACE_LEVEL_VERBOSE,
8042 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
8043 pDirNode->ObjectInformation,
8049 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
8052 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
8054 AFSLibExFreePoolWithTag( pDirNode->NonPaged,
8055 AFS_DIR_ENTRY_NP_TAG);
8057 AFSLibExFreePoolWithTag( pDirNode,
8060 pDirNode = pLastDirNode;
8063 AFSSpecialShareNames = NULL;
8071 AFSDefaultLogMsg( IN ULONG Subsystem,
8077 UNREFERENCED_PARAMETER(Subsystem);
8078 UNREFERENCED_PARAMETER(Level);
8079 NTSTATUS ntStatus = STATUS_SUCCESS;
8081 char chDebugBuffer[ 256];
8086 va_start( va_args, Format);
8088 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8093 if( NT_SUCCESS( ntStatus))
8095 DbgPrint( chDebugBuffer);
8105 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8106 IN ULONG InputBufferLength,
8107 IN AFSStatusInfoCB *StatusInfo,
8108 OUT ULONG *ReturnLength)
8111 NTSTATUS ntStatus = STATUS_SUCCESS;
8112 AFSVolumeCB *pVolumeCB = NULL;
8113 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8114 AFSVolumeCB *pNewVolumeCB = NULL;
8115 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8116 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8117 AFSObjectInfoCB *pObjectInfo = NULL;
8118 ULONGLONG ullIndex = 0;
8119 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8120 AFSNameArrayHdr *pNameArray = NULL;
8121 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8122 AFSDirectoryCB *pNewParentDirEntry = NULL;
8129 // If we are given a FID then look up the entry by that, otherwise
8133 if( GetStatusInfo->FileID.Cell != 0 &&
8134 GetStatusInfo->FileID.Volume != 0 &&
8135 GetStatusInfo->FileID.Vnode != 0 &&
8136 GetStatusInfo->FileID.Unique != 0)
8139 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8142 // Locate the volume node
8145 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8147 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8149 (AFSBTreeEntry **)&pVolumeCB);
8151 if( pVolumeCB != NULL)
8154 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8156 lCount = AFSVolumeIncrement( pVolumeCB,
8157 VolumeReferenceReason);
8159 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8160 AFS_TRACE_LEVEL_VERBOSE,
8161 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
8163 VolumeReferenceReason,
8167 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8169 if( !NT_SUCCESS( ntStatus) ||
8172 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8175 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8178 pObjectInfo = &pVolumeCB->ObjectInformation;
8180 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8183 lCount = AFSObjectInfoIncrement( pObjectInfo,
8184 AFS_OBJECT_REFERENCE_STATUS);
8186 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8187 AFS_TRACE_LEVEL_VERBOSE,
8188 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8192 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8197 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
8200 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8202 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8204 (AFSBTreeEntry **)&pObjectInfo);
8206 if( pObjectInfo != NULL)
8210 // Reference the node so it won't be torn down
8213 lCount = AFSObjectInfoIncrement( pObjectInfo,
8214 AFS_OBJECT_REFERENCE_STATUS);
8216 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8217 AFS_TRACE_LEVEL_VERBOSE,
8218 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8222 KeQueryTickCount( &pObjectInfo->LastAccessCount);
8225 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8227 if( !NT_SUCCESS( ntStatus) ||
8228 pObjectInfo == NULL)
8230 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8237 if( GetStatusInfo->FileNameLength == 0 ||
8238 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8240 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8243 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8244 uniFullPathName.MaximumLength = uniFullPathName.Length;
8246 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8249 // This name should begin with the \afs server so parse it off and check it
8252 FsRtlDissectName( uniFullPathName,
8256 if( RtlCompareUnicodeString( &uniComponentName,
8260 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8261 AFS_TRACE_LEVEL_ERROR,
8262 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8265 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8268 uniFullPathName = uniRemainingPath;
8270 uniParsedName = uniFullPathName;
8276 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8279 if( pNameArray == NULL)
8281 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8284 pVolumeCB = AFSGlobalRoot;
8286 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8289 // Increment the ref count on the volume and dir entry for correct processing below
8292 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8294 lCount = AFSVolumeIncrement( pVolumeCB,
8295 VolumeReferenceReason);
8297 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8298 AFS_TRACE_LEVEL_VERBOSE,
8299 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8301 VolumeReferenceReason,
8304 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8306 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8307 AFS_TRACE_LEVEL_VERBOSE,
8308 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8309 &pParentDirEntry->NameInformation.FileName,
8314 ntStatus = AFSLocateNameEntry( NULL,
8319 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8320 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8324 &NewVolumeReferenceReason,
8325 &pNewParentDirEntry,
8329 if ( pNewVolumeCB != NULL)
8333 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8334 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8335 // the reference on pVolumeCB that was held prior to the call.
8336 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8337 // will be released second.
8340 lCount = AFSVolumeDecrement( pVolumeCB,
8341 VolumeReferenceReason);
8343 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8344 AFS_TRACE_LEVEL_VERBOSE,
8345 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8347 VolumeReferenceReason,
8350 pVolumeCB = pNewVolumeCB;
8352 pNewVolumeCB = NULL;
8354 VolumeReferenceReason = NewVolumeReferenceReason;
8356 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8360 // AFSLocateNameEntry does not alter the reference count of
8361 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8362 // a reference held.
8365 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8367 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8368 AFS_TRACE_LEVEL_VERBOSE,
8369 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8370 &pParentDirEntry->NameInformation.FileName,
8374 pParentDirEntry = pNewParentDirEntry;
8376 pNewParentDirEntry = NULL;
8378 if( !NT_SUCCESS( ntStatus) ||
8379 ntStatus == STATUS_REPARSE)
8384 try_return( ntStatus);
8387 pObjectInfo = pDirectoryEntry->ObjectInformation;
8389 AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
8392 lCount = AFSObjectInfoIncrement( pObjectInfo,
8393 AFS_OBJECT_REFERENCE_STATUS);
8395 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8396 AFS_TRACE_LEVEL_VERBOSE,
8397 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8401 AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
8405 // At this point we have an object info block, return the information
8408 StatusInfo->FileId = pObjectInfo->FileId;
8410 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8412 StatusInfo->Expiration = pObjectInfo->Expiration;
8414 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8416 StatusInfo->FileType = pObjectInfo->FileType;
8418 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8420 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8422 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8424 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8426 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8428 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8430 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8432 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8434 StatusInfo->EaSize = pObjectInfo->EaSize;
8436 StatusInfo->Links = pObjectInfo->Links;
8439 // Return the information length
8442 *ReturnLength = sizeof( AFSStatusInfoCB);
8446 if( pDirectoryEntry != NULL)
8449 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8451 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8452 AFS_TRACE_LEVEL_VERBOSE,
8453 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8454 &pDirectoryEntry->NameInformation.FileName,
8459 ASSERT( lCount >= 0);
8462 if ( pParentDirEntry != NULL)
8465 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8467 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8468 AFS_TRACE_LEVEL_VERBOSE,
8469 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8470 &pParentDirEntry->NameInformation.FileName,
8475 ASSERT( lCount >= 0);
8478 if( pVolumeCB != NULL)
8481 if( pObjectInfo != NULL)
8484 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8487 lCount = AFSObjectInfoDecrement( pObjectInfo,
8488 AFS_OBJECT_REFERENCE_STATUS);
8490 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8491 AFS_TRACE_LEVEL_VERBOSE,
8492 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8496 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8499 lCount = AFSVolumeDecrement( pVolumeCB,
8500 VolumeReferenceReason);
8502 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8503 AFS_TRACE_LEVEL_VERBOSE,
8504 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8506 VolumeReferenceReason,
8510 if( pNameArray != NULL)
8513 AFSFreeNameArray( pNameArray);
8521 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8522 IN UNICODE_STRING *ComponentName)
8525 NTSTATUS ntStatus = STATUS_SUCCESS;
8526 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8527 AFSDirectoryCB *pDirEntry = NULL;
8535 // Search for the entry in the parent
8538 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8539 AFS_TRACE_LEVEL_VERBOSE_2,
8540 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8543 ulCRC = AFSGenerateCRC( ComponentName,
8546 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8549 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8553 if( pDirEntry == NULL)
8557 // Missed so perform a case insensitive lookup
8560 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8561 AFS_TRACE_LEVEL_VERBOSE_2,
8562 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8565 ulCRC = AFSGenerateCRC( ComponentName,
8568 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8572 if( pDirEntry == NULL)
8576 // OK, if this component is a valid short name then try
8577 // a lookup in the short name tree
8580 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8581 RtlIsNameLegalDOS8Dot3( ComponentName,
8586 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8587 AFS_TRACE_LEVEL_VERBOSE_2,
8588 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8591 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8598 if( pDirEntry != NULL)
8600 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8602 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8603 AFS_TRACE_LEVEL_VERBOSE,
8604 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8605 &pDirEntry->NameInformation.FileName,
8610 ASSERT( lCount >= 0);
8613 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8615 if( pDirEntry == NULL)
8618 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8619 AFS_TRACE_LEVEL_VERBOSE_2,
8620 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8622 STATUS_OBJECT_NAME_NOT_FOUND));
8624 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8628 // We have the symlink object but previously failed to process it so return access
8632 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8633 AFS_TRACE_LEVEL_VERBOSE_2,
8634 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8637 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8639 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8641 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8642 AFS_TRACE_LEVEL_VERBOSE,
8643 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8644 &pDirEntry->NameInformation.FileName,
8649 ASSERT( lCount >= 0);
8660 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8661 OUT UNICODE_STRING *ComponentName)
8664 NTSTATUS ntStatus = STATUS_SUCCESS;
8665 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8667 uniFullPathName = *FullPathName;
8672 FsRtlDissectName( uniFullPathName,
8676 if( uniRemainingPath.Length == 0)
8681 uniFullPathName = uniRemainingPath;
8684 if( uniComponentName.Length > 0)
8686 *ComponentName = uniComponentName;
8693 AFSDumpTraceFiles_Default()
8699 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8702 BOOLEAN bIsValidName = TRUE;
8708 while( usIndex < FileName->Length/sizeof( WCHAR))
8711 if( FileName->Buffer[ usIndex] == L':' ||
8712 FileName->Buffer[ usIndex] == L'*' ||
8713 FileName->Buffer[ usIndex] == L'?' ||
8714 FileName->Buffer[ usIndex] == L'"' ||
8715 FileName->Buffer[ usIndex] == L'<' ||
8716 FileName->Buffer[ usIndex] == L'>')
8718 bIsValidName = FALSE;
8726 return bIsValidName;
8730 AFSCreateDefaultSecurityDescriptor()
8733 NTSTATUS ntStatus = STATUS_SUCCESS;
8735 ULONG ulSACLSize = 0;
8736 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8737 ULONG ulACESize = 0;
8738 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8739 ULONG ulSDLength = 0;
8740 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8741 PSID pWorldSID = NULL;
8742 ULONG *pulSubAuthority = NULL;
8743 ULONG ulWorldSIDLEngth = 0;
8748 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8750 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8752 AFS_GENERIC_MEMORY_29_TAG);
8754 if( pWorldSID == NULL)
8756 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8758 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8761 RtlZeroMemory( pWorldSID,
8764 RtlInitializeSid( pWorldSID,
8765 &SeWorldSidAuthority,
8768 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8769 *pulSubAuthority = SECURITY_WORLD_RID;
8771 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8774 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8779 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8781 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8783 AFS_GENERIC_MEMORY_29_TAG);
8788 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8790 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8793 RtlZeroMemory( pACE,
8796 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8797 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8798 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8799 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8801 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8803 SeExports->SeLowMandatorySid);
8805 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8806 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8808 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8810 AFS_GENERIC_MEMORY_29_TAG);
8815 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8817 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8820 ntStatus = RtlCreateAcl( pSACL,
8824 if( !NT_SUCCESS( ntStatus))
8827 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8830 try_return( ntStatus);
8833 ntStatus = RtlAddAce( pSACL,
8837 pACE->Header.AceSize);
8839 if( !NT_SUCCESS( ntStatus))
8842 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8845 try_return( ntStatus);
8849 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8850 sizeof( SECURITY_DESCRIPTOR),
8851 AFS_GENERIC_MEMORY_27_TAG);
8853 if( pSecurityDescr == NULL)
8856 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8858 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8861 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8862 SECURITY_DESCRIPTOR_REVISION);
8864 if( !NT_SUCCESS( ntStatus))
8867 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8870 try_return( ntStatus);
8873 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8875 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8880 if( !NT_SUCCESS( ntStatus))
8883 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8886 try_return( ntStatus);
8891 // Add in the group and owner to the SD
8894 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8896 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8900 if( !NT_SUCCESS( ntStatus))
8903 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8906 try_return( ntStatus);
8910 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8914 if( !NT_SUCCESS( ntStatus))
8917 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8920 try_return( ntStatus);
8923 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8926 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8928 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8931 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)AFSLibExAllocatePoolWithTag( NonPagedPool,
8933 AFS_GENERIC_MEMORY_27_TAG);
8935 if( pRelativeSecurityDescr == NULL)
8938 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8940 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8943 ulSDLength = PAGE_SIZE;
8945 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8946 pRelativeSecurityDescr,
8949 if( !NT_SUCCESS( ntStatus))
8952 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8955 try_return( ntStatus);
8958 AFSDefaultSD = pRelativeSecurityDescr;
8962 if( !NT_SUCCESS( ntStatus))
8965 if( pRelativeSecurityDescr != NULL)
8968 AFSLibExFreePoolWithTag( pRelativeSecurityDescr,
8969 AFS_GENERIC_MEMORY_27_TAG);
8973 if( pSecurityDescr != NULL)
8976 AFSLibExFreePoolWithTag( pSecurityDescr,
8977 AFS_GENERIC_MEMORY_27_TAG);
8983 AFSLibExFreePoolWithTag( pSACL,
8984 AFS_GENERIC_MEMORY_29_TAG);
8990 AFSLibExFreePoolWithTag( pACE,
8991 AFS_GENERIC_MEMORY_29_TAG);
8994 if( pWorldSID != NULL)
8997 AFSLibExFreePoolWithTag( pWorldSID,
8998 AFS_GENERIC_MEMORY_29_TAG);
9006 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
9007 OUT UNICODE_STRING *ParentPath)
9010 *ParentPath = *FullFileName;
9013 // If the final character is a \, jump over it
9016 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
9018 ParentPath->Length -= sizeof( WCHAR);
9021 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
9023 ParentPath->Length -= sizeof( WCHAR);
9027 // And the separator
9030 ParentPath->Length -= sizeof( WCHAR);
9036 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
9037 IN AFSObjectInfoCB *ObjectInfo,
9038 IN BOOLEAN WriteAccess,
9039 OUT GUID *AuthGroup)
9042 NTSTATUS ntStatus = STATUS_SUCCESS;
9043 GUID stAuthGroup, stZeroAuthGroup;
9044 BOOLEAN bFoundAuthGroup = FALSE;
9045 AFSCcb *pCcb = NULL;
9051 RtlZeroMemory( &stAuthGroup,
9054 RtlZeroMemory( &stZeroAuthGroup,
9060 if( ObjectInfo != NULL &&
9061 ObjectInfo->Fcb != NULL)
9063 pFcb = ObjectInfo->Fcb;
9070 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
9073 pCcb = Fcb->CcbListHead;
9075 while( pCcb != NULL)
9079 pCcb->GrantedAccess & FILE_WRITE_DATA)
9081 RtlCopyMemory( &stAuthGroup,
9085 bFoundAuthGroup = TRUE;
9089 else if( pCcb->GrantedAccess & FILE_READ_DATA)
9092 // At least get the read-only access
9095 RtlCopyMemory( &stAuthGroup,
9099 bFoundAuthGroup = TRUE;
9102 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9105 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9108 if( !bFoundAuthGroup)
9111 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9112 (ULONGLONG)PsGetCurrentThreadId(),
9115 if( RtlCompareMemory( &stZeroAuthGroup,
9117 sizeof( GUID)) == sizeof( GUID))
9120 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9122 try_return( ntStatus = STATUS_ACCESS_DENIED);
9126 RtlCopyMemory( AuthGroup,
9139 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9140 IN ULONG InvalidateReason)
9143 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
9144 NTSTATUS ntStatus = STATUS_SUCCESS;
9150 switch( InvalidateReason)
9153 case AFS_INVALIDATE_DELETED:
9156 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
9157 AFS_TRACE_LEVEL_VERBOSE,
9158 "AFSPerformObjectInvalidation on node type %d for FID %08lX-%08lX-%08lX-%08lX Reason DELETED\n",
9159 ObjectInfo->FileType,
9160 ObjectInfo->FileId.Cell,
9161 ObjectInfo->FileId.Volume,
9162 ObjectInfo->FileId.Vnode,
9163 ObjectInfo->FileId.Unique));
9165 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9166 ObjectInfo->Fcb != NULL)
9169 if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
9172 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9175 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9177 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9182 // Clear out the extents
9183 // And get rid of them (note this involves waiting
9184 // for any writes or reads to the cache to complete)
9187 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9190 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9194 ObjectInfo->Links = 0;
9199 case AFS_INVALIDATE_DATA_VERSION:
9202 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9203 ObjectInfo->Fcb != NULL)
9206 if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
9209 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9210 AFS_TRACE_LEVEL_VERBOSE,
9211 "AFSPerformObjectInvalidate Acquiring Fcb lock %p EXCL %08lX\n",
9212 &ObjectInfo->Fcb->NPFcb->Resource,
9213 PsGetCurrentThread()));
9215 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9218 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9219 AFS_TRACE_LEVEL_VERBOSE,
9220 "AFSPerformObjectInvalidation DirectIO Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9221 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9222 PsGetCurrentThread()));
9224 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9230 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9231 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9237 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9238 AFS_TRACE_LEVEL_WARNING,
9239 "AFSPerformObjectInvalidation DirectIO CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9240 ObjectInfo->FileId.Cell,
9241 ObjectInfo->FileId.Volume,
9242 ObjectInfo->FileId.Vnode,
9243 ObjectInfo->FileId.Unique));
9245 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9248 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9251 ntStatus = GetExceptionCode();
9255 "EXCEPTION - AFSPerformObjectInvalidation DirectIO FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9256 ObjectInfo->FileId.Cell,
9257 ObjectInfo->FileId.Volume,
9258 ObjectInfo->FileId.Vnode,
9259 ObjectInfo->FileId.Unique,
9262 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9265 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9266 AFS_TRACE_LEVEL_VERBOSE,
9267 "AFSPerformObjectInvalidation DirectIO Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9268 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9269 PsGetCurrentThread()));
9271 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9273 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9274 AFS_TRACE_LEVEL_VERBOSE,
9275 "AFSPerformObjectInvalidation DirectIO Releasing Fcb lock %p EXCL %08lX\n",
9276 &ObjectInfo->Fcb->NPFcb->Resource,
9277 PsGetCurrentThread()));
9279 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9285 ULONG ulProcessCount = 0;
9287 LARGE_INTEGER liCurrentOffset = {0,0};
9288 LARGE_INTEGER liFlushLength = {0,0};
9289 ULONG ulFlushLength = 0;
9290 BOOLEAN bLocked = FALSE;
9291 BOOLEAN bExtentsLocked = FALSE;
9292 BOOLEAN bCleanExtents = FALSE;
9294 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9295 AFS_TRACE_LEVEL_VERBOSE,
9296 "AFSPerformObjectInvalidate Acquiring Fcb lock %p EXCL %08lX\n",
9297 &ObjectInfo->Fcb->NPFcb->Resource,
9298 PsGetCurrentThread()));
9300 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9305 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9306 AFS_TRACE_LEVEL_VERBOSE,
9307 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9308 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9309 PsGetCurrentThread()));
9311 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9314 bExtentsLocked = TRUE;
9317 // There are several possibilities here:
9319 // 0. If there are no extents or all of the extents are dirty, do nothing.
9321 // 1. There could be nothing dirty and an open reference count of zero
9322 // in which case we can just tear down all of the extents without
9323 // holding any resources.
9325 // 2. There could be nothing dirty and a non-zero open reference count
9326 // in which case we can issue a CcPurge against the entire file
9327 // while holding just the Fcb Resource.
9329 // 3. There can be dirty extents in which case we need to identify
9330 // the non-dirty ranges and then perform a CcPurge on just the
9331 // non-dirty ranges while holding just the Fcb Resource.
9334 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9337 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9340 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9342 bExtentsLocked = FALSE;
9344 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9347 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9351 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9357 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9358 AFS_TRACE_LEVEL_VERBOSE,
9359 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9360 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9361 PsGetCurrentThread()));
9363 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9369 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9370 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9376 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9377 AFS_TRACE_LEVEL_WARNING,
9378 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9379 ObjectInfo->FileId.Cell,
9380 ObjectInfo->FileId.Volume,
9381 ObjectInfo->FileId.Vnode,
9382 ObjectInfo->FileId.Unique));
9384 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9389 bCleanExtents = TRUE;
9392 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9395 ntStatus = GetExceptionCode();
9399 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9400 ObjectInfo->FileId.Cell,
9401 ObjectInfo->FileId.Volume,
9402 ObjectInfo->FileId.Vnode,
9403 ObjectInfo->FileId.Unique,
9406 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9409 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9410 AFS_TRACE_LEVEL_VERBOSE,
9411 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9412 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9413 PsGetCurrentThread()));
9415 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9417 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9425 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9427 bExtentsLocked = FALSE;
9429 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9430 AFS_TRACE_LEVEL_VERBOSE,
9431 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9432 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9433 PsGetCurrentThread()));
9435 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9439 // Must build a list of non-dirty ranges from the beginning of the file
9440 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9441 // ranges. In all but the most extreme random data write scenario there will
9442 // be significantly fewer.
9444 // For each range we need offset and size.
9447 AFSByteRange * ByteRangeList = NULL;
9448 ULONG ulByteRangeCount = 0;
9450 BOOLEAN bPurgeOnClose = FALSE;
9455 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9458 if ( ByteRangeList != NULL ||
9459 ulByteRangeCount == 0)
9462 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9469 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9471 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9472 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9473 &ByteRangeList[ulIndex].FileOffset,
9478 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9479 AFS_TRACE_LEVEL_WARNING,
9480 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9481 ObjectInfo->FileId.Cell,
9482 ObjectInfo->FileId.Volume,
9483 ObjectInfo->FileId.Vnode,
9484 ObjectInfo->FileId.Unique));
9486 bPurgeOnClose = TRUE;
9491 bCleanExtents = TRUE;
9494 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9496 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9498 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9505 // We couldn't allocate the memory to build the purge list
9506 // so just walk the extent list while holding the ExtentsList Resource.
9507 // This could deadlock but we do not have much choice.
9510 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9512 bExtentsLocked = TRUE;
9514 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9518 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9522 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9524 while( ulProcessCount < ulCount)
9526 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9528 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9530 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9531 &pEntry->FileOffset,
9536 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9537 AFS_TRACE_LEVEL_WARNING,
9538 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9539 ObjectInfo->FileId.Cell,
9540 ObjectInfo->FileId.Volume,
9541 ObjectInfo->FileId.Vnode,
9542 ObjectInfo->FileId.Unique));
9544 bPurgeOnClose = TRUE;
9549 bCleanExtents = TRUE;
9553 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9556 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9558 while( liFlushLength.QuadPart > 0)
9561 if( liFlushLength.QuadPart > 512 * 1024000)
9563 ulFlushLength = 512 * 1024000;
9567 ulFlushLength = liFlushLength.LowPart;
9570 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9576 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9577 AFS_TRACE_LEVEL_WARNING,
9578 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9579 ObjectInfo->FileId.Cell,
9580 ObjectInfo->FileId.Volume,
9581 ObjectInfo->FileId.Vnode,
9582 ObjectInfo->FileId.Unique));
9584 bPurgeOnClose = TRUE;
9589 bCleanExtents = TRUE;
9592 liFlushLength.QuadPart -= ulFlushLength;
9596 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9604 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9610 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9611 AFS_TRACE_LEVEL_WARNING,
9612 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9613 ObjectInfo->FileId.Cell,
9614 ObjectInfo->FileId.Volume,
9615 ObjectInfo->FileId.Vnode,
9616 ObjectInfo->FileId.Unique));
9618 bPurgeOnClose = TRUE;
9623 bCleanExtents = TRUE;
9630 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9634 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9637 ntStatus = GetExceptionCode();
9641 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9642 ObjectInfo->FileId.Cell,
9643 ObjectInfo->FileId.Volume,
9644 ObjectInfo->FileId.Vnode,
9645 ObjectInfo->FileId.Unique,
9649 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9650 AFS_TRACE_LEVEL_VERBOSE,
9651 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9652 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9653 PsGetCurrentThread()));
9655 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9657 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9663 if ( bExtentsLocked)
9666 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9672 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9678 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9689 // Destroy the reference passed in by the caller to AFSInvalidateObject
9690 // or AFSQueueInvalidateObject
9693 AFSAcquireShared( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
9696 lCount = AFSObjectInfoDecrement( ObjectInfo,
9697 AFS_OBJECT_REFERENCE_INVALIDATION);
9699 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
9700 AFS_TRACE_LEVEL_VERBOSE,
9701 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",
9705 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
9712 AFSIgnoreReparsePointToFile( void)
9714 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
9715 BOOLEAN bIgnoreReparsePoint;
9719 bIgnoreReparsePoint = BooleanFlagOn( pDeviceExt->Specific.RDR.ReparsePointPolicy,
9720 AFS_REPARSE_POINT_TO_FILE_AS_FILE);
9723 return bIgnoreReparsePoint;