2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2015 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
16 * nor the names of their contributors may be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission from Kernel Drivers, LLC and Your File System, Inc.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 // File: AFSGeneric.cpp
37 #include "AFSCommon.h"
40 // Function: AFSExceptionFilter
44 // This function is the exception handler
48 // A status is returned for the function
52 AFSExceptionFilter( IN CHAR *FunctionString,
54 IN PEXCEPTION_POINTERS ExceptPtrs)
57 UNREFERENCED_PARAMETER(Code);
58 PEXCEPTION_RECORD ExceptRec;
64 ExceptRec = ExceptPtrs->ExceptionRecord;
66 Context = ExceptPtrs->ContextRecord;
70 "AFSExceptionFilter (Library) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
74 ExceptRec->ExceptionCode,
75 ExceptRec->ExceptionAddress,
76 (void *)AFSExceptionFilter));
78 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
80 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
81 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
83 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
85 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
88 KeBugCheck( (ULONG)-2);
96 __except( EXCEPTION_EXECUTE_HANDLER)
102 return EXCEPTION_EXECUTE_HANDLER;
106 // Function: AFSLibExAllocatePoolWithTag()
108 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
109 // is configured on, then bugcheck the system if
110 // a memory allocation fails. The routine should be
111 // used for all memory allocations that are to be freed
112 // when the library is unloaded. Memory allocations that
113 // are to survive library unload and reload should be
114 // performed using AFSExAllocatePoolWithTag() which is
115 // provided by the AFS Framework.
118 // POOL_TYPE PoolType - Paged or NonPaged
119 // SIZE_T NumberOfBytes - requested allocation size
120 // ULONG Tag - Pool Allocation Tag to be applied for tracking
123 // void * - the memory allocation
127 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
128 IN SIZE_T NumberOfBytes,
132 void *pBuffer = NULL;
134 pBuffer = ExAllocatePoolWithTag( PoolType,
141 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
144 KeBugCheck( (ULONG)-2);
151 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
155 PsGetCurrentThread()));
165 // Function: AFSAcquireExcl()
167 // Purpose: Called to acquire a resource exclusive with optional wait
170 // PERESOURCE Resource - Resource to acquire
171 // BOOLEAN Wait - Whether to block
174 // BOOLEAN - Whether the mask was acquired
178 AFSAcquireExcl( IN PERESOURCE Resource,
182 BOOLEAN bStatus = FALSE;
185 // Normal kernel APCs must be disabled before calling
186 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
189 KeEnterCriticalRegion();
191 bStatus = ExAcquireResourceExclusiveLite( Resource,
197 KeLeaveCriticalRegion();
204 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
208 BOOLEAN bStatus = FALSE;
210 KeEnterCriticalRegion();
212 bStatus = ExAcquireSharedStarveExclusive( Resource,
218 KeLeaveCriticalRegion();
225 // Function: AFSAcquireShared()
227 // Purpose: Called to acquire a resource shared with optional wait
230 // PERESOURCE Resource - Resource to acquire
231 // BOOLEAN Wait - Whether to block
234 // BOOLEAN - Whether the mask was acquired
238 AFSAcquireShared( IN PERESOURCE Resource,
242 BOOLEAN bStatus = FALSE;
244 KeEnterCriticalRegion();
246 bStatus = ExAcquireResourceSharedLite( Resource,
252 KeLeaveCriticalRegion();
259 // Function: AFSReleaseResource()
261 // Purpose: Called to release a resource
264 // PERESOURCE Resource - Resource to release
271 AFSReleaseResource( IN PERESOURCE Resource)
274 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
275 AFS_TRACE_LEVEL_VERBOSE,
276 "AFSReleaseResource Releasing lock %p Thread %08lX\n",
278 PsGetCurrentThread()));
280 ExReleaseResourceLite( Resource);
282 KeLeaveCriticalRegion();
288 AFSConvertToShared( IN PERESOURCE Resource)
291 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
292 AFS_TRACE_LEVEL_VERBOSE,
293 "AFSConvertToShared Converting lock %p Thread %08lX\n",
295 PsGetCurrentThread()));
297 ExConvertExclusiveToSharedLite( Resource);
303 // Function: AFSCompleteRequest
307 // This function completes irps
311 // A status is returned for the function
315 AFSCompleteRequest( IN PIRP Irp,
319 Irp->IoStatus.Status = Status;
321 IoCompleteRequest( Irp,
328 // Function: AFSGenerateCRC
332 // Given a device and filename this function generates a CRC
336 // A status is returned for the function
340 AFSGenerateCRC( IN PUNICODE_STRING FileName,
341 IN BOOLEAN UpperCaseName)
345 NTSTATUS ntStatus = STATUS_SUCCESS;
347 ntStatus = RtlHashUnicodeString( FileName,
349 HASH_STRING_ALGORITHM_DEFAULT,
352 if( !NT_SUCCESS( ntStatus))
361 AFSLockSystemBuffer( IN PIRP Irp,
365 void *pAddress = NULL;
367 if( Irp->MdlAddress != NULL)
370 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress,
373 else if( Irp->AssociatedIrp.SystemBuffer != NULL)
376 pAddress = Irp->AssociatedIrp.SystemBuffer;
378 else if( Irp->UserBuffer != NULL)
381 Irp->MdlAddress = IoAllocateMdl( Irp->UserBuffer,
387 if( Irp->MdlAddress != NULL)
391 // Lock the new Mdl in memory.
396 PIO_STACK_LOCATION pIoStack;
397 pIoStack = IoGetCurrentIrpStackLocation( Irp);
400 MmProbeAndLockPages( Irp->MdlAddress, KernelMode,
401 (pIoStack->MajorFunction == IRP_MJ_READ) ? IoWriteAccess : IoReadAccess);
403 pAddress = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
406 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
409 AFSDumpTraceFilesFnc();
411 IoFreeMdl( Irp->MdlAddress );
412 Irp->MdlAddress = NULL;
422 AFSLockUserBuffer( IN void *UserBuffer,
423 IN ULONG BufferLength,
427 NTSTATUS ntStatus = STATUS_SUCCESS;
428 void *pAddress = NULL;
434 pMdl = IoAllocateMdl( UserBuffer,
443 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
447 // Lock the new Mdl in memory.
453 MmProbeAndLockPages( pMdl,
457 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
460 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
463 AFSDumpTraceFilesFnc();
485 AFSMapToService( IN PIRP Irp,
489 NTSTATUS ntStatus = STATUS_SUCCESS;
490 void *pMappedBuffer = NULL;
491 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
497 if( pDevExt->Specific.Control.ServiceProcess == NULL)
500 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
503 if( Irp->MdlAddress == NULL)
506 if( AFSLockSystemBuffer( Irp,
510 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
515 // Attach to the service process for mapping
518 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
519 (PRKAPC_STATE)&stApcState);
521 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
528 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
535 return pMappedBuffer;
539 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
543 NTSTATUS ntStatus = STATUS_SUCCESS;
544 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
550 if( pDevExt->Specific.Control.ServiceProcess == NULL)
553 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
560 // Attach to the service process for mapping
563 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
564 (PRKAPC_STATE)&stApcState);
566 MmUnmapLockedPages( MappedBuffer,
569 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
581 AFSInitializeLibraryDevice()
584 NTSTATUS ntStatus = STATUS_SUCCESS;
585 AFSDeviceExt *pDeviceExt = NULL;
590 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
593 // The PIOCtl file name
596 RtlInitUnicodeString( &AFSPIOCtlName,
597 AFS_PIOCTL_FILE_INTERFACE_NAME);
600 // And the global root share name
603 RtlInitUnicodeString( &AFSGlobalRootName,
604 AFS_GLOBAL_ROOT_SHARE_NAME);
612 AFSRemoveLibraryDevice()
615 NTSTATUS ntStatus = STATUS_SUCCESS;
626 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
630 UNREFERENCED_PARAMETER(DeviceObject);
631 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
633 AFSCompleteRequest( Irp,
640 AFSInitializeGlobalDirectoryEntries()
643 NTSTATUS ntStatus = STATUS_SUCCESS;
644 AFSDirectoryCB *pDirNode = NULL;
645 ULONG ulEntryLength = 0;
646 AFSObjectInfoCB *pObjectInfoCB = NULL;
647 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
654 // Initialize the global . entry
657 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
660 if( pObjectInfoCB == NULL)
663 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
664 AFS_TRACE_LEVEL_ERROR,
665 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
668 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
671 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
672 AFS_OBJECT_REFERENCE_GLOBAL);
674 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
675 AFS_TRACE_LEVEL_VERBOSE,
676 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
680 ntStatus = STATUS_SUCCESS;
682 ulEntryLength = sizeof( AFSDirectoryCB) +
685 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
689 if( pDirNode == NULL)
692 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
693 AFS_OBJECT_REFERENCE_GLOBAL);
695 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
696 AFS_TRACE_LEVEL_VERBOSE,
697 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
704 AFSDeleteObjectInfo( &pObjectInfoCB);
707 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
708 AFS_TRACE_LEVEL_ERROR,
709 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n"));
711 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
714 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
715 AFS_TRACE_LEVEL_VERBOSE,
716 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocated %p\n",
719 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
720 sizeof( AFSNonPagedDirectoryCB),
721 AFS_DIR_ENTRY_NP_TAG);
723 if( pNonPagedDirEntry == NULL)
726 AFSLibExFreePoolWithTag( pDirNode,
729 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
730 AFS_OBJECT_REFERENCE_GLOBAL);
732 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
733 AFS_TRACE_LEVEL_VERBOSE,
734 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
741 AFSDeleteObjectInfo( &pObjectInfoCB);
744 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
745 AFS_TRACE_LEVEL_ERROR,
746 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n"));
748 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
751 RtlZeroMemory( pDirNode,
754 RtlZeroMemory( pNonPagedDirEntry,
755 sizeof( AFSNonPagedDirectoryCB));
757 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
759 pDirNode->NonPaged = pNonPagedDirEntry;
761 pDirNode->ObjectInformation = pObjectInfoCB;
767 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
769 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
772 // Setup the names in the entry
775 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
777 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
779 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
781 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
784 // Populate the rest of the data
787 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
789 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
791 AFSGlobalDotDirEntry = pDirNode;
797 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
800 if( pObjectInfoCB == NULL)
803 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
804 AFS_TRACE_LEVEL_ERROR,
805 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
808 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
811 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
812 AFS_OBJECT_REFERENCE_GLOBAL);
814 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
815 AFS_TRACE_LEVEL_VERBOSE,
816 "AFSInitializeGlobalDirectoryEntries Increment count on object %p Cnt %d\n",
820 ntStatus = STATUS_SUCCESS;
822 ulEntryLength = sizeof( AFSDirectoryCB) +
823 ( 2 * sizeof( WCHAR));
825 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
829 if( pDirNode == NULL)
832 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING | AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
833 AFS_TRACE_LEVEL_ERROR,
834 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocation failure\n"));
836 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
837 AFS_OBJECT_REFERENCE_GLOBAL);
839 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
840 AFS_TRACE_LEVEL_VERBOSE,
841 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
848 AFSDeleteObjectInfo( &pObjectInfoCB);
851 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
854 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
855 AFS_TRACE_LEVEL_VERBOSE,
856 "AFSInitializeGlobalDirectoryEntries AFS_DIR_ENTRY_TAG allocated %p\n",
859 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
860 sizeof( AFSNonPagedDirectoryCB),
861 AFS_DIR_ENTRY_NP_TAG);
863 if( pNonPagedDirEntry == NULL)
866 AFSLibExFreePoolWithTag( pDirNode,
869 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
870 AFS_OBJECT_REFERENCE_GLOBAL);
872 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
873 AFS_TRACE_LEVEL_VERBOSE,
874 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
881 AFSDeleteObjectInfo( &pObjectInfoCB);
884 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
887 RtlZeroMemory( pDirNode,
890 RtlZeroMemory( pNonPagedDirEntry,
891 sizeof( AFSNonPagedDirectoryCB));
893 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
895 pDirNode->NonPaged = pNonPagedDirEntry;
897 pDirNode->ObjectInformation = pObjectInfoCB;
903 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
905 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
908 // Setup the names in the entry
911 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
913 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
915 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
917 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
919 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
922 // Populate the rest of the data
925 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
927 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
929 AFSGlobalDotDotDirEntry = pDirNode;
933 if( !NT_SUCCESS( ntStatus))
936 if( AFSGlobalDotDirEntry != NULL)
939 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
940 AFS_OBJECT_REFERENCE_GLOBAL);
942 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
943 AFS_TRACE_LEVEL_VERBOSE,
944 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
945 AFSGlobalDotDirEntry->ObjectInformation,
951 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
954 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
956 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry->NonPaged,
957 AFS_DIR_ENTRY_NP_TAG);
959 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry,
962 AFSGlobalDotDirEntry = NULL;
965 if( AFSGlobalDotDotDirEntry != NULL)
968 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
969 AFS_OBJECT_REFERENCE_GLOBAL);
971 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
972 AFS_TRACE_LEVEL_VERBOSE,
973 "AFSInitializeGlobalDirectoryEntries Decrement count on object %p Cnt %d\n",
974 AFSGlobalDotDotDirEntry->ObjectInformation,
980 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
983 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
985 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry->NonPaged,
986 AFS_DIR_ENTRY_NP_TAG);
988 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry,
991 AFSGlobalDotDotDirEntry = NULL;
1000 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
1001 IN PUNICODE_STRING FileName,
1002 IN PUNICODE_STRING TargetName,
1003 IN AFSDirEnumEntry *DirEnumEntry,
1007 AFSDirectoryCB *pDirNode = NULL;
1008 NTSTATUS ntStatus = STATUS_SUCCESS;
1009 ULONG ulEntryLength = 0;
1010 AFSObjectInfoCB *pObjectInfoCB = NULL;
1011 ULONGLONG ullIndex = 0;
1012 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
1018 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1019 AFS_TRACE_LEVEL_VERBOSE,
1020 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
1022 ParentObjectInfo->FileId.Cell,
1023 ParentObjectInfo->FileId.Volume,
1024 ParentObjectInfo->FileId.Vnode,
1025 ParentObjectInfo->FileId.Unique));
1028 // First thing is to locate/create our object information block
1032 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
1035 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
1037 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
1039 (AFSBTreeEntry **)&pObjectInfoCB);
1041 if( !NT_SUCCESS( ntStatus))
1045 // Allocate our object info cb
1048 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
1051 if( pObjectInfoCB == NULL)
1054 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1056 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1059 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1060 AFS_TRACE_LEVEL_VERBOSE,
1061 "AFSInitDirEntry initialized object %p Parent Object %p for %wZ\n",
1067 // If we allocated the object information cb then set the information
1070 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1072 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1074 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1076 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1078 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1079 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1082 pObjectInfoCB->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1085 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK)
1088 if ( pObjectInfoCB->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1091 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1096 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1101 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1102 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1106 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1107 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1108 pObjectInfoCB->TargetFileId.Unique == 0 &&
1109 (TargetName == NULL || TargetName->Length == 0))
1113 // This will ensure we perform a validation on the node
1116 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1119 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1122 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1125 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1128 if ( BooleanFlagOn( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY))
1131 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1133 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1135 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1137 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1139 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1141 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1143 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1145 pObjectInfoCB->Links = DirEnumEntry->Links;
1147 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1149 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1151 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1152 AFS_TRACE_LEVEL_VERBOSE,
1153 "AFSInitDirEntry FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
1154 pObjectInfoCB->FileId.Cell,
1155 pObjectInfoCB->FileId.Volume,
1156 pObjectInfoCB->FileId.Vnode,
1157 pObjectInfoCB->FileId.Unique));
1159 ClearFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_VERIFY);
1163 // This reference count is either stored into the return DirectoryCB
1164 // or released before function exit.
1167 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
1168 AFS_OBJECT_REFERENCE_DIRENTRY);
1170 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1171 AFS_TRACE_LEVEL_VERBOSE,
1172 "AFSInitDirEntry Increment count on object %p Cnt %d\n",
1176 KeQueryTickCount( &pObjectInfoCB->LastAccessCount);
1178 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
1180 ntStatus = STATUS_SUCCESS;
1182 ulEntryLength = sizeof( AFSDirectoryCB) +
1185 if( TargetName != NULL)
1188 ulEntryLength += TargetName->Length;
1191 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
1195 if( pDirNode == NULL)
1198 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1201 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1202 AFS_TRACE_LEVEL_VERBOSE,
1203 "AFSInitDirEntry AFS_DIR_ENTRY_TAG allocated %p\n",
1206 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1207 sizeof( AFSNonPagedDirectoryCB),
1208 AFS_DIR_ENTRY_NP_TAG);
1210 if( pNonPagedDirEntry == NULL)
1213 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1216 RtlZeroMemory( pDirNode,
1219 RtlZeroMemory( pNonPagedDirEntry,
1220 sizeof( AFSNonPagedDirectoryCB));
1222 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1224 pDirNode->NonPaged = pNonPagedDirEntry;
1226 pDirNode->ObjectInformation = pObjectInfoCB;
1229 // Set valid entry and NOT_IN_PARENT flag
1232 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1234 pDirNode->FileIndex = FileIndex;
1237 // Setup the names in the entry
1240 if( FileName->Length > 0)
1243 pDirNode->NameInformation.FileName.Length = FileName->Length;
1245 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1247 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1249 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1251 pDirNode->NameInformation.FileName.Length);
1254 // Create a CRC for the file
1257 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1260 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1264 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1265 AFS_TRACE_LEVEL_VERBOSE,
1266 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1269 ParentObjectInfo->FileId.Cell,
1270 ParentObjectInfo->FileId.Volume,
1271 ParentObjectInfo->FileId.Vnode,
1272 ParentObjectInfo->FileId.Unique));
1274 if( TargetName != NULL &&
1275 TargetName->Length > 0)
1278 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1280 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1282 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1283 sizeof( AFSDirectoryCB) +
1284 pDirNode->NameInformation.FileName.Length);
1286 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1288 pDirNode->NameInformation.TargetName.Length);
1294 if( !NT_SUCCESS( ntStatus))
1297 if( pNonPagedDirEntry != NULL)
1300 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1302 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
1305 if( pDirNode != NULL)
1308 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
1309 AFS_TRACE_LEVEL_VERBOSE,
1310 "AFSInitDirEntry AFS_DIR_ENTRY_TAG deallocating %p\n",
1313 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
1319 // Dereference our object info block if we have one
1322 if( pObjectInfoCB != NULL)
1325 AFSAcquireShared( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock,
1328 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
1329 AFS_OBJECT_REFERENCE_DIRENTRY);
1331 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1332 AFS_TRACE_LEVEL_VERBOSE,
1333 "AFSInitDirEntry Decrement count on object %p Cnt %d\n",
1337 AFSReleaseResource( pObjectInfoCB->VolumeCB->ObjectInfoTree.TreeLock);
1346 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1347 IN BOOLEAN DirectoryEntry)
1350 BOOLEAN bReturn = TRUE;
1351 ACCESS_MASK stAccessMask = 0;
1354 // Get rid of anything we don't know about
1357 DesiredAccess = (DesiredAccess &
1363 ACCESS_SYSTEM_SECURITY |
1367 FILE_READ_ATTRIBUTES |
1368 FILE_WRITE_ATTRIBUTES |
1369 FILE_LIST_DIRECTORY |
1375 // Our 'read only' access mask. These are the accesses we will
1376 // allow for a read only file
1379 stAccessMask = DELETE |
1384 ACCESS_SYSTEM_SECURITY |
1388 FILE_READ_ATTRIBUTES |
1389 FILE_WRITE_ATTRIBUTES |
1391 FILE_LIST_DIRECTORY |
1395 // For a directory, add in the directory specific accesses
1401 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1406 if( FlagOn( DesiredAccess, ~stAccessMask))
1410 // A write access is set ...
1420 AFSEvaluateNode( IN GUID *AuthGroup,
1421 IN AFSDirectoryCB *DirEntry)
1424 NTSTATUS ntStatus = STATUS_SUCCESS;
1425 AFSDirEnumEntry *pDirEntry = NULL;
1426 UNICODE_STRING uniTargetName;
1431 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1436 if( !NT_SUCCESS( ntStatus))
1439 try_return( ntStatus);
1442 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1444 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1446 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1448 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1450 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1452 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1454 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1456 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1458 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1460 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1462 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1464 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1465 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1468 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1471 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1474 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1477 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1482 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1486 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1488 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1491 // If we have a target name then see if it needs updating ...
1494 if( pDirEntry->TargetNameLength > 0)
1498 // Update the target name information if needed
1501 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1503 uniTargetName.MaximumLength = uniTargetName.Length;
1505 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1507 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1510 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1511 RtlCompareUnicodeString( &uniTargetName,
1512 &DirEntry->NameInformation.TargetName,
1517 // Update the target name
1520 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1522 uniTargetName.Buffer,
1523 uniTargetName.Length);
1525 if( !NT_SUCCESS( ntStatus))
1528 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1530 try_return( ntStatus);
1534 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1539 if( pDirEntry != NULL)
1542 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1550 AFSValidateSymLink( IN GUID *AuthGroup,
1551 IN AFSDirectoryCB *DirEntry)
1554 NTSTATUS ntStatus = STATUS_SUCCESS;
1555 AFSDirEnumEntry *pDirEntry = NULL;
1556 UNICODE_STRING uniTargetName;
1561 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1566 if( !NT_SUCCESS( ntStatus))
1569 try_return( ntStatus);
1572 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1573 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1576 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1577 AFS_TRACE_LEVEL_VERBOSE_2,
1578 "AFSValidateSymLink Invalid type Status %08lX\n",
1579 STATUS_OBJECT_NAME_NOT_FOUND));
1581 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1584 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1586 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1588 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1591 // Update the target name information if needed
1594 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1596 uniTargetName.MaximumLength = uniTargetName.Length;
1598 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1600 if( uniTargetName.Length > 0)
1603 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1606 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1607 RtlCompareUnicodeString( &uniTargetName,
1608 &DirEntry->NameInformation.TargetName,
1613 // Update the target name
1616 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1618 uniTargetName.Buffer,
1619 uniTargetName.Length);
1621 if( !NT_SUCCESS( ntStatus))
1624 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1626 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1630 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1634 // If the FileType is the same then nothing to do since it IS
1638 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1641 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1643 try_return( ntStatus = STATUS_SUCCESS);
1646 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1648 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1650 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1652 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1654 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1656 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1658 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1660 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1662 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1663 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1666 DirEntry->ObjectInformation->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1669 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK)
1672 if ( DirEntry->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
1675 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1680 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1684 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1686 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1690 if( pDirEntry != NULL)
1693 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
1701 AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
1705 NTSTATUS ntStatus = STATUS_SUCCESS;
1706 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1707 IO_STATUS_BLOCK stIoStatus;
1709 AFSObjectInfoCB * pParentObjectInfo = NULL;
1711 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1712 AFS_TRACE_LEVEL_VERBOSE,
1713 "AFSInvalidateObject Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1714 (*ppObjectInfo)->FileType,
1715 (*ppObjectInfo)->FileId.Cell,
1716 (*ppObjectInfo)->FileId.Volume,
1717 (*ppObjectInfo)->FileId.Vnode,
1718 (*ppObjectInfo)->FileId.Unique,
1721 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1724 pParentObjectInfo = AFSFindObjectInfo( (*ppObjectInfo)->VolumeCB,
1725 &(*ppObjectInfo)->ParentFileId,
1729 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_SYMLINK ||
1730 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DFSLINK ||
1731 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1734 // We only act on the mount point itself, not the target. If the
1735 // node has been deleted then mark it as such otherwise indicate
1736 // it requires verification
1739 if( Reason == AFS_INVALIDATE_DELETED)
1741 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1746 if( Reason == AFS_INVALIDATE_FLUSHED)
1749 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1752 (*ppObjectInfo)->Expiration.QuadPart = 0;
1754 (*ppObjectInfo)->TargetFileId.Vnode = 0;
1756 (*ppObjectInfo)->TargetFileId.Unique = 0;
1758 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1759 AFS_TRACE_LEVEL_VERBOSE,
1760 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1761 (*ppObjectInfo)->FileId.Cell,
1762 (*ppObjectInfo)->FileId.Volume,
1763 (*ppObjectInfo)->FileId.Vnode,
1764 (*ppObjectInfo)->FileId.Unique));
1766 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
1769 if ( pParentObjectInfo != NULL)
1772 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1774 if( Reason == AFS_INVALIDATE_CREDS)
1776 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1779 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
1780 Reason == AFS_INVALIDATE_FLUSHED)
1782 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1786 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1789 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1792 FILE_ACTION_MODIFIED);
1795 try_return( ntStatus);
1799 // Depending on the reason for invalidation then perform work on the node
1805 case AFS_INVALIDATE_DELETED:
1809 // Mark this node as invalid
1812 (*ppObjectInfo)->Links = 0;
1814 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_DELETED);
1816 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1817 AFS_TRACE_LEVEL_VERBOSE,
1818 "AFSInvalidateObject Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1819 (*ppObjectInfo)->FileId.Cell,
1820 (*ppObjectInfo)->FileId.Volume,
1821 (*ppObjectInfo)->FileId.Vnode,
1822 (*ppObjectInfo)->FileId.Unique));
1824 if( pParentObjectInfo != NULL)
1827 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1828 AFS_TRACE_LEVEL_VERBOSE,
1829 "AFSInvalidateObject Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1830 pParentObjectInfo->FileId.Cell,
1831 pParentObjectInfo->FileId.Volume,
1832 pParentObjectInfo->FileId.Vnode,
1833 pParentObjectInfo->FileId.Unique));
1835 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1837 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1839 pParentObjectInfo->Expiration.QuadPart = 0;
1841 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
1843 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1847 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1850 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1853 FILE_ACTION_REMOVED);
1856 if( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
1859 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
1865 case AFS_INVALIDATE_FLUSHED:
1868 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
1869 (*ppObjectInfo)->Fcb != NULL)
1872 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1873 AFS_TRACE_LEVEL_VERBOSE,
1874 "AFSInvalidateObject Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1875 (*ppObjectInfo)->FileId.Cell,
1876 (*ppObjectInfo)->FileId.Volume,
1877 (*ppObjectInfo)->FileId.Vnode,
1878 (*ppObjectInfo)->FileId.Unique));
1880 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1881 AFS_TRACE_LEVEL_VERBOSE,
1882 "AFSInvalidateObject Flush/purge Acquiring Fcb lock %p EXCL %08lX\n",
1883 &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1884 PsGetCurrentThread()));
1886 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1889 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1890 AFS_TRACE_LEVEL_VERBOSE,
1891 "AFSInvalidateObject Flush/purge Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
1892 &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1893 PsGetCurrentThread()));
1895 AFSAcquireExcl( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1901 CcFlushCache( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1906 if( !NT_SUCCESS( stIoStatus.Status))
1909 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1910 AFS_TRACE_LEVEL_ERROR,
1911 "AFSInvalidateObject CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1912 (*ppObjectInfo)->FileId.Cell,
1913 (*ppObjectInfo)->FileId.Volume,
1914 (*ppObjectInfo)->FileId.Vnode,
1915 (*ppObjectInfo)->FileId.Unique,
1917 stIoStatus.Information));
1919 ntStatus = stIoStatus.Status;
1923 if ( (*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
1926 if ( !CcPurgeCacheSection( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectPointers,
1932 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1933 AFS_TRACE_LEVEL_WARNING,
1934 "AFSInvalidateObject CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
1935 (*ppObjectInfo)->FileId.Cell,
1936 (*ppObjectInfo)->FileId.Volume,
1937 (*ppObjectInfo)->FileId.Vnode,
1938 (*ppObjectInfo)->FileId.Unique));
1940 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1944 __except( EXCEPTION_EXECUTE_HANDLER)
1947 ntStatus = GetExceptionCode();
1951 "EXCEPTION - AFSInvalidateObject Cc FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
1952 (*ppObjectInfo)->FileId.Cell,
1953 (*ppObjectInfo)->FileId.Volume,
1954 (*ppObjectInfo)->FileId.Vnode,
1955 (*ppObjectInfo)->FileId.Unique,
1958 SetFlag( (*ppObjectInfo)->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
1961 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
1962 AFS_TRACE_LEVEL_VERBOSE,
1963 "AFSInvalidateObject Flush/purge Releasing Fcb SectionObject lock %p EXCL %08lX\n",
1964 &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource,
1965 PsGetCurrentThread()));
1967 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->SectionObjectResource);
1969 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1970 AFS_TRACE_LEVEL_VERBOSE,
1971 "AFSInvalidateObject Flush/purge Releasing Fcb lock %p EXCL %08lX\n",
1972 &(*ppObjectInfo)->Fcb->NPFcb->Resource,
1973 PsGetCurrentThread()));
1975 AFSReleaseResource( &(*ppObjectInfo)->Fcb->NPFcb->Resource);
1977 if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
1981 // Clear out the extents
1982 // Get rid of them (note this involves waiting
1983 // for any writes or reads to the cache to complete)
1986 AFSTearDownFcbExtents( (*ppObjectInfo)->Fcb,
1991 (*ppObjectInfo)->DataVersion.QuadPart = (ULONGLONG)-1;
1994 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE)
1997 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1998 AFS_TRACE_LEVEL_VERBOSE,
1999 "AFSInvalidateObject Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
2000 (*ppObjectInfo)->FileId.Cell,
2001 (*ppObjectInfo)->FileId.Volume,
2002 (*ppObjectInfo)->FileId.Vnode,
2003 (*ppObjectInfo)->FileId.Unique));
2005 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2008 // Fall through to the default processing
2014 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
2016 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2020 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2023 if( Reason == AFS_INVALIDATE_CREDS)
2025 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2028 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2030 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2034 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2037 if( (*ppObjectInfo)->FileType == AFS_FILE_TYPE_DIRECTORY)
2040 AFSFsRtlNotifyFullReportChange( (*ppObjectInfo),
2043 FILE_ACTION_MODIFIED);
2045 else if ( pParentObjectInfo != NULL)
2048 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2051 FILE_ACTION_MODIFIED);
2055 // Indicate this node requires re-evaluation for the remaining reasons
2058 (*ppObjectInfo)->Expiration.QuadPart = 0;
2060 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2061 AFS_TRACE_LEVEL_VERBOSE,
2062 "AFSInvalidateObject Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2063 (*ppObjectInfo)->FileId.Cell,
2064 (*ppObjectInfo)->FileId.Volume,
2065 (*ppObjectInfo)->FileId.Vnode,
2066 (*ppObjectInfo)->FileId.Unique));
2068 SetFlag( (*ppObjectInfo)->Flags, AFS_OBJECT_FLAGS_VERIFY);
2070 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2071 (*ppObjectInfo)->FileType == AFS_FILE_TYPE_FILE &&
2072 ( Reason == AFS_INVALIDATE_CALLBACK ||
2073 Reason == AFS_INVALIDATE_EXPIRED))
2075 if ( NT_SUCCESS( AFSQueueInvalidateObject( (*ppObjectInfo),
2076 AFS_INVALIDATE_DATA_VERSION)))
2079 (*ppObjectInfo) = NULL; // We'll dec the count in the worker item
2089 if ( pParentObjectInfo != NULL)
2092 AFSReleaseObjectInfo( &pParentObjectInfo);
2099 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
2102 NTSTATUS ntStatus = STATUS_SUCCESS;
2103 AFSVolumeCB *pVolumeCB = NULL;
2104 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2105 ULONGLONG ullIndex = 0;
2106 AFSObjectInfoCB *pObjectInfo = NULL;
2112 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2113 AFS_TRACE_LEVEL_VERBOSE,
2114 "AFSInvalidateCache Invalidation FID %08lX-%08lX-%08lX-%08lX Type %d WholeVolume %d Reason %d\n",
2115 InvalidateCB->FileID.Cell,
2116 InvalidateCB->FileID.Volume,
2117 InvalidateCB->FileID.Vnode,
2118 InvalidateCB->FileID.Unique,
2119 InvalidateCB->FileType,
2120 InvalidateCB->WholeVolume,
2121 InvalidateCB->Reason));
2124 // Need to locate the Fcb for the directory to purge
2127 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2128 AFS_TRACE_LEVEL_VERBOSE,
2129 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
2130 &pDevExt->Specific.RDR.VolumeTreeLock,
2131 PsGetCurrentThread()));
2134 // Starve any exclusive waiters on this paticular call
2137 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
2140 // Locate the volume node
2143 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
2145 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
2147 (AFSBTreeEntry **)&pVolumeCB);
2149 if( pVolumeCB != NULL)
2152 lCount = AFSVolumeIncrement( pVolumeCB,
2153 AFS_VOLUME_REFERENCE_INVALIDATE);
2155 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2156 AFS_TRACE_LEVEL_VERBOSE,
2157 "AFSInvalidateCache Increment count on volume %p Cnt %d\n",
2162 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
2164 if( !NT_SUCCESS( ntStatus) ||
2168 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2169 AFS_TRACE_LEVEL_WARNING,
2170 "AFSInvalidateCache Invalidation FAILURE Unable to locate volume node FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2171 InvalidateCB->FileID.Cell,
2172 InvalidateCB->FileID.Volume,
2173 InvalidateCB->FileID.Vnode,
2174 InvalidateCB->FileID.Unique,
2177 try_return( ntStatus = STATUS_SUCCESS);
2181 // If this is a whole volume invalidation then go do it now
2184 if( InvalidateCB->WholeVolume)
2187 ntStatus = AFSInvalidateVolume( pVolumeCB,
2188 InvalidateCB->Reason);
2190 try_return( ntStatus);
2193 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
2196 if ( AFSIsVolumeFID( &InvalidateCB->FileID))
2199 pObjectInfo = &pVolumeCB->ObjectInformation;
2204 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
2206 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
2208 (AFSBTreeEntry **)&pObjectInfo);
2211 if( pObjectInfo != NULL)
2215 // Reference the node so it won't be torn down
2218 lCount = AFSObjectInfoIncrement( pObjectInfo,
2219 AFS_OBJECT_REFERENCE_INVALIDATION);
2221 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2222 AFS_TRACE_LEVEL_VERBOSE,
2223 "AFSInvalidateCache Increment count on object %p Cnt %d\n",
2228 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
2230 if( !NT_SUCCESS( ntStatus) ||
2231 pObjectInfo == NULL)
2234 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2235 AFS_TRACE_LEVEL_VERBOSE,
2236 "AFSInvalidateCache Invalidation FAILURE Unable to locate object FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2237 InvalidateCB->FileID.Cell,
2238 InvalidateCB->FileID.Volume,
2239 InvalidateCB->FileID.Vnode,
2240 InvalidateCB->FileID.Unique,
2243 try_return( ntStatus = STATUS_SUCCESS);
2246 AFSInvalidateObject( &pObjectInfo,
2247 InvalidateCB->Reason);
2251 if( pObjectInfo != NULL)
2254 lCount = AFSObjectInfoDecrement( pObjectInfo,
2255 AFS_OBJECT_REFERENCE_INVALIDATION);
2257 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2258 AFS_TRACE_LEVEL_VERBOSE,
2259 "AFSInvalidateCache Decrement count on object %p Cnt %d\n",
2264 if ( pVolumeCB != NULL)
2267 lCount = AFSVolumeDecrement( pVolumeCB,
2268 AFS_VOLUME_REFERENCE_INVALIDATE);
2270 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2271 AFS_TRACE_LEVEL_VERBOSE,
2272 "AFSInvalidateCache Decrement count on volume %p Cnt %d\n",
2282 AFSIsChildOfParent( IN AFSFcb *Dcb,
2286 BOOLEAN bIsChild = FALSE;
2287 AFSFcb *pCurrentFcb = Fcb;
2288 AFSObjectInfoCB * pParentObjectInfo = NULL;
2290 while( pCurrentFcb != NULL)
2293 if( BooleanFlagOn( pCurrentFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2294 AFSIsEqualFID( &pCurrentFcb->ObjectInformation->ParentFileId, &Dcb->ObjectInformation->FileId))
2302 pParentObjectInfo = AFSFindObjectInfo( pCurrentFcb->ObjectInformation->VolumeCB,
2303 &pCurrentFcb->ObjectInformation->ParentFileId,
2306 if ( pParentObjectInfo != NULL)
2309 pCurrentFcb = pParentObjectInfo->Fcb;
2311 AFSReleaseObjectInfo( &pParentObjectInfo);
2325 AFSCreateHighIndex( IN AFSFileID *FileID)
2328 ULONGLONG ullIndex = 0;
2330 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2337 AFSCreateLowIndex( IN AFSFileID *FileID)
2340 ULONGLONG ullIndex = 0;
2342 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2348 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2349 IN ACCESS_MASK GrantedAccess,
2350 IN BOOLEAN DirectoryEntry)
2353 BOOLEAN bAccessGranted = TRUE;
2356 // Check if we are asking for read/write and granted only read only
2357 // NOTE: There will be more checks here
2360 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2362 AFSCheckForReadOnlyAccess( GrantedAccess,
2366 bAccessGranted = FALSE;
2369 return bAccessGranted;
2373 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2376 NTSTATUS ntStatus = STATUS_SUCCESS;
2377 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2383 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2385 if( AFSGlobalRoot == NULL)
2392 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2395 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2402 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2409 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2410 IN UNICODE_STRING *SubstituteName,
2411 IN ULONG StringIndex)
2414 NTSTATUS ntStatus = STATUS_SUCCESS;
2415 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2416 AFSSysNameCB *pSysName = NULL;
2417 ERESOURCE *pSysNameLock = NULL;
2420 UNICODE_STRING uniSysName;
2427 if( IoIs32bitProcess( NULL))
2430 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2432 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2437 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2439 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2443 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2445 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2449 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2450 AFS_TRACE_LEVEL_VERBOSE,
2451 "AFSSubstituteSysName Acquiring SysName lock %p SHARED %08lX\n",
2453 PsGetCurrentThread()));
2455 AFSAcquireShared( pSysNameLock,
2459 // Find where we are in the list
2462 while( pSysName != NULL &&
2463 ulIndex < StringIndex)
2466 pSysName = pSysName->fLink;
2471 if( pSysName == NULL)
2474 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2475 AFS_TRACE_LEVEL_VERBOSE_2,
2476 "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
2478 STATUS_OBJECT_NAME_NOT_FOUND));
2480 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2483 RtlInitUnicodeString( &uniSysName,
2486 // If it is a full component of @SYS then just substitue the
2490 if( RtlCompareUnicodeString( &uniSysName,
2495 SubstituteName->Length = pSysName->SysName.Length;
2496 SubstituteName->MaximumLength = SubstituteName->Length;
2498 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2499 SubstituteName->Length,
2500 AFS_SUBST_BUFFER_TAG);
2502 if( SubstituteName->Buffer == NULL)
2505 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2508 RtlCopyMemory( SubstituteName->Buffer,
2509 pSysName->SysName.Buffer,
2510 pSysName->SysName.Length);
2517 while( ComponentName->Buffer[ usIndex] != L'@')
2523 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2524 SubstituteName->MaximumLength = SubstituteName->Length;
2526 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2527 SubstituteName->Length,
2528 AFS_SUBST_BUFFER_TAG);
2530 if( SubstituteName->Buffer == NULL)
2533 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2536 RtlCopyMemory( SubstituteName->Buffer,
2537 ComponentName->Buffer,
2538 usIndex * sizeof( WCHAR));
2540 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2541 pSysName->SysName.Buffer,
2542 pSysName->SysName.Length);
2547 AFSReleaseResource( pSysNameLock);
2554 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2555 IN OUT UNICODE_STRING *ComponentName,
2556 IN UNICODE_STRING *SubstituteName,
2557 IN OUT UNICODE_STRING *RemainingPath,
2558 IN BOOLEAN FreePathName)
2561 NTSTATUS ntStatus = STATUS_SUCCESS;
2562 UNICODE_STRING uniPathName;
2563 USHORT usPrefixNameLen = 0;
2564 SHORT sNameLenDelta = 0;
2570 // If the passed in name can handle the additional length
2571 // then just moves things around
2574 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2576 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2578 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2581 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2584 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2585 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2586 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2589 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2590 SubstituteName->Buffer,
2591 SubstituteName->Length);
2593 FullPathName->Length += sNameLenDelta;
2595 ComponentName->Length += sNameLenDelta;
2597 ComponentName->MaximumLength = ComponentName->Length;
2599 if ( RemainingPath->Buffer)
2602 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2605 try_return( ntStatus);
2609 // Need to re-allocate the buffer
2612 uniPathName.Length = FullPathName->Length -
2613 ComponentName->Length +
2614 SubstituteName->Length;
2616 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2618 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2619 uniPathName.MaximumLength,
2620 AFS_NAME_BUFFER_FOUR_TAG);
2622 if( uniPathName.Buffer == NULL)
2625 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2628 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2630 usPrefixNameLen *= sizeof( WCHAR);
2632 RtlZeroMemory( uniPathName.Buffer,
2633 uniPathName.MaximumLength);
2635 RtlCopyMemory( uniPathName.Buffer,
2636 FullPathName->Buffer,
2639 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2640 SubstituteName->Buffer,
2641 SubstituteName->Length);
2643 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2646 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2647 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2648 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2651 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2653 ComponentName->Length += sNameLenDelta;
2655 ComponentName->MaximumLength = ComponentName->Length;
2657 if ( RemainingPath->Buffer)
2660 RemainingPath->Buffer = uniPathName.Buffer
2661 + (RemainingPath->Buffer - FullPathName->Buffer)
2662 + sNameLenDelta/sizeof( WCHAR);
2667 AFSExFreePoolWithTag( FullPathName->Buffer, 0);
2670 *FullPathName = uniPathName;
2681 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2685 NTSTATUS ntStatus = STATUS_SUCCESS;
2686 AFSObjectInfoCB *pCurrentObject = NULL;
2687 AFSObjectInfoCB *pNextObject = NULL;
2693 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2694 AFS_TRACE_LEVEL_VERBOSE,
2695 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2696 VolumeCB->ObjectInformation.FileId.Cell,
2697 VolumeCB->ObjectInformation.FileId.Volume,
2698 VolumeCB->ObjectInformation.FileId.Vnode,
2699 VolumeCB->ObjectInformation.FileId.Unique,
2703 // Depending on the reason for invalidation then perform work on the node
2709 case AFS_INVALIDATE_DELETED:
2713 // Mark this volume as invalid
2716 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2718 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2724 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2728 // Invalidate the volume root directory
2731 pCurrentObject = &VolumeCB->ObjectInformation;
2733 if ( pCurrentObject )
2736 lCount = AFSObjectInfoIncrement( pCurrentObject,
2737 AFS_OBJECT_REFERENCE_INVALIDATION);
2739 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2740 AFS_TRACE_LEVEL_VERBOSE,
2741 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2745 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2747 AFSInvalidateObject( &pCurrentObject,
2750 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2753 if ( pCurrentObject)
2756 lCount = AFSObjectInfoDecrement( pCurrentObject,
2757 AFS_OBJECT_REFERENCE_INVALIDATION);
2759 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2760 AFS_TRACE_LEVEL_VERBOSE,
2761 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2768 // Apply invalidation to all other volume objects
2771 pCurrentObject = VolumeCB->ObjectInfoListHead;
2773 if ( pCurrentObject)
2777 // Reference the node so it won't be torn down
2780 lCount = AFSObjectInfoIncrement( pCurrentObject,
2781 AFS_OBJECT_REFERENCE_INVALIDATION);
2783 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2784 AFS_TRACE_LEVEL_VERBOSE,
2785 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2790 while( pCurrentObject != NULL)
2793 pNextObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2799 // Reference the node so it won't be torn down
2802 lCount = AFSObjectInfoIncrement( pNextObject,
2803 AFS_OBJECT_REFERENCE_INVALIDATION);
2805 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2806 AFS_TRACE_LEVEL_VERBOSE,
2807 "AFSInvalidateVolumeObjects Increment count on object %p Cnt %d\n",
2812 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2814 AFSInvalidateObject( &pCurrentObject,
2817 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2820 if ( pCurrentObject )
2823 lCount = AFSObjectInfoDecrement( pCurrentObject,
2824 AFS_OBJECT_REFERENCE_INVALIDATION);
2826 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2827 AFS_TRACE_LEVEL_VERBOSE,
2828 "AFSInvalidateVolumeObjects Decrement count on object %p Cnt %d\n",
2833 pCurrentObject = pNextObject;
2836 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2843 AFSInvalidateAllVolumes( VOID)
2845 AFSVolumeCB *pVolumeCB = NULL;
2846 AFSVolumeCB *pNextVolumeCB = NULL;
2847 AFSDeviceExt *pRDRDeviceExt = NULL;
2850 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2852 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2853 AFS_TRACE_LEVEL_VERBOSE,
2854 "AFSInvalidateAllVolumes Acquiring RDR VolumeListLock lock %p SHARED %08lX\n",
2855 &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2856 PsGetCurrentThread()));
2858 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2861 pVolumeCB = pRDRDeviceExt->Specific.RDR.VolumeListHead;
2866 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2867 AFS_TRACE_LEVEL_VERBOSE,
2868 "AFSInvalidateAllVolumes Acquiring VolumeRoot ObjectInfoTree lock %p SHARED %08lX\n",
2869 pVolumeCB->ObjectInfoTree.TreeLock,
2870 PsGetCurrentThread()));
2872 lCount = AFSVolumeIncrement( pVolumeCB,
2873 AFS_VOLUME_REFERENCE_INVALIDATE);
2875 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2876 AFS_TRACE_LEVEL_VERBOSE,
2877 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2882 while( pVolumeCB != NULL)
2885 pNextVolumeCB = (AFSVolumeCB *)pVolumeCB->ListEntry.fLink;
2890 lCount = AFSVolumeIncrement( pNextVolumeCB,
2891 AFS_VOLUME_REFERENCE_INVALIDATE);
2893 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2894 AFS_TRACE_LEVEL_VERBOSE,
2895 "AFSInvalidateAllVolumes Increment count on volume %p Cnt %d\n",
2900 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2902 // do I need to hold the volume lock here?
2904 AFSInvalidateVolume( pVolumeCB, AFS_INVALIDATE_EXPIRED);
2906 AFSAcquireShared( &pRDRDeviceExt->Specific.RDR.VolumeListLock,
2909 lCount = AFSVolumeDecrement( pVolumeCB,
2910 AFS_VOLUME_REFERENCE_INVALIDATE);
2912 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
2913 AFS_TRACE_LEVEL_VERBOSE,
2914 "AFSInvalidateAllVolumes Decrement count on volume %p Cnt %d\n",
2918 pVolumeCB = pNextVolumeCB;
2921 AFSReleaseResource( &pRDRDeviceExt->Specific.RDR.VolumeListLock);
2925 AFSVerifyEntry( IN GUID *AuthGroup,
2926 IN AFSDirectoryCB *DirEntry,
2927 IN BOOLEAN bFollowMountPoint)
2930 NTSTATUS ntStatus = STATUS_SUCCESS;
2931 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2932 AFSDirEnumEntry *pDirEnumEntry = NULL;
2933 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2934 IO_STATUS_BLOCK stIoStatus;
2939 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2940 AFS_TRACE_LEVEL_VERBOSE_2,
2941 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2942 &DirEntry->NameInformation.FileName,
2943 pObjectInfo->FileId.Cell,
2944 pObjectInfo->FileId.Volume,
2945 pObjectInfo->FileId.Vnode,
2946 pObjectInfo->FileId.Unique));
2948 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2950 bFollowMountPoint ? FALSE : TRUE,
2953 if( !NT_SUCCESS( ntStatus))
2956 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2957 AFS_TRACE_LEVEL_ERROR,
2958 "AFSVerifyEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2959 &DirEntry->NameInformation.FileName,
2960 pObjectInfo->FileId.Cell,
2961 pObjectInfo->FileId.Volume,
2962 pObjectInfo->FileId.Vnode,
2963 pObjectInfo->FileId.Unique,
2966 try_return( ntStatus);
2970 // Check the data version of the file
2973 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2974 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2977 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2978 AFS_TRACE_LEVEL_VERBOSE,
2979 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
2980 pObjectInfo->DataVersion.QuadPart,
2981 &DirEntry->NameInformation.FileName,
2982 pObjectInfo->FileId.Cell,
2983 pObjectInfo->FileId.Volume,
2984 pObjectInfo->FileId.Vnode,
2985 pObjectInfo->FileId.Unique));
2988 // We are ok, just get out
2991 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2993 try_return( ntStatus = STATUS_SUCCESS);
2997 // New data version so we will need to process the node based on the type
3000 switch( pDirEnumEntry->FileType)
3003 case AFS_FILE_TYPE_MOUNTPOINT:
3007 // For a mount point we need to ensure the target is the same
3010 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
3011 &pDirEnumEntry->TargetFileId))
3017 // Update the metadata for the entry
3020 ntStatus = AFSUpdateMetaData( DirEntry,
3023 if( NT_SUCCESS( ntStatus))
3026 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3027 AFS_TRACE_LEVEL_VERBOSE,
3028 "AFSVerifyEntry MountPoint FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
3029 pObjectInfo->FileId.Cell,
3030 pObjectInfo->FileId.Volume,
3031 pObjectInfo->FileId.Vnode,
3032 pObjectInfo->FileId.Unique));
3034 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3040 case AFS_FILE_TYPE_SYMLINK:
3044 // Update the metadata for the entry
3047 ntStatus = AFSUpdateMetaData( DirEntry,
3050 if( NT_SUCCESS( ntStatus))
3053 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3054 AFS_TRACE_LEVEL_VERBOSE,
3055 "AFSVerifyEntry Symlink FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
3056 pObjectInfo->FileId.Cell,
3057 pObjectInfo->FileId.Volume,
3058 pObjectInfo->FileId.Vnode,
3059 pObjectInfo->FileId.Unique));
3061 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3067 case AFS_FILE_TYPE_FILE:
3069 FILE_OBJECT * pCCFileObject = NULL;
3071 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3074 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3075 AFS_TRACE_LEVEL_VERBOSE,
3076 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3077 &DirEntry->NameInformation.FileName,
3078 pObjectInfo->FileId.Cell,
3079 pObjectInfo->FileId.Volume,
3080 pObjectInfo->FileId.Vnode,
3081 pObjectInfo->FileId.Unique));
3083 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3086 if( pObjectInfo->Fcb != NULL)
3089 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3090 AFS_TRACE_LEVEL_VERBOSE,
3091 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3092 &DirEntry->NameInformation.FileName,
3093 pObjectInfo->FileId.Cell,
3094 pObjectInfo->FileId.Volume,
3095 pObjectInfo->FileId.Vnode,
3096 pObjectInfo->FileId.Unique));
3098 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3099 AFS_TRACE_LEVEL_VERBOSE,
3100 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3101 &pObjectInfo->Fcb->NPFcb->Resource,
3102 PsGetCurrentThread()));
3104 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3107 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3108 AFS_TRACE_LEVEL_VERBOSE,
3109 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3110 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3111 PsGetCurrentThread()));
3113 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3119 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3124 if( !NT_SUCCESS( stIoStatus.Status))
3127 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3128 AFS_TRACE_LEVEL_ERROR,
3129 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3130 &DirEntry->NameInformation.FileName,
3131 pObjectInfo->FileId.Cell,
3132 pObjectInfo->FileId.Volume,
3133 pObjectInfo->FileId.Vnode,
3134 pObjectInfo->FileId.Unique,
3136 stIoStatus.Information));
3138 ntStatus = stIoStatus.Status;
3141 if ( pObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
3144 if ( !CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3150 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
3151 AFS_TRACE_LEVEL_WARNING,
3152 "AFSVerifyEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3153 &DirEntry->NameInformation.FileName,
3154 pObjectInfo->FileId.Cell,
3155 pObjectInfo->FileId.Volume,
3156 pObjectInfo->FileId.Vnode,
3157 pObjectInfo->FileId.Unique));
3159 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3163 __except( EXCEPTION_EXECUTE_HANDLER)
3165 ntStatus = GetExceptionCode();
3169 "EXCEPTION - AFSVerifyEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3170 &DirEntry->NameInformation.FileName,
3171 pObjectInfo->FileId.Cell,
3172 pObjectInfo->FileId.Volume,
3173 pObjectInfo->FileId.Vnode,
3174 pObjectInfo->FileId.Unique,
3177 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
3180 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3181 AFS_TRACE_LEVEL_VERBOSE,
3182 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3183 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3184 PsGetCurrentThread()));
3186 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3188 if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
3191 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3192 AFS_TRACE_LEVEL_VERBOSE,
3193 "AFSVerifyEntry Releasing Fcb lock %p EXCL %08lX\n",
3194 &pObjectInfo->Fcb->NPFcb->Resource,
3195 PsGetCurrentThread()));
3197 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3199 AFSFlushExtents( pObjectInfo->Fcb,
3203 // Acquire the Fcb to purge the cache
3206 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3207 AFS_TRACE_LEVEL_VERBOSE,
3208 "AFSVerifyEntry Acquiring Fcb lock %p EXCL %08lX\n",
3209 &pObjectInfo->Fcb->NPFcb->Resource,
3210 PsGetCurrentThread()));
3212 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
3217 // Update the metadata for the entry
3220 ntStatus = AFSUpdateMetaData( DirEntry,
3223 if( !NT_SUCCESS( ntStatus))
3226 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3227 AFS_TRACE_LEVEL_ERROR,
3228 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3229 &DirEntry->NameInformation.FileName,
3230 pObjectInfo->FileId.Cell,
3231 pObjectInfo->FileId.Volume,
3232 pObjectInfo->FileId.Vnode,
3233 pObjectInfo->FileId.Unique,
3240 // Update file sizes
3243 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3244 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3245 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3247 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3248 AFS_TRACE_LEVEL_VERBOSE,
3249 "AFSVerifyEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3250 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3251 PsGetCurrentThread()));
3253 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3259 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3261 if ( pCCFileObject != NULL)
3263 CcSetFileSizes( pCCFileObject,
3264 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3267 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3270 ntStatus = GetExceptionCode();
3274 "EXCEPTION - AFSVerifyEntry CcSetFileSized failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3275 pObjectInfo->FileId.Cell,
3276 pObjectInfo->FileId.Volume,
3277 pObjectInfo->FileId.Vnode,
3278 pObjectInfo->FileId.Unique,
3282 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3283 AFS_TRACE_LEVEL_VERBOSE,
3284 "AFSVerifyEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3285 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3286 PsGetCurrentThread()));
3288 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3291 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3292 AFS_TRACE_LEVEL_VERBOSE,
3293 "AFSVerifyEntry Releasing Fcb lock %p EXCL %08lX\n",
3294 &pObjectInfo->Fcb->NPFcb->Resource,
3295 PsGetCurrentThread()));
3297 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
3303 // Update the metadata for the entry
3306 ntStatus = AFSUpdateMetaData( DirEntry,
3309 if( !NT_SUCCESS( ntStatus))
3312 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3313 AFS_TRACE_LEVEL_ERROR,
3314 "AFSVerifyEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
3315 &DirEntry->NameInformation.FileName,
3316 pObjectInfo->FileId.Cell,
3317 pObjectInfo->FileId.Volume,
3318 pObjectInfo->FileId.Vnode,
3319 pObjectInfo->FileId.Unique,
3325 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3326 AFS_TRACE_LEVEL_WARNING,
3327 "AFSVerifyEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3328 &DirEntry->NameInformation.FileName,
3329 pObjectInfo->FileId.Cell,
3330 pObjectInfo->FileId.Volume,
3331 pObjectInfo->FileId.Vnode,
3332 pObjectInfo->FileId.Unique));
3336 if ( NT_SUCCESS( ntStatus))
3339 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3340 AFS_TRACE_LEVEL_VERBOSE,
3341 "AFSVerifyEntry File FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
3342 pObjectInfo->FileId.Cell,
3343 pObjectInfo->FileId.Volume,
3344 pObjectInfo->FileId.Vnode,
3345 pObjectInfo->FileId.Unique));
3347 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3352 case AFS_FILE_TYPE_DIRECTORY:
3356 // For a directory or root entry flush the content of
3357 // the directory enumeration.
3360 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3363 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3364 AFS_TRACE_LEVEL_VERBOSE_2,
3365 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3366 &DirEntry->NameInformation.FileName,
3367 pObjectInfo->FileId.Cell,
3368 pObjectInfo->FileId.Volume,
3369 pObjectInfo->FileId.Vnode,
3370 pObjectInfo->FileId.Unique));
3372 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3375 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
3378 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3380 if ( !NT_SUCCESS( ntStatus))
3383 try_return( ntStatus);
3388 // Update the metadata for the entry
3391 ntStatus = AFSUpdateMetaData( DirEntry,
3394 if( NT_SUCCESS( ntStatus))
3397 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3398 AFS_TRACE_LEVEL_VERBOSE,
3399 "AFSVerifyEntry Directory FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
3400 pObjectInfo->FileId.Cell,
3401 pObjectInfo->FileId.Volume,
3402 pObjectInfo->FileId.Vnode,
3403 pObjectInfo->FileId.Unique));
3405 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3411 case AFS_FILE_TYPE_DFSLINK:
3414 UNICODE_STRING uniTargetName;
3417 // For a DFS link need to check the target name has not changed
3420 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
3422 uniTargetName.MaximumLength = uniTargetName.Length;
3424 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
3426 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3429 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3430 RtlCompareUnicodeString( &uniTargetName,
3431 &DirEntry->NameInformation.TargetName,
3436 // Update the target name
3439 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3441 uniTargetName.Buffer,
3442 uniTargetName.Length);
3444 if( !NT_SUCCESS( ntStatus))
3447 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3453 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3456 // Update the metadata for the entry
3459 ntStatus = AFSUpdateMetaData( DirEntry,
3462 if( NT_SUCCESS( ntStatus))
3465 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3466 AFS_TRACE_LEVEL_VERBOSE,
3467 "AFSVerifyEntry DFSLink FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
3468 pObjectInfo->FileId.Cell,
3469 pObjectInfo->FileId.Volume,
3470 pObjectInfo->FileId.Vnode,
3471 pObjectInfo->FileId.Unique));
3473 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3481 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3482 AFS_TRACE_LEVEL_WARNING,
3483 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3484 pObjectInfo->FileType,
3485 &DirEntry->NameInformation.FileName,
3486 pObjectInfo->FileId.Cell,
3487 pObjectInfo->FileId.Volume,
3488 pObjectInfo->FileId.Vnode,
3489 pObjectInfo->FileId.Unique));
3496 if( pDirEnumEntry != NULL)
3499 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
3507 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3510 NTSTATUS ntStatus = STATUS_SUCCESS;
3511 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3512 ULONGLONG ullIndex = 0;
3513 AFSVolumeCB *pVolumeCB = NULL;
3519 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3520 AFS_TRACE_LEVEL_VERBOSE,
3521 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3522 VolumeStatus->Online,
3523 VolumeStatus->FileID.Cell,
3524 VolumeStatus->FileID.Volume));
3527 // Need to locate the Fcb for the directory to purge
3530 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3531 AFS_TRACE_LEVEL_VERBOSE,
3532 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %p SHARED %08lX\n",
3533 &pDevExt->Specific.RDR.VolumeTreeLock,
3534 PsGetCurrentThread()));
3536 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3539 // Locate the volume node
3542 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3544 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3546 (AFSBTreeEntry **)&pVolumeCB);
3548 if( pVolumeCB != NULL)
3551 lCount = AFSVolumeIncrement( pVolumeCB,
3552 AFS_VOLUME_REFERENCE_INVALIDATE);
3554 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
3555 AFS_TRACE_LEVEL_VERBOSE,
3556 "AFSSetVolumeState Increment count on volume %p Cnt %d\n",
3560 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3563 // Set the volume state accordingly
3566 if( VolumeStatus->Online)
3569 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3574 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3583 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3586 NTSTATUS ntStatus = STATUS_SUCCESS;
3591 if( AFSGlobalRoot == NULL)
3594 try_return( ntStatus);
3597 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3601 // Set the network state according to the information
3604 if( NetworkStatus->Online)
3607 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3612 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3615 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3626 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3630 NTSTATUS ntStatus = STATUS_SUCCESS;
3631 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
3632 BOOLEAN bAcquiredLock = FALSE;
3633 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3638 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3639 AFS_TRACE_LEVEL_VERBOSE,
3640 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3641 ObjectInfo->FileId.Cell,
3642 ObjectInfo->FileId.Volume,
3643 ObjectInfo->FileId.Vnode,
3644 ObjectInfo->FileId.Unique));
3646 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3649 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3650 AFS_TRACE_LEVEL_VERBOSE,
3651 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
3652 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3653 PsGetCurrentThread()));
3655 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3658 bAcquiredLock = TRUE;
3662 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3665 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3666 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3669 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3670 AFS_TRACE_LEVEL_ERROR,
3671 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %d for dir FID %08lX-%08lX-%08lX-%08lX\n",
3672 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3673 ObjectInfo->FileId.Cell,
3674 ObjectInfo->FileId.Volume,
3675 ObjectInfo->FileId.Vnode,
3676 ObjectInfo->FileId.Unique));
3680 // Reset the directory list information by clearing all valid entries
3683 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3685 while( pCurrentDirEntry != NULL)
3688 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3690 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3694 // If this entry has been deleted then process it here
3697 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3698 pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3699 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3702 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3703 AFS_TRACE_LEVEL_VERBOSE,
3704 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3706 &pCurrentDirEntry->NameInformation.FileName));
3708 AFSDeleteDirEntry( ObjectInfo,
3714 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3716 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3717 AFS_TRACE_LEVEL_VERBOSE,
3718 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %d\n",
3720 pCurrentDirEntry->DirOpenReferenceCount));
3723 // We pull the short name from the parent tree since it could change below
3726 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3729 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3730 AFS_TRACE_LEVEL_VERBOSE,
3731 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3733 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3734 &pCurrentDirEntry->NameInformation.FileName));
3736 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3739 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3744 pCurrentDirEntry = pNextDirEntry;
3748 // Reget the directory contents
3751 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3754 if ( !NT_SUCCESS( ntStatus))
3756 try_return( ntStatus);
3760 // Now start again and tear down any entries not valid
3763 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3765 while( pCurrentDirEntry != NULL)
3768 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3770 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3773 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
3774 !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3775 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3778 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3781 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3783 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3784 AFS_TRACE_LEVEL_VERBOSE,
3785 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3787 &pCurrentDirEntry->NameInformation.FileName));
3789 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3794 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3797 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3798 AFS_TRACE_LEVEL_VERBOSE,
3799 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3801 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3802 &pCurrentDirEntry->NameInformation.FileName));
3806 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3808 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3809 AFS_TRACE_LEVEL_VERBOSE,
3810 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3812 &pCurrentDirEntry->NameInformation.FileName));
3817 pCurrentDirEntry = pNextDirEntry;
3822 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3823 AFS_TRACE_LEVEL_VERBOSE,
3824 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %d\n",
3826 pCurrentDirEntry->DirOpenReferenceCount));
3828 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
3829 pCurrentDirEntry->NameArrayReferenceCount <= 0)
3832 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3833 AFS_TRACE_LEVEL_VERBOSE,
3834 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3835 &pCurrentDirEntry->NameInformation.FileName,
3836 ObjectInfo->FileId.Cell,
3837 ObjectInfo->FileId.Volume,
3838 ObjectInfo->FileId.Vnode,
3839 ObjectInfo->FileId.Unique));
3841 AFSDeleteDirEntry( ObjectInfo,
3847 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3848 AFS_TRACE_LEVEL_VERBOSE,
3849 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3851 &pCurrentDirEntry->NameInformation.FileName,
3852 ObjectInfo->FileId.Cell,
3853 ObjectInfo->FileId.Volume,
3854 ObjectInfo->FileId.Vnode,
3855 ObjectInfo->FileId.Unique));
3857 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3859 AFSRemoveNameEntry( ObjectInfo,
3863 pCurrentDirEntry = pNextDirEntry;
3867 if( !AFSValidateDirList( ObjectInfo))
3870 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3879 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3887 AFSIsVolumeFID( IN AFSFileID *FileID)
3890 BOOLEAN bIsVolume = FALSE;
3892 if( FileID->Vnode == 1 &&
3893 FileID->Unique == 1)
3903 AFSIsFinalNode( IN AFSFcb *Fcb)
3906 BOOLEAN bIsFinalNode = FALSE;
3908 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3909 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3910 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3911 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3912 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3915 bIsFinalNode = TRUE;
3920 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3921 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3924 return bIsFinalNode;
3928 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3929 IN AFSDirEnumEntry *DirEnumEntry)
3932 NTSTATUS ntStatus = STATUS_SUCCESS;
3933 UNICODE_STRING uniTargetName;
3934 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3939 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3941 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3943 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3945 pObjectInfo->FileType = DirEnumEntry->FileType;
3947 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3949 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3951 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3953 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3955 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3957 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3959 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3961 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3962 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3965 pObjectInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3968 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
3971 if ( pObjectInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
3974 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3979 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3983 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3985 pObjectInfo->Links = DirEnumEntry->Links;
3987 if( DirEnumEntry->TargetNameLength > 0 &&
3988 ( DirEntry->NameInformation.TargetName.Length != DirEnumEntry->TargetNameLength ||
3989 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart))
3993 // Update the target name information if needed
3996 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3998 uniTargetName.MaximumLength = uniTargetName.Length;
4000 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
4002 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4005 if( DirEntry->NameInformation.TargetName.Length == 0 ||
4006 RtlCompareUnicodeString( &uniTargetName,
4007 &DirEntry->NameInformation.TargetName,
4012 // Update the target name
4015 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
4017 uniTargetName.Buffer,
4018 uniTargetName.Length);
4020 if( !NT_SUCCESS( ntStatus))
4023 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4025 try_return( ntStatus);
4029 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4031 else if( DirEntry->NameInformation.TargetName.Length > 0 &&
4032 DirEntry->ObjectInformation->DataVersion.QuadPart != DirEnumEntry->DataVersion.QuadPart)
4035 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
4038 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
4039 DirEntry->NameInformation.TargetName.Buffer != NULL)
4041 AFSExFreePoolWithTag( DirEntry->NameInformation.TargetName.Buffer, AFS_NAME_BUFFER_FIVE_TAG);
4044 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4046 DirEntry->NameInformation.TargetName.Length = 0;
4047 DirEntry->NameInformation.TargetName.MaximumLength = 0;
4048 DirEntry->NameInformation.TargetName.Buffer = NULL;
4050 AFSReleaseResource( &DirEntry->NonPaged->Lock);
4062 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
4064 IN BOOLEAN FastCall,
4065 IN BOOLEAN bSafeToPurge)
4068 NTSTATUS ntStatus = STATUS_SUCCESS;
4069 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4070 LARGE_INTEGER liSystemTime;
4071 AFSDirEnumEntry *pDirEnumEntry = NULL;
4072 AFSFcb *pCurrentFcb = NULL;
4073 BOOLEAN bReleaseFcb = FALSE;
4074 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
4080 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
4084 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4085 AFS_TRACE_LEVEL_VERBOSE_2,
4086 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX FastCall %u\n",
4087 &DirEntry->NameInformation.FileName,
4088 pObjectInfo->FileId.Cell,
4089 pObjectInfo->FileId.Volume,
4090 pObjectInfo->FileId.Vnode,
4091 pObjectInfo->FileId.Unique,
4095 // If this is a fake node then bail since the service knows nothing about it
4098 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
4101 try_return( ntStatus);
4105 // This routine ensures that the current entry is valid by:
4107 // 1) Checking that the expiration time is non-zero and after where we
4111 KeQuerySystemTime( &liSystemTime);
4113 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
4114 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
4115 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
4116 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
4119 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4120 AFS_TRACE_LEVEL_VERBOSE_2,
4121 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
4122 &DirEntry->NameInformation.FileName,
4123 pObjectInfo->FileId.Cell,
4124 pObjectInfo->FileId.Volume,
4125 pObjectInfo->FileId.Vnode,
4126 pObjectInfo->FileId.Unique));
4128 try_return( ntStatus);
4132 // This node requires updating
4135 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
4140 if( !NT_SUCCESS( ntStatus))
4143 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4144 AFS_TRACE_LEVEL_ERROR,
4145 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4147 &DirEntry->NameInformation.FileName,
4148 pObjectInfo->FileId.Cell,
4149 pObjectInfo->FileId.Volume,
4150 pObjectInfo->FileId.Vnode,
4151 pObjectInfo->FileId.Unique,
4155 // Failed validation of node so return access-denied
4158 try_return( ntStatus);
4161 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4162 AFS_TRACE_LEVEL_VERBOSE,
4163 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
4165 &DirEntry->NameInformation.FileName,
4166 pObjectInfo->FileId.Cell,
4167 pObjectInfo->FileId.Volume,
4168 pObjectInfo->FileId.Vnode,
4169 pObjectInfo->FileId.Unique,
4170 pObjectInfo->DataVersion.QuadPart,
4171 pDirEnumEntry->DataVersion.QuadPart,
4172 pDirEnumEntry->FileType));
4176 // Based on the file type, process the node
4179 switch( pDirEnumEntry->FileType)
4182 case AFS_FILE_TYPE_MOUNTPOINT:
4186 // Update the metadata for the entry
4189 ntStatus = AFSUpdateMetaData( DirEntry,
4192 if( NT_SUCCESS( ntStatus))
4195 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4196 AFS_TRACE_LEVEL_VERBOSE,
4197 "AFSValidateEntry MountPoint FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
4198 pObjectInfo->FileId.Cell,
4199 pObjectInfo->FileId.Volume,
4200 pObjectInfo->FileId.Vnode,
4201 pObjectInfo->FileId.Unique));
4203 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4209 case AFS_FILE_TYPE_SYMLINK:
4210 case AFS_FILE_TYPE_DFSLINK:
4214 // Update the metadata for the entry
4217 ntStatus = AFSUpdateMetaData( DirEntry,
4220 if( NT_SUCCESS( ntStatus))
4223 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4224 AFS_TRACE_LEVEL_VERBOSE,
4225 "AFSValidateEntry Symlink FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
4226 pObjectInfo->FileId.Cell,
4227 pObjectInfo->FileId.Volume,
4228 pObjectInfo->FileId.Vnode,
4229 pObjectInfo->FileId.Unique));
4231 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4237 case AFS_FILE_TYPE_FILE:
4240 BOOLEAN bPurgeExtents = FALSE;
4243 // For a file where the data version has become invalid we need to
4244 // fail any current extent requests and purge the cache for the file
4245 // Can't hold the Fcb resource while doing this
4248 if( pObjectInfo->Fcb != NULL &&
4249 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
4250 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
4253 pCurrentFcb = pObjectInfo->Fcb;
4255 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
4258 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4259 AFS_TRACE_LEVEL_VERBOSE,
4260 "AFSValidateEntry Acquiring Fcb lock %p EXCL %08lX\n",
4261 &pCurrentFcb->NPFcb->Resource,
4262 PsGetCurrentThread()));
4264 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
4270 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4271 AFS_TRACE_LEVEL_VERBOSE_2,
4272 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4273 &DirEntry->NameInformation.FileName,
4274 pObjectInfo->FileId.Cell,
4275 pObjectInfo->FileId.Volume,
4276 pObjectInfo->FileId.Vnode,
4277 pObjectInfo->FileId.Unique));
4279 if ( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4282 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4283 AFS_TRACE_LEVEL_VERBOSE,
4284 "AFSValidateEntry DV Change %wZ FID %08lX-%08lX-%08lX-%08lX (%08lX != %08lX)\n",
4285 &DirEntry->NameInformation.FileName,
4286 pObjectInfo->FileId.Cell,
4287 pObjectInfo->FileId.Volume,
4288 pObjectInfo->FileId.Vnode,
4289 pObjectInfo->FileId.Unique,
4290 pObjectInfo->DataVersion.LowPart,
4291 pDirEnumEntry->DataVersion.LowPart));
4293 bPurgeExtents = TRUE;
4299 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
4301 bPurgeExtents = TRUE;
4303 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4304 AFS_TRACE_LEVEL_VERBOSE,
4305 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4306 &DirEntry->NameInformation.FileName,
4307 pObjectInfo->FileId.Cell,
4308 pObjectInfo->FileId.Volume,
4309 pObjectInfo->FileId.Vnode,
4310 pObjectInfo->FileId.Unique));
4312 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4315 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4316 AFS_TRACE_LEVEL_VERBOSE,
4317 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4318 &pCurrentFcb->NPFcb->SectionObjectResource,
4319 PsGetCurrentThread()));
4321 AFSAcquireExcl( &pCurrentFcb->NPFcb->SectionObjectResource,
4327 IO_STATUS_BLOCK stIoStatus;
4329 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
4334 if( !NT_SUCCESS( stIoStatus.Status))
4337 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4338 AFS_TRACE_LEVEL_ERROR,
4339 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
4340 &DirEntry->NameInformation.FileName,
4341 pObjectInfo->FileId.Cell,
4342 pObjectInfo->FileId.Volume,
4343 pObjectInfo->FileId.Vnode,
4344 pObjectInfo->FileId.Unique,
4346 stIoStatus.Information));
4348 ntStatus = stIoStatus.Status;
4351 if ( bPurgeExtents &&
4352 pCurrentFcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
4355 if ( !CcPurgeCacheSection( &pCurrentFcb->NPFcb->SectionObjectPointers,
4361 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
4362 AFS_TRACE_LEVEL_WARNING,
4363 "AFSValidateEntry CcPurgeCacheSection failure %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4364 &DirEntry->NameInformation.FileName,
4365 pObjectInfo->FileId.Cell,
4366 pObjectInfo->FileId.Volume,
4367 pObjectInfo->FileId.Vnode,
4368 pObjectInfo->FileId.Unique));
4370 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4374 __except( EXCEPTION_EXECUTE_HANDLER)
4376 ntStatus = GetExceptionCode();
4380 "EXCEPTION - AFSValidateEntry CcFlushCache or CcPurgeCacheSection %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4381 &DirEntry->NameInformation.FileName,
4382 pObjectInfo->FileId.Cell,
4383 pObjectInfo->FileId.Volume,
4384 pObjectInfo->FileId.Vnode,
4385 pObjectInfo->FileId.Unique,
4388 SetFlag( pCurrentFcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
4391 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4392 AFS_TRACE_LEVEL_VERBOSE,
4393 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4394 &pCurrentFcb->NPFcb->SectionObjectResource,
4395 PsGetCurrentThread()));
4397 AFSReleaseResource( &pCurrentFcb->NPFcb->SectionObjectResource);
4405 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
4411 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4413 bReleaseFcb = FALSE;
4416 if ( bPurgeExtents &&
4420 if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
4422 AFSFlushExtents( pCurrentFcb,
4429 // Update the metadata for the entry but only if it is safe to do so.
4430 // If it was determined that a data version change has occurred or
4431 // that a pending data verification was required, do not update the
4432 // ObjectInfo meta data or the FileObject size information. That
4433 // way it is consistent for the next time that the data is verified
4437 if ( !(bPurgeExtents && bSafeToPurge))
4440 ntStatus = AFSUpdateMetaData( DirEntry,
4443 if( !NT_SUCCESS( ntStatus))
4446 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4447 AFS_TRACE_LEVEL_ERROR,
4448 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4449 &DirEntry->NameInformation.FileName,
4450 pObjectInfo->FileId.Cell,
4451 pObjectInfo->FileId.Volume,
4452 pObjectInfo->FileId.Vnode,
4453 pObjectInfo->FileId.Unique,
4459 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4460 AFS_TRACE_LEVEL_VERBOSE,
4461 "AFSValidateEntry File FID %08lX-%08lX-%08lX-%08lX No Purge Clearing Verify Flag\n",
4462 pObjectInfo->FileId.Cell,
4463 pObjectInfo->FileId.Volume,
4464 pObjectInfo->FileId.Vnode,
4465 pObjectInfo->FileId.Unique));
4467 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4470 // Update file sizes
4473 if( pObjectInfo->Fcb != NULL)
4475 FILE_OBJECT *pCCFileObject;
4477 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4478 AFS_TRACE_LEVEL_VERBOSE,
4479 "AFSValidateEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
4480 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4481 PsGetCurrentThread()));
4483 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4489 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
4491 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
4492 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4493 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
4495 if ( pCCFileObject != NULL)
4497 CcSetFileSizes( pCCFileObject,
4498 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4501 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
4504 ntStatus = GetExceptionCode();
4508 "EXCEPTION - AFSValidateEntry CcSetFileSizes failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
4509 pObjectInfo->FileId.Cell,
4510 pObjectInfo->FileId.Volume,
4511 pObjectInfo->FileId.Vnode,
4512 pObjectInfo->FileId.Unique,
4516 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
4517 AFS_TRACE_LEVEL_VERBOSE,
4518 "AFSValidateEntry Releasing Fcb SectionObject lock %p EXCL %08lX\n",
4519 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
4520 PsGetCurrentThread()));
4522 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
4528 case AFS_FILE_TYPE_DIRECTORY:
4531 if( pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4535 // For a directory or root entry flush the content of
4536 // the directory enumeration.
4539 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
4540 AFS_TRACE_LEVEL_VERBOSE,
4541 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
4542 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4543 PsGetCurrentThread()));
4545 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4548 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4549 AFS_TRACE_LEVEL_VERBOSE_2,
4550 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4551 &DirEntry->NameInformation.FileName,
4552 pObjectInfo->FileId.Cell,
4553 pObjectInfo->FileId.Volume,
4554 pObjectInfo->FileId.Vnode,
4555 pObjectInfo->FileId.Unique));
4557 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4560 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
4563 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4566 if( !NT_SUCCESS( ntStatus))
4569 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4570 AFS_TRACE_LEVEL_ERROR,
4571 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4572 &DirEntry->NameInformation.FileName,
4573 pObjectInfo->FileId.Cell,
4574 pObjectInfo->FileId.Volume,
4575 pObjectInfo->FileId.Vnode,
4576 pObjectInfo->FileId.Unique,
4584 // Update the metadata for the entry
4587 ntStatus = AFSUpdateMetaData( DirEntry,
4590 if( NT_SUCCESS( ntStatus))
4593 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4594 AFS_TRACE_LEVEL_VERBOSE,
4595 "AFSValidateEntry Directory FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
4596 pObjectInfo->FileId.Cell,
4597 pObjectInfo->FileId.Volume,
4598 pObjectInfo->FileId.Vnode,
4599 pObjectInfo->FileId.Unique));
4601 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4609 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4610 AFS_TRACE_LEVEL_WARNING,
4611 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4612 pObjectInfo->FileType,
4614 &DirEntry->NameInformation.FileName,
4615 pObjectInfo->FileId.Cell,
4616 pObjectInfo->FileId.Volume,
4617 pObjectInfo->FileId.Vnode,
4618 pObjectInfo->FileId.Unique));
4628 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4631 if( pDirEnumEntry != NULL)
4634 AFSExFreePoolWithTag( pDirEnumEntry, AFS_GENERIC_MEMORY_2_TAG);
4642 AFSInitializeSpecialShareNameList()
4645 NTSTATUS ntStatus = STATUS_SUCCESS;
4646 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4647 AFSObjectInfoCB *pObjectInfoCB = NULL;
4648 UNICODE_STRING uniShareName;
4649 ULONG ulEntryLength = 0;
4650 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4656 RtlInitUnicodeString( &uniShareName,
4659 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4662 if( pObjectInfoCB == NULL)
4665 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4668 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4669 AFS_OBJECT_REFERENCE_GLOBAL);
4671 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4672 AFS_TRACE_LEVEL_VERBOSE,
4673 "AFSInitializeSpecialShareNameList (srvsvc) Increment count on object %p Cnt %d\n",
4677 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4679 ulEntryLength = sizeof( AFSDirectoryCB) +
4680 uniShareName.Length;
4682 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4686 if( pDirNode == NULL)
4689 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4690 AFS_OBJECT_REFERENCE_GLOBAL);
4692 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4693 AFS_TRACE_LEVEL_VERBOSE,
4694 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4701 AFSDeleteObjectInfo( &pObjectInfoCB);
4704 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4707 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4708 AFS_TRACE_LEVEL_VERBOSE,
4709 "AFSInitializeSpecialShareNameList (srvsvc) AFS_DIR_ENTRY_TAG allocated %p\n",
4712 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4713 sizeof( AFSNonPagedDirectoryCB),
4714 AFS_DIR_ENTRY_NP_TAG);
4716 if( pNonPagedDirEntry == NULL)
4719 AFSLibExFreePoolWithTag( pDirNode,
4722 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4723 AFS_OBJECT_REFERENCE_GLOBAL);
4725 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4726 AFS_TRACE_LEVEL_VERBOSE,
4727 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4734 AFSDeleteObjectInfo( &pObjectInfoCB);
4737 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4740 RtlZeroMemory( pDirNode,
4743 RtlZeroMemory( pNonPagedDirEntry,
4744 sizeof( AFSNonPagedDirectoryCB));
4746 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4748 pDirNode->NonPaged = pNonPagedDirEntry;
4750 pDirNode->ObjectInformation = pObjectInfoCB;
4756 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_PIPE_SERVICE);
4758 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4760 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4762 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4764 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4765 uniShareName.Buffer,
4766 pDirNode->NameInformation.FileName.Length);
4768 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4771 AFSSpecialShareNames = pDirNode;
4773 pLastDirNode = pDirNode;
4776 RtlInitUnicodeString( &uniShareName,
4779 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4782 if( pObjectInfoCB == NULL)
4785 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4788 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
4789 AFS_OBJECT_REFERENCE_GLOBAL);
4791 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4792 AFS_TRACE_LEVEL_VERBOSE,
4793 "AFSInitializeSpecialShareNameList (ipc$) Incrementing count on object %p Cnt %d\n",
4797 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4799 ulEntryLength = sizeof( AFSDirectoryCB) +
4800 uniShareName.Length;
4802 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4806 if( pDirNode == NULL)
4809 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4810 AFS_OBJECT_REFERENCE_GLOBAL);
4812 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4813 AFS_TRACE_LEVEL_VERBOSE,
4814 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4821 AFSDeleteObjectInfo( &pObjectInfoCB);
4824 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4827 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
4828 AFS_TRACE_LEVEL_VERBOSE,
4829 "AFSInitializeSpecialShareNameList (ipc$) AFS_DIR_ENTRY_TAG allocated %p\n",
4832 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4833 sizeof( AFSNonPagedDirectoryCB),
4834 AFS_DIR_ENTRY_NP_TAG);
4836 if( pNonPagedDirEntry == NULL)
4839 AFSLibExFreePoolWithTag( pDirNode,
4842 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
4843 AFS_OBJECT_REFERENCE_GLOBAL);
4845 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4846 AFS_TRACE_LEVEL_VERBOSE,
4847 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4854 AFSDeleteObjectInfo( &pObjectInfoCB);
4857 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4860 RtlZeroMemory( pDirNode,
4863 RtlZeroMemory( pNonPagedDirEntry,
4864 sizeof( AFSNonPagedDirectoryCB));
4866 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4868 pDirNode->NonPaged = pNonPagedDirEntry;
4870 pDirNode->ObjectInformation = pObjectInfoCB;
4876 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4878 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4880 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4882 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4884 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4885 uniShareName.Buffer,
4886 pDirNode->NameInformation.FileName.Length);
4888 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4891 pLastDirNode->ListEntry.fLink = pDirNode;
4893 pDirNode->ListEntry.bLink = pLastDirNode;
4897 if( !NT_SUCCESS( ntStatus))
4900 if( AFSSpecialShareNames != NULL)
4903 pDirNode = AFSSpecialShareNames;
4905 while( pDirNode != NULL)
4908 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4910 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
4911 AFS_OBJECT_REFERENCE_GLOBAL);
4913 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4914 AFS_TRACE_LEVEL_VERBOSE,
4915 "AFSInitializeSpecialShareNameList Decrement count on object %p Cnt %d\n",
4916 pDirNode->ObjectInformation,
4922 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
4925 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4927 AFSLibExFreePoolWithTag( pDirNode->NonPaged,
4928 AFS_DIR_ENTRY_NP_TAG);
4930 AFSLibExFreePoolWithTag( pDirNode,
4933 pDirNode = pLastDirNode;
4936 AFSSpecialShareNames = NULL;
4945 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4946 IN UNICODE_STRING *SecondaryName)
4949 AFSDirectoryCB *pDirectoryCB = NULL;
4950 ULONGLONG ullHash = 0;
4951 UNICODE_STRING uniFullShareName;
4957 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
4958 AFS_TRACE_LEVEL_VERBOSE_2,
4959 "AFSGetSpecialShareNameEntry share name %wZ secondary name %wZ\n",
4963 uniFullShareName = *ShareName;
4966 // Generate our hash value
4969 ullHash = AFSGenerateCRC( &uniFullShareName,
4973 // Loop through our special share names to see if this is one of them
4976 pDirectoryCB = AFSSpecialShareNames;
4978 while( pDirectoryCB != NULL)
4981 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4987 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4991 return pDirectoryCB;
4995 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4999 // Block on the queue flush event
5002 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
5012 AFSWaitOnQueuedReleases()
5015 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
5018 // Block on the queue flush event
5021 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
5031 AFSIsEqualFID( IN AFSFileID *FileId1,
5032 IN AFSFileID *FileId2)
5035 BOOLEAN bIsEqual = FALSE;
5037 if( FileId1->Hash == FileId2->Hash &&
5038 FileId1->Unique == FileId2->Unique &&
5039 FileId1->Vnode == FileId2->Vnode &&
5040 FileId1->Volume == FileId2->Volume &&
5041 FileId1->Cell == FileId2->Cell)
5051 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
5054 NTSTATUS ntStatus = STATUS_SUCCESS;
5055 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
5060 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
5063 // Reset the directory list information
5066 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
5068 while( pCurrentDirEntry != NULL)
5071 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
5073 if( pCurrentDirEntry->DirOpenReferenceCount <= 0 &&
5074 pCurrentDirEntry->NameArrayReferenceCount <= 0)
5077 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
5078 AFS_TRACE_LEVEL_VERBOSE,
5079 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
5081 &pCurrentDirEntry->NameInformation.FileName));
5083 AFSDeleteDirEntry( ObjectInfoCB,
5089 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
5090 AFS_TRACE_LEVEL_VERBOSE,
5091 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
5093 &pCurrentDirEntry->NameInformation.FileName));
5095 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
5097 AFSRemoveNameEntry( ObjectInfoCB,
5101 pCurrentDirEntry = pNextDirEntry;
5104 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
5106 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
5108 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
5110 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
5112 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
5114 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
5116 AFSDbgTrace(( AFS_SUBSYSTEM_DIR_NODE_COUNT,
5117 AFS_TRACE_LEVEL_VERBOSE,
5118 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
5119 ObjectInfoCB->FileId.Cell,
5120 ObjectInfoCB->FileId.Volume,
5121 ObjectInfoCB->FileId.Vnode,
5122 ObjectInfoCB->FileId.Unique));
5129 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
5132 NTSTATUS ntStatus = STATUS_SUCCESS;
5133 AFSDirectoryCB *pDirGlobalDirNode = NULL;
5134 UNICODE_STRING uniFullName;
5139 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
5140 AFS_TRACE_LEVEL_VERBOSE,
5141 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %p EXCL %08lX\n",
5142 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
5143 PsGetCurrentThread()));
5145 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
5148 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
5151 try_return( ntStatus);
5155 // Initialize the root information
5158 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
5161 // Enumerate the shares in the volume
5164 ntStatus = AFSEnumerateDirectory( AuthGroup,
5165 &AFSGlobalRoot->ObjectInformation,
5168 if( !NT_SUCCESS( ntStatus))
5171 try_return( ntStatus);
5174 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
5176 uniFullName.MaximumLength = PAGE_SIZE;
5177 uniFullName.Length = 0;
5179 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
5180 uniFullName.MaximumLength,
5181 AFS_GENERIC_MEMORY_12_TAG);
5183 if( uniFullName.Buffer == NULL)
5187 // Reset the directory content
5190 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
5192 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
5194 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5198 // Populate our list of entries in the NP enumeration list
5201 while( pDirGlobalDirNode != NULL)
5204 uniFullName.Buffer[ 0] = L'\\';
5205 uniFullName.Buffer[ 1] = L'\\';
5207 uniFullName.Length = 2 * sizeof( WCHAR);
5209 RtlCopyMemory( &uniFullName.Buffer[ 2],
5210 AFSServerName.Buffer,
5211 AFSServerName.Length);
5213 uniFullName.Length += AFSServerName.Length;
5215 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
5217 uniFullName.Length += sizeof( WCHAR);
5219 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
5220 pDirGlobalDirNode->NameInformation.FileName.Buffer,
5221 pDirGlobalDirNode->NameInformation.FileName.Length);
5223 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
5225 AFSAddConnectionEx( &uniFullName,
5226 RESOURCEDISPLAYTYPE_SHARE,
5229 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
5232 AFSLibExFreePoolWithTag( uniFullName.Buffer,
5233 AFS_GENERIC_MEMORY_12_TAG);
5237 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
5244 AFSIsRelativeName( IN UNICODE_STRING *Name)
5247 BOOLEAN bIsRelative = FALSE;
5249 if( Name->Length > 0 &&
5250 Name->Buffer[ 0] != L'\\')
5260 AFSIsAbsoluteAFSName( IN UNICODE_STRING *Name)
5262 UNICODE_STRING uniTempName;
5263 BOOLEAN bIsAbsolute = FALSE;
5266 // An absolute AFS path must begin with \afs\... or equivalent
5269 if ( Name->Length == 0 ||
5270 Name->Length <= AFSMountRootName.Length + sizeof( WCHAR) ||
5271 Name->Buffer[ 0] != L'\\' ||
5272 Name->Buffer[ AFSMountRootName.Length/sizeof( WCHAR)] != L'\\')
5278 uniTempName.Length = AFSMountRootName.Length;
5279 uniTempName.MaximumLength = AFSMountRootName.Length;
5281 uniTempName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5282 uniTempName.MaximumLength,
5283 AFS_NAME_BUFFER_TWO_TAG);
5285 if( uniTempName.Buffer == NULL)
5291 RtlCopyMemory( uniTempName.Buffer,
5293 AFSMountRootName.Length);
5295 bIsAbsolute = (0 == RtlCompareUnicodeString( &uniTempName,
5299 AFSExFreePoolWithTag( uniTempName.Buffer,
5300 AFS_NAME_BUFFER_TWO_TAG);
5307 AFSUpdateName( IN UNICODE_STRING *Name)
5312 while( usIndex < Name->Length/sizeof( WCHAR))
5315 if( Name->Buffer[ usIndex] == L'/')
5318 Name->Buffer[ usIndex] = L'\\';
5328 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
5329 IN OUT ULONG *Flags,
5330 IN WCHAR *NameBuffer,
5331 IN USHORT NameLength)
5334 NTSTATUS ntStatus = STATUS_SUCCESS;
5335 WCHAR *pTmpBuffer = NULL;
5341 // If we have enough space then just move in the name otherwise
5342 // allocate a new buffer
5345 if( TargetName->Length < NameLength)
5348 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5350 AFS_NAME_BUFFER_FIVE_TAG);
5352 if( pTmpBuffer == NULL)
5355 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5358 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
5361 AFSExFreePoolWithTag( TargetName->Buffer, AFS_NAME_BUFFER_FIVE_TAG);
5364 TargetName->MaximumLength = NameLength;
5366 TargetName->Buffer = pTmpBuffer;
5368 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
5371 TargetName->Length = NameLength;
5373 RtlCopyMemory( TargetName->Buffer,
5375 TargetName->Length);
5378 // Update the name in the buffer
5381 AFSUpdateName( TargetName);
5392 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5397 // Depending on the type of node, set the event
5400 switch( Fcb->Header.NodeTypeCode)
5403 case AFS_DIRECTORY_FCB:
5408 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5418 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5424 // Depending on the type of node, set the event
5427 switch( Fcb->Header.NodeTypeCode)
5430 case AFS_DIRECTORY_FCB:
5435 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5437 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5447 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5450 BOOLEAN bIsInProcess = FALSE;
5455 if( ObjectInfo->Fcb == NULL)
5458 try_return( bIsInProcess);
5461 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5464 case AFS_DIRECTORY_FCB:
5469 if( ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0)
5472 bIsInProcess = TRUE;
5484 return bIsInProcess;
5488 AFSVerifyVolume( IN ULONGLONG ProcessId,
5489 IN AFSVolumeCB *VolumeCB)
5492 UNREFERENCED_PARAMETER(ProcessId);
5493 UNREFERENCED_PARAMETER(VolumeCB);
5494 NTSTATUS ntStatus = STATUS_SUCCESS;
5501 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ParentObjectInfo)
5504 NTSTATUS ntStatus = STATUS_SUCCESS;
5505 AFSObjectInfoCB *pObjectInfoCB = NULL;
5506 AFSDirectoryCB *pDirNode = NULL;
5507 ULONG ulEntryLength = 0;
5508 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5514 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
5517 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
5520 if( pObjectInfoCB == NULL)
5523 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5525 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5528 lCount = AFSObjectInfoIncrement( pObjectInfoCB,
5529 AFS_OBJECT_REFERENCE_PIOCTL);
5531 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5532 AFS_TRACE_LEVEL_VERBOSE,
5533 "AFSInitPIOCtlDirectoryCB Increment count on object %p Cnt %d\n",
5537 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
5539 pObjectInfoCB->FileType = (ULONG) AFS_FILE_TYPE_PIOCTL;
5541 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5543 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5545 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5549 if( pDirNode == NULL)
5552 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5555 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5556 AFS_TRACE_LEVEL_VERBOSE,
5557 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG allocated %p\n",
5560 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5561 sizeof( AFSNonPagedDirectoryCB),
5562 AFS_DIR_ENTRY_NP_TAG);
5564 if( pNonPagedDirEntry == NULL)
5567 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5570 RtlZeroMemory( pDirNode,
5573 RtlZeroMemory( pNonPagedDirEntry,
5574 sizeof( AFSNonPagedDirectoryCB));
5576 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5578 pDirNode->NonPaged = pNonPagedDirEntry;
5580 pDirNode->ObjectInformation = pObjectInfoCB;
5582 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5588 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5590 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5592 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5594 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5596 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5597 AFSPIOCtlName.Buffer,
5598 pDirNode->NameInformation.FileName.Length);
5600 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5603 if ( InterlockedCompareExchangePointer( (PVOID *)&ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB, pDirNode, NULL) != NULL)
5606 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5607 AFS_TRACE_LEVEL_WARNING,
5608 "AFSInitPIOCtlDirectoryCB Raced PIOCtlDirectoryCB %p pFcb %p\n",
5609 ParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
5612 try_return( ntStatus = STATUS_REPARSE);
5617 if ( ntStatus != STATUS_SUCCESS)
5620 if ( pDirNode != NULL)
5623 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
5624 AFS_TRACE_LEVEL_VERBOSE,
5625 "AFSInitPIOCtlDirectoryCB AFS_DIR_ENTRY_TAG deallocating %p\n",
5628 AFSExFreePoolWithTag( pDirNode, AFS_DIR_ENTRY_TAG);
5631 if( pNonPagedDirEntry != NULL)
5634 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
5636 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
5639 if ( pObjectInfoCB != NULL)
5642 lCount = AFSObjectInfoDecrement( pObjectInfoCB,
5643 AFS_OBJECT_REFERENCE_PIOCTL);
5645 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5646 AFS_TRACE_LEVEL_VERBOSE,
5647 "AFSInitPIOCtlDirectoryCB Decrement count on object %p Cnt %d\n",
5654 AFSDeleteObjectInfo( &pObjectInfoCB);
5664 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5665 IN AFSDirectoryCB *DirectoryCB,
5666 IN UNICODE_STRING *ParentPathName,
5667 IN AFSNameArrayHdr *RelatedNameArray,
5669 OUT AFSFileInfoCB *FileInfo)
5672 NTSTATUS ntStatus = STATUS_SUCCESS;
5673 AFSDirEnumEntry *pDirEntry = NULL;
5674 UNICODE_STRING uniFullPathName = {0};
5675 AFSNameArrayHdr *pNameArray = NULL;
5676 AFSVolumeCB *pVolumeCB = NULL;
5677 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5678 AFSVolumeCB *pNewVolumeCB = NULL;
5679 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
5680 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5681 AFSDirectoryCB *pNewParentDirEntry = NULL;
5682 WCHAR *pwchBuffer = NULL;
5683 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5684 ULONG ulNameDifference = 0;
5686 UNICODE_STRING uniDFSTargetName;
5691 uniDFSTargetName.Length = 0;
5692 uniDFSTargetName.MaximumLength = 0;
5693 uniDFSTargetName.Buffer = NULL;
5696 // Retrieve a target name for the entry
5699 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5702 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5705 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5707 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5712 if( !NT_SUCCESS( ntStatus) ||
5713 pDirEntry->TargetNameLength == 0)
5716 if( pDirEntry != NULL)
5719 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5722 try_return( ntStatus);
5725 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5728 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5732 // Update the target name
5735 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5736 &DirectoryCB->Flags,
5737 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5738 (USHORT)pDirEntry->TargetNameLength);
5740 if( !NT_SUCCESS( ntStatus))
5743 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5745 try_return( ntStatus);
5749 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5753 // Need to pass the full path in for parsing.
5756 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5759 uniFullPathName.Length = 0;
5760 uniFullPathName.MaximumLength = ParentPathName->Length +
5762 DirectoryCB->NameInformation.TargetName.Length;
5764 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5765 uniFullPathName.MaximumLength,
5766 AFS_NAME_BUFFER_SIX_TAG);
5768 if( uniFullPathName.Buffer == NULL)
5771 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5773 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5776 pwchBuffer = uniFullPathName.Buffer;
5778 RtlZeroMemory( uniFullPathName.Buffer,
5779 uniFullPathName.MaximumLength);
5781 if ( ParentPathName->Length > 0)
5784 RtlCopyMemory( uniFullPathName.Buffer,
5785 ParentPathName->Buffer,
5786 ParentPathName->Length);
5788 uniFullPathName.Length = ParentPathName->Length;
5790 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5791 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5794 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5796 uniFullPathName.Length += sizeof( WCHAR);
5800 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5801 DirectoryCB->NameInformation.TargetName.Buffer,
5802 DirectoryCB->NameInformation.TargetName.Length);
5804 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5806 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5807 uniParsedName.MaximumLength = uniParsedName.Length;
5809 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5811 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5814 // We populate up to the current parent
5817 if( RelatedNameArray != NULL)
5820 pNameArray = AFSInitNameArray( NULL,
5821 RelatedNameArray->MaxElementCount);
5823 if( pNameArray == NULL)
5826 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5829 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5836 pNameArray = AFSInitNameArray( NULL,
5839 if( pNameArray == NULL)
5842 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5845 ntStatus = AFSPopulateNameArray( pNameArray,
5850 if( !NT_SUCCESS( ntStatus))
5853 try_return( ntStatus);
5856 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5858 pParentDirEntry = ParentDirectoryCB;
5863 uniFullPathName.Length = 0;
5864 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5866 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5867 uniFullPathName.MaximumLength,
5868 AFS_NAME_BUFFER_SEVEN_TAG);
5870 if( uniFullPathName.Buffer == NULL)
5873 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5875 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5878 pwchBuffer = uniFullPathName.Buffer;
5880 RtlZeroMemory( uniFullPathName.Buffer,
5881 uniFullPathName.MaximumLength);
5883 RtlCopyMemory( uniFullPathName.Buffer,
5884 DirectoryCB->NameInformation.TargetName.Buffer,
5885 DirectoryCB->NameInformation.TargetName.Length);
5887 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5890 // This name should begin with the \afs server so parse it off and check it
5893 FsRtlDissectName( uniFullPathName,
5897 if( RtlCompareUnicodeString( &uniComponentName,
5902 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5904 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
5905 AFS_TRACE_LEVEL_ERROR,
5906 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5909 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5912 uniFullPathName = uniRemainingPath;
5914 uniParsedName = uniFullPathName;
5916 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5918 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5924 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5927 if( pNameArray == NULL)
5930 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5933 pVolumeCB = AFSGlobalRoot;
5935 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5939 // Increment the ref count on the volume and dir entry for correct processing below
5942 VolumeReferenceReason = AFS_VOLUME_REFERENCE_FILE_ATTRS;
5944 lCount = AFSVolumeIncrement( pVolumeCB,
5945 VolumeReferenceReason);
5947 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5948 AFS_TRACE_LEVEL_VERBOSE,
5949 "AFSRetrieveFileAttributes Increment count on volume %p Reason %u Cnt %d\n",
5951 VolumeReferenceReason,
5954 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
5956 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5957 AFS_TRACE_LEVEL_VERBOSE,
5958 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5959 &pParentDirEntry->NameInformation.FileName,
5964 ntStatus = AFSLocateNameEntry( NULL,
5969 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5973 &NewVolumeReferenceReason,
5974 &pNewParentDirEntry,
5979 if ( pNewVolumeCB != NULL)
5982 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
5983 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
5984 // the reference on pVolumeCB that was held prior to the call.
5985 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
5986 // will be released second.
5989 lCount = AFSVolumeDecrement( pVolumeCB,
5990 VolumeReferenceReason);
5992 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5993 AFS_TRACE_LEVEL_VERBOSE,
5994 "AFSRetrieveFileAttributes Decrement count on volume %p Reason %u Cnt %d\n",
5996 VolumeReferenceReason,
5999 pVolumeCB = pNewVolumeCB;
6001 pNewVolumeCB = NULL;
6003 VolumeReferenceReason = NewVolumeReferenceReason;
6005 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6009 // AFSLocateNameEntry does not alter the reference count of
6010 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6011 // a reference held.
6014 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6016 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6017 AFS_TRACE_LEVEL_VERBOSE,
6018 "AFSRetrieveFileAttributes DecrementX count on %wZ DE %p Cnt %d\n",
6019 &pParentDirEntry->NameInformation.FileName,
6023 pParentDirEntry = pNewParentDirEntry;
6025 pNewParentDirEntry = NULL;
6027 if( !NT_SUCCESS( ntStatus))
6029 try_return( ntStatus);
6033 // If the status is STATUS_REPARSE then attempt to retrieve the attributes from the target name returned
6036 if( ntStatus == STATUS_REPARSE)
6039 ntStatus = AFSRetrieveTargetFileInfo( &uniDFSTargetName,
6042 try_return( ntStatus);
6046 // Store off the information
6049 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
6052 // Check for the mount point being returned
6055 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
6056 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6059 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6061 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK)
6064 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6067 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6072 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6076 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6078 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6080 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6082 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6084 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6086 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6090 if( pDirEntry != NULL)
6093 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6096 if( pDirectoryEntry != NULL)
6099 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6101 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6102 AFS_TRACE_LEVEL_VERBOSE,
6103 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6104 &pDirectoryEntry->NameInformation.FileName,
6109 ASSERT( lCount >= 0);
6112 if ( pParentDirEntry != NULL)
6115 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6117 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6118 AFS_TRACE_LEVEL_VERBOSE,
6119 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6120 &pParentDirEntry->NameInformation.FileName,
6125 ASSERT( lCount >= 0);
6128 if( pVolumeCB != NULL)
6131 lCount = AFSVolumeDecrement( pVolumeCB,
6132 VolumeReferenceReason);
6134 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6135 AFS_TRACE_LEVEL_VERBOSE,
6136 "AFSRetrieveFileAttributes Decrement2 count on volume %p Reason %u Cnt %d\n",
6138 VolumeReferenceReason,
6142 if( pNameArray != NULL)
6145 AFSFreeNameArray( pNameArray);
6148 if( pwchBuffer != NULL)
6152 // Always free the buffer that we allocated as AFSLocateNameEntry
6153 // will not free it. If uniFullPathName.Buffer was allocated by
6154 // AFSLocateNameEntry, then we must free that as well.
6155 // Check that the uniFullPathName.Buffer in the string is not the same
6156 // offset by the length of the server name
6159 if( uniFullPathName.Length > 0 &&
6160 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6163 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6166 AFSExFreePoolWithTag( pwchBuffer, 0);
6169 if ( uniDFSTargetName.Buffer != NULL)
6172 AFSExFreePoolWithTag( uniDFSTargetName.Buffer,
6173 AFS_REPARSE_NAME_TAG);
6181 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6182 IN ULONGLONG HashIndex)
6185 NTSTATUS ntStatus = STATUS_SUCCESS;
6186 AFSObjectInfoCB *pObjectInfo = NULL;
6192 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6193 sizeof( AFSObjectInfoCB),
6194 AFS_OBJECT_INFO_TAG);
6196 if( pObjectInfo == NULL)
6199 try_return( pObjectInfo);
6202 RtlZeroMemory( pObjectInfo,
6203 sizeof( AFSObjectInfoCB));
6205 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6206 sizeof( AFSNonPagedObjectInfoCB),
6207 AFS_NP_OBJECT_INFO_TAG);
6209 if( pObjectInfo->NonPagedInfo == NULL)
6212 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6214 try_return( pObjectInfo = NULL);
6217 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6219 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6221 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6223 if( ParentObjectInfo != NULL)
6226 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6228 pObjectInfo->ParentFileId = ParentObjectInfo->FileId;
6230 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6232 AFSAcquireShared( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6235 lCount = AFSObjectInfoIncrement( ParentObjectInfo,
6236 AFS_OBJECT_REFERENCE_CHILD);
6238 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6239 AFS_TRACE_LEVEL_VERBOSE,
6240 "AFSAllocateObjectInfo Increment count on parent object %p Cnt %d\n",
6244 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6248 // Initialize the access time
6251 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6256 ASSERT( ParentObjectInfo);
6259 // Insert the entry into the object tree and list
6262 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6264 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6267 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6272 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6273 &pObjectInfo->TreeEntry);
6275 ASSERT( NT_SUCCESS( ntStatus));
6279 // And the object list in the volume
6282 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6285 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6290 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6292 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6295 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6298 // Indicate the object is in the hash tree and linked list in the volume
6301 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6313 AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo,
6319 if ( ObjectInfo->ObjectReferenceCount == 0)
6322 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6325 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6330 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6333 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6338 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6340 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6345 InterlockedIncrement( &ObjectInfo->ObjectReferences[ Reason]);
6347 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6353 AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo,
6357 LONG lCount, lCount2;
6359 AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6362 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6367 lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
6369 AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
6371 AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
6374 lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
6377 lCount2 = InterlockedDecrement( &ObjectInfo->ObjectReferences[ Reason]);
6379 ASSERT( lCount2 >= 0);
6381 AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
6387 AFSFindObjectInfo( IN AFSVolumeCB *VolumeCB,
6388 IN AFSFileID *FileId,
6389 IN BOOLEAN bUpdateLastUse)
6391 DWORD ntStatus = STATUS_SUCCESS;
6393 AFSObjectInfoCB *pObjectInfo = NULL;
6396 ullIndex = AFSCreateLowIndex( FileId);
6398 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
6401 if ( AFSIsEqualFID( &VolumeCB->ObjectInformation.FileId, FileId))
6404 pObjectInfo = &VolumeCB->ObjectInformation;
6409 ntStatus = AFSLocateHashEntry( VolumeCB->ObjectInfoTree.TreeHead,
6411 (AFSBTreeEntry **)&pObjectInfo);
6414 if ( NT_SUCCESS( ntStatus)) {
6416 lCount = AFSObjectInfoIncrement( pObjectInfo,
6417 AFS_OBJECT_REFERENCE_FIND);
6419 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6420 AFS_TRACE_LEVEL_VERBOSE,
6421 "AFSFindObjectInfo Decrement count on object %p Cnt %d\n",
6425 if ( bUpdateLastUse)
6428 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6432 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
6438 AFSReleaseObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6442 lCount = AFSObjectInfoDecrement( *ppObjectInfo,
6443 AFS_OBJECT_REFERENCE_FIND);
6445 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6446 AFS_TRACE_LEVEL_VERBOSE,
6447 "AFSReleaseObjectInfo Decrement count on object %p Cnt %d\n",
6451 *ppObjectInfo = NULL;
6455 AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
6457 BOOLEAN bAcquiredTreeLock = FALSE;
6458 AFSObjectInfoCB *pObjectInfo = NULL;
6459 AFSVolumeCB * pVolume = NULL;
6460 BOOLEAN bHeldInService;
6461 AFSObjectInfoCB * pParentObjectInfo = NULL;
6467 if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
6471 // AFSDeleteObjectInfo should never be called on the ObjectInformationCB
6472 // embedded in the VolumeCB.
6480 pVolume = (*ppObjectInfo)->VolumeCB;
6482 if( !ExIsResourceAcquiredExclusiveLite( pVolume->ObjectInfoTree.TreeLock))
6485 ASSERT( !ExIsResourceAcquiredLite( pVolume->ObjectInfoTree.TreeLock));
6487 AFSAcquireExcl( pVolume->ObjectInfoTree.TreeLock,
6490 bAcquiredTreeLock = TRUE;
6493 for ( lCount = 0; lCount < AFS_OBJECT_REFERENCE_MAX; lCount++)
6496 ASSERT( (*ppObjectInfo)->ObjectReferences[ lCount] >= 0);
6499 ASSERT( (*ppObjectInfo)->ObjectReferenceCount == 0);
6501 pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
6505 if ( pObjectInfo == NULL)
6508 try_return( NOTHING);
6511 ASSERT( *ppObjectInfo == NULL);
6513 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
6516 pParentObjectInfo = AFSFindObjectInfo( pVolume,
6517 &pObjectInfo->ParentFileId,
6520 if( pParentObjectInfo != NULL)
6523 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID);
6525 AFSAcquireShared( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6528 lCount = AFSObjectInfoDecrement( pParentObjectInfo,
6529 AFS_OBJECT_REFERENCE_CHILD);
6531 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
6532 AFS_TRACE_LEVEL_VERBOSE,
6533 "AFSDeleteObjectInfo Decrement count on parent object %p Cnt %d\n",
6537 AFSReleaseResource( pParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6539 AFSReleaseObjectInfo( &pParentObjectInfo);
6544 // Remove it from the tree and list if it was inserted
6547 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6550 AFSRemoveHashEntry( &pVolume->ObjectInfoTree.TreeHead,
6551 &pObjectInfo->TreeEntry);
6554 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6557 if( pObjectInfo->ListEntry.fLink == NULL)
6560 pVolume->ObjectInfoListTail = (AFSObjectInfoCB *)pObjectInfo->ListEntry.bLink;
6562 if( pVolume->ObjectInfoListTail != NULL)
6565 pVolume->ObjectInfoListTail->ListEntry.fLink = NULL;
6571 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.fLink))->ListEntry.bLink = pObjectInfo->ListEntry.bLink;
6574 if( pObjectInfo->ListEntry.bLink == NULL)
6577 pVolume->ObjectInfoListHead = (AFSObjectInfoCB *)pObjectInfo->ListEntry.fLink;
6579 if( pVolume->ObjectInfoListHead != NULL)
6582 pVolume->ObjectInfoListHead->ListEntry.bLink = NULL;
6588 ((AFSObjectInfoCB *)(pObjectInfo->ListEntry.bLink))->ListEntry.fLink = pObjectInfo->ListEntry.fLink;
6592 bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
6597 FileId = pObjectInfo->FileId;
6600 ASSERT( pObjectInfo->ObjectReferenceCount == 0);
6602 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
6604 ExDeleteResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6606 AFSExFreePoolWithTag( pObjectInfo->NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
6608 AFSExFreePoolWithTag( pObjectInfo, AFS_OBJECT_INFO_TAG);
6612 if( bAcquiredTreeLock)
6615 AFSReleaseResource( pVolume->ObjectInfoTree.TreeLock);
6619 // Release the fid in the service
6625 AFSReleaseFid( &FileId);
6633 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6634 OUT AFSDirectoryCB **TargetDirEntry)
6637 NTSTATUS ntStatus = STATUS_SUCCESS;
6638 AFSDirEnumEntry *pDirEntry = NULL;
6639 UNICODE_STRING uniFullPathName = {0};
6640 AFSNameArrayHdr *pNameArray = NULL;
6641 AFSVolumeCB *pVolumeCB = NULL;
6642 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6643 AFSVolumeCB *pNewVolumeCB = NULL;
6644 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6645 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6646 AFSDirectoryCB *pNewParentDirEntry = NULL;
6647 WCHAR *pwchBuffer = NULL;
6648 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6649 ULONG ulNameDifference = 0;
6656 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6657 DirectoryCB->ObjectInformation,
6661 if( !NT_SUCCESS( ntStatus))
6663 try_return( ntStatus);
6667 // Retrieve a target name for the entry
6670 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6673 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6676 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6678 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6683 if( !NT_SUCCESS( ntStatus) ||
6684 pDirEntry->TargetNameLength == 0)
6687 if( pDirEntry != NULL)
6690 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6693 try_return( ntStatus);
6696 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6699 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6703 // Update the target name
6706 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6707 &DirectoryCB->Flags,
6708 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6709 (USHORT)pDirEntry->TargetNameLength);
6711 if( !NT_SUCCESS( ntStatus))
6714 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6716 try_return( ntStatus);
6720 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6724 // Need to pass the full path in for parsing.
6727 uniFullPathName.Length = 0;
6728 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6730 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6731 uniFullPathName.MaximumLength,
6732 AFS_NAME_BUFFER_EIGHT_TAG);
6734 if( uniFullPathName.Buffer == NULL)
6737 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6739 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6742 pwchBuffer = uniFullPathName.Buffer;
6744 RtlZeroMemory( uniFullPathName.Buffer,
6745 uniFullPathName.MaximumLength);
6747 RtlCopyMemory( uniFullPathName.Buffer,
6748 DirectoryCB->NameInformation.TargetName.Buffer,
6749 DirectoryCB->NameInformation.TargetName.Length);
6751 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6754 // This name should begin with the \afs server so parse it off and chech it
6757 FsRtlDissectName( uniFullPathName,
6761 if( RtlCompareUnicodeString( &uniComponentName,
6767 // Try evaluating the full path
6770 uniFullPathName.Buffer = pwchBuffer;
6772 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6774 uniFullPathName.MaximumLength = uniFullPathName.Length;
6779 uniFullPathName = uniRemainingPath;
6782 uniParsedName = uniFullPathName;
6784 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6786 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6792 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6795 if( pNameArray == NULL)
6798 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6801 pVolumeCB = AFSGlobalRoot;
6803 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6805 VolumeReferenceReason = AFS_VOLUME_REFERENCE_EVAL_ROOT;
6807 lCount = AFSVolumeIncrement( pVolumeCB,
6808 VolumeReferenceReason);
6810 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6811 AFS_TRACE_LEVEL_VERBOSE,
6812 "AFSEvaluateRootEntry Increment count on volume %p Reason %u Cnt %d\n",
6814 VolumeReferenceReason,
6817 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
6819 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6820 AFS_TRACE_LEVEL_VERBOSE,
6821 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6822 &pParentDirEntry->NameInformation.FileName,
6827 ntStatus = AFSLocateNameEntry( NULL,
6836 &VolumeReferenceReason,
6837 &pNewParentDirEntry,
6842 if ( pNewVolumeCB != NULL)
6845 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
6846 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
6847 // the reference on pVolumeCB that was held prior to the call.
6848 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
6849 // will be released second.
6852 lCount = AFSVolumeDecrement( pVolumeCB,
6853 VolumeReferenceReason);
6855 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6856 AFS_TRACE_LEVEL_VERBOSE,
6857 "AFSEvaluateRootEntry Decrement count on volume %p Reason %u Cnt %d\n",
6859 VolumeReferenceReason,
6862 pVolumeCB = pNewVolumeCB;
6864 pNewVolumeCB = NULL;
6866 VolumeReferenceReason = NewVolumeReferenceReason;
6868 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
6872 // AFSLocateNameEntry does not alter the reference count of
6873 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
6874 // a reference held.
6877 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6879 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6880 AFS_TRACE_LEVEL_VERBOSE,
6881 "AFSEvaluateRootEntry DecrementX count on %wZ DE %p Cnt %d\n",
6882 &pParentDirEntry->NameInformation.FileName,
6886 pParentDirEntry = pNewParentDirEntry;
6888 pNewParentDirEntry = NULL;
6890 if( !NT_SUCCESS( ntStatus) ||
6891 ntStatus == STATUS_REPARSE)
6896 try_return( ntStatus);
6900 // Pass back the target dir entry for this request
6901 // The caller must release the DirOpenReferenceCount
6904 *TargetDirEntry = pDirectoryEntry;
6906 pDirectoryEntry = NULL;
6910 if( pDirectoryEntry != NULL)
6913 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
6915 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6916 AFS_TRACE_LEVEL_VERBOSE,
6917 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6918 &pDirectoryEntry->NameInformation.FileName,
6923 ASSERT( lCount >= 0);
6926 if ( pParentDirEntry != NULL)
6929 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
6931 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6932 AFS_TRACE_LEVEL_VERBOSE,
6933 "AFSEvaluateRootEntry Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
6934 &pParentDirEntry->NameInformation.FileName,
6939 ASSERT( lCount >= 0);
6942 if( pDirEntry != NULL)
6945 AFSExFreePoolWithTag( pDirEntry, AFS_GENERIC_MEMORY_2_TAG);
6948 if( pVolumeCB != NULL)
6951 lCount = AFSVolumeDecrement( pVolumeCB,
6952 VolumeReferenceReason);
6954 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6955 AFS_TRACE_LEVEL_VERBOSE,
6956 "AFSEvaluateRootEntry Decrement2 count on volume %p Reason %u Cnt %d\n",
6958 VolumeReferenceReason,
6962 if( pNameArray != NULL)
6965 AFSFreeNameArray( pNameArray);
6968 if( pwchBuffer != NULL)
6972 // Always free the buffer that we allocated as AFSLocateNameEntry
6973 // will not free it. If uniFullPathName.Buffer was allocated by
6974 // AFSLocateNameEntry, then we must free that as well.
6975 // Check that the uniFullPathName.Buffer in the string is not the same
6976 // offset by the length of the server name
6979 if( uniFullPathName.Length > 0 &&
6980 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6983 AFSExFreePoolWithTag( uniFullPathName.Buffer, 0);
6986 AFSExFreePoolWithTag( pwchBuffer, 0);
6994 AFSCleanupFcb( IN AFSFcb *Fcb,
6995 IN BOOLEAN ForceFlush)
6998 NTSTATUS ntStatus = STATUS_SUCCESS;
6999 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
7000 LARGE_INTEGER liTime;
7001 IO_STATUS_BLOCK stIoStatus;
7006 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7008 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7010 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
7013 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
7014 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7017 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7018 AFS_TRACE_LEVEL_VERBOSE,
7019 "AFSCleanupEntry Acquiring Fcb lock %p EXCL %08lX\n",
7020 &Fcb->NPFcb->Resource,
7021 PsGetCurrentThread()));
7023 AFSAcquireExcl( &Fcb->NPFcb->Resource,
7026 if( Fcb->OpenReferenceCount > 0)
7029 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7030 AFS_TRACE_LEVEL_VERBOSE,
7031 "AFSCleanupEntry Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7032 &Fcb->NPFcb->SectionObjectResource,
7033 PsGetCurrentThread()));
7035 AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource,
7041 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7046 if( !NT_SUCCESS( stIoStatus.Status))
7049 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7050 AFS_TRACE_LEVEL_ERROR,
7051 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7052 Fcb->ObjectInformation->FileId.Cell,
7053 Fcb->ObjectInformation->FileId.Volume,
7054 Fcb->ObjectInformation->FileId.Vnode,
7055 Fcb->ObjectInformation->FileId.Unique,
7057 stIoStatus.Information));
7059 ntStatus = stIoStatus.Status;
7062 if ( Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7065 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7071 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7072 AFS_TRACE_LEVEL_WARNING,
7073 "AFSCleanupFcb CcPurgeCacheSection [1] failure FID %08lX-%08lX-%08lX-%08lX\n",
7074 Fcb->ObjectInformation->FileId.Cell,
7075 Fcb->ObjectInformation->FileId.Volume,
7076 Fcb->ObjectInformation->FileId.Vnode,
7077 Fcb->ObjectInformation->FileId.Unique));
7079 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7083 __except( EXCEPTION_EXECUTE_HANDLER)
7086 ntStatus = GetExceptionCode();
7090 "EXCEPTION - AFSCleanupFcb Cc [1] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7091 Fcb->ObjectInformation->FileId.Cell,
7092 Fcb->ObjectInformation->FileId.Volume,
7093 Fcb->ObjectInformation->FileId.Vnode,
7094 Fcb->ObjectInformation->FileId.Unique,
7097 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7100 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7101 AFS_TRACE_LEVEL_VERBOSE,
7102 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7103 &Fcb->NPFcb->SectionObjectResource,
7104 PsGetCurrentThread()));
7106 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7109 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7110 AFS_TRACE_LEVEL_VERBOSE,
7111 "AFSCleanupEntry Releasing Fcb lock %p EXCL %08lX\n",
7112 &Fcb->NPFcb->Resource,
7113 PsGetCurrentThread()));
7115 AFSReleaseResource( &Fcb->NPFcb->Resource);
7117 if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
7120 // Wait for any currently running flush or release requests to complete
7123 AFSWaitOnQueuedFlushes( Fcb);
7126 // Now perform another flush on the file
7129 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7133 AFSReleaseExtentsWithFlush( Fcb,
7140 if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
7143 if( Fcb->OpenReferenceCount == 0 ||
7144 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7145 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7148 AFSTearDownFcbExtents( Fcb,
7153 try_return( ntStatus);
7156 KeQueryTickCount( &liTime);
7158 if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
7161 // First up are there dirty extents in the cache to flush?
7164 if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
7165 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
7169 // The file has been marked as invalid. Dump it
7172 AFSTearDownFcbExtents( Fcb,
7175 else if( ForceFlush ||
7176 ( ( Fcb->Specific.File.ExtentsDirtyCount ||
7177 Fcb->Specific.File.ExtentCount) &&
7178 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
7179 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
7182 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
7184 Fcb->OpenReferenceCount == 0)
7187 AFSReleaseExtentsWithFlush( Fcb,
7195 // If there are extents and they haven't been used recently *and*
7196 // are not being used
7200 ( 0 != Fcb->Specific.File.ExtentCount &&
7201 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
7202 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
7203 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))))
7206 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7207 AFS_TRACE_LEVEL_VERBOSE,
7208 "AFSCleanupFcb Acquiring Fcb lock %p EXCL %08lX\n",
7209 &Fcb->NPFcb->Resource,
7210 PsGetCurrentThread()));
7212 if ( AFSAcquireExcl( &Fcb->NPFcb->Resource, ForceFlush) == FALSE)
7215 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7216 AFS_TRACE_LEVEL_VERBOSE,
7217 "AFSCleanupFcb Failed to Acquire Fcb lock %p EXCL %08lX\n",
7218 &Fcb->NPFcb->Resource,
7219 PsGetCurrentThread()));
7221 try_return( ntStatus = STATUS_RETRY);
7224 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7225 AFS_TRACE_LEVEL_VERBOSE,
7226 "AFSCleanupFcb Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
7227 &Fcb->NPFcb->SectionObjectResource,
7228 PsGetCurrentThread()));
7230 if ( AFSAcquireExcl( &Fcb->NPFcb->SectionObjectResource, ForceFlush))
7236 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
7241 if( !NT_SUCCESS( stIoStatus.Status))
7244 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7245 AFS_TRACE_LEVEL_ERROR,
7246 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
7247 Fcb->ObjectInformation->FileId.Cell,
7248 Fcb->ObjectInformation->FileId.Volume,
7249 Fcb->ObjectInformation->FileId.Vnode,
7250 Fcb->ObjectInformation->FileId.Unique,
7252 stIoStatus.Information));
7254 ntStatus = stIoStatus.Status;
7258 Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL)
7261 if ( !CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
7267 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
7268 AFS_TRACE_LEVEL_WARNING,
7269 "AFSCleanupFcb CcPurgeCacheSection [2] failure FID %08lX-%08lX-%08lX-%08lX\n",
7270 Fcb->ObjectInformation->FileId.Cell,
7271 Fcb->ObjectInformation->FileId.Volume,
7272 Fcb->ObjectInformation->FileId.Vnode,
7273 Fcb->ObjectInformation->FileId.Unique));
7275 SetFlag( Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
7279 __except( EXCEPTION_EXECUTE_HANDLER)
7282 ntStatus = GetExceptionCode();
7286 "EXCEPTION - AFSCleanupFcb Cc [2] FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
7287 Fcb->ObjectInformation->FileId.Cell,
7288 Fcb->ObjectInformation->FileId.Volume,
7289 Fcb->ObjectInformation->FileId.Vnode,
7290 Fcb->ObjectInformation->FileId.Unique,
7294 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7295 AFS_TRACE_LEVEL_VERBOSE,
7296 "AFSCleanupFcb Releasing Fcb SectionObject lock %p EXCL %08lX\n",
7297 &Fcb->NPFcb->SectionObjectResource,
7298 PsGetCurrentThread()));
7300 AFSReleaseResource( &Fcb->NPFcb->SectionObjectResource);
7302 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7303 AFS_TRACE_LEVEL_VERBOSE,
7304 "AFSCleanupFcb Releasing Fcb lock %p EXCL %08lX\n",
7305 &Fcb->NPFcb->Resource,
7306 PsGetCurrentThread()));
7308 AFSReleaseResource( &Fcb->NPFcb->Resource);
7310 if( !BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
7313 if( Fcb->OpenReferenceCount <= 0)
7317 // Tear em down we'll not be needing them again
7320 AFSTearDownFcbExtents( Fcb,
7328 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
7329 AFS_TRACE_LEVEL_VERBOSE,
7330 "AFSCleanupFcb Failed to Acquire Fcb SectionObject lock %p EXCL %08lX\n",
7331 &Fcb->NPFcb->SectionObjectResource,
7332 PsGetCurrentThread()));
7334 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
7335 AFS_TRACE_LEVEL_VERBOSE,
7336 "AFSCleanupFcb Releasing Fcb lock %p EXCL %08lX\n",
7337 &Fcb->NPFcb->Resource,
7338 PsGetCurrentThread()));
7340 AFSReleaseResource( &Fcb->NPFcb->Resource);
7342 ntStatus = STATUS_RETRY;
7355 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
7356 IN UNICODE_STRING *NewFileName)
7359 NTSTATUS ntStatus = STATUS_SUCCESS;
7360 WCHAR *pTmpBuffer = NULL;
7365 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
7368 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
7371 AFSExFreePoolWithTag( DirectoryCB->NameInformation.FileName.Buffer, 0);
7373 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7375 DirectoryCB->NameInformation.FileName.Buffer = NULL;
7379 // OK, we need to allocate a new name buffer
7382 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
7383 NewFileName->Length,
7384 AFS_NAME_BUFFER_NINE_TAG);
7386 if( pTmpBuffer == NULL)
7389 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7392 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
7394 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
7396 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
7399 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
7401 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
7402 NewFileName->Buffer,
7403 NewFileName->Length);
7414 AFSReadCacheFile( IN void *ReadBuffer,
7415 IN LARGE_INTEGER *ReadOffset,
7416 IN ULONG RequestedDataLength,
7417 IN OUT PULONG BytesRead)
7420 NTSTATUS ntStatus = STATUS_SUCCESS;
7423 PIO_STACK_LOCATION pIoStackLocation = NULL;
7424 DEVICE_OBJECT *pTargetDeviceObject = NULL;
7425 FILE_OBJECT *pCacheFileObject = NULL;
7430 pCacheFileObject = AFSReferenceCacheFileObject();
7432 if( pCacheFileObject == NULL)
7434 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
7437 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
7440 // Initialize the event
7443 KeInitializeEvent( &kEvent,
7444 SynchronizationEvent,
7448 // Allocate an irp for this request. This could also come from a
7449 // private pool, for instance.
7452 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
7458 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7462 // Build the IRP's main body
7465 pIrp->UserBuffer = ReadBuffer;
7467 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
7468 pIrp->RequestorMode = KernelMode;
7469 pIrp->Flags |= IRP_READ_OPERATION;
7472 // Set up the I/O stack location.
7475 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
7476 pIoStackLocation->MajorFunction = IRP_MJ_READ;
7477 pIoStackLocation->DeviceObject = pTargetDeviceObject;
7478 pIoStackLocation->FileObject = pCacheFileObject;
7479 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
7481 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
7484 // Set the completion routine.
7487 IoSetCompletionRoutine( pIrp,
7495 // Send it to the FSD
7498 ntStatus = IoCallDriver( pTargetDeviceObject,
7501 if( NT_SUCCESS( ntStatus))
7508 ntStatus = KeWaitForSingleObject( &kEvent,
7514 if( NT_SUCCESS( ntStatus))
7517 ntStatus = pIrp->IoStatus.Status;
7519 *BytesRead = (ULONG)pIrp->IoStatus.Information;
7525 if( pCacheFileObject != NULL)
7527 AFSReleaseCacheFileObject( pCacheFileObject);
7533 if( pIrp->MdlAddress != NULL)
7536 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7539 MmUnlockPages( pIrp->MdlAddress);
7542 IoFreeMdl( pIrp->MdlAddress);
7545 pIrp->MdlAddress = NULL;
7559 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7564 UNREFERENCED_PARAMETER(Irp);
7565 UNREFERENCED_PARAMETER(DeviceObject);
7566 KEVENT *pEvent = (KEVENT *)Context;
7572 return STATUS_MORE_PROCESSING_REQUIRED;
7576 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7579 BOOLEAN bIsEmpty = FALSE;
7580 AFSDirectoryCB *pDirEntry = NULL;
7585 ASSERT( Fcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY);
7587 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7592 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7595 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7597 while( pDirEntry != NULL)
7600 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7601 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7609 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7614 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7621 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7622 IN AFSDirectoryCB *DirEntry)
7625 NTSTATUS ntStatus = STATUS_SUCCESS;
7630 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7633 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7634 AFS_TRACE_LEVEL_VERBOSE,
7635 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7637 &DirEntry->NameInformation.FileName));
7639 try_return( ntStatus);
7642 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7645 // Remove the entry from the parent tree
7648 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7649 AFS_TRACE_LEVEL_VERBOSE,
7650 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7652 &DirEntry->NameInformation.FileName));
7654 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7657 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7658 AFS_TRACE_LEVEL_VERBOSE,
7659 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7661 &DirEntry->NameInformation.FileName));
7663 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7666 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7670 // From the short name tree
7673 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7674 AFS_TRACE_LEVEL_VERBOSE,
7675 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7677 &DirEntry->NameInformation.FileName));
7679 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7682 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7685 AFSDbgTrace(( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
7686 AFS_TRACE_LEVEL_VERBOSE,
7687 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7689 &DirEntry->NameInformation.FileName));
7691 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7693 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7704 AFSGetAuthenticationId( OUT LARGE_INTEGER *pliAuthId)
7706 AFSWorkItem *pWorkItem = NULL;
7712 RtlZeroMemory( pliAuthId, sizeof(LARGE_INTEGER));
7714 pWorkItem = (AFSWorkItem *) AFSExAllocatePoolWithTag( NonPagedPool,
7715 sizeof(AFSWorkItem),
7717 if (NULL == pWorkItem)
7720 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7721 AFS_TRACE_LEVEL_ERROR,
7722 "AFSGetAuthenticationId Failed to allocate work item\n"));
7724 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES );
7727 RtlZeroMemory( pWorkItem,
7728 sizeof(AFSWorkItem));
7730 pWorkItem->Size = sizeof( AFSWorkItem);
7732 pWorkItem->RequestType = AFS_WORK_GET_AUTH_ID;
7734 pWorkItem->RequestFlags = AFS_SYNCHRONOUS_REQUEST;
7736 KeInitializeEvent(&pWorkItem->Event,
7740 pWorkItem->Specific.GetAuthId.peProcess = PsGetCurrentProcess();
7742 pWorkItem->Specific.GetAuthId.peThread = PsGetCurrentThread();
7744 AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
7745 AFS_TRACE_LEVEL_VERBOSE,
7746 "AFSGetAuthenticationId Workitem %p\n",
7749 ntStatus = AFSQueueWorkerRequest( pWorkItem);
7753 if( NT_SUCCESS( ntStatus))
7756 *pliAuthId = pWorkItem->Specific.GetAuthId.AuthId;
7758 ntStatus = pWorkItem->Status;
7760 AFSDbgTrace(( AFS_SUBSYSTEM_WORKER_PROCESSING,
7761 AFS_TRACE_LEVEL_VERBOSE,
7762 "AFSGetAuthenticationId Request complete Status %08lX\n",
7767 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
7768 AFS_TRACE_LEVEL_ERROR,
7769 "AFSGetAuthenticationId Failed to queue request Status %08lX\n",
7773 if( pWorkItem != NULL)
7776 AFSExFreePoolWithTag( pWorkItem,
7780 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
7785 "EXCEPTION - AFSGetAuthenticationId\n"));
7787 AFSDumpTraceFilesFnc();
7794 AFSPerformGetAuthId( IN PEPROCESS peProcess,
7795 IN PETHREAD peThread,
7796 OUT LARGE_INTEGER *outAuthId)
7799 LARGE_INTEGER liAuthId = {0,0};
7800 NTSTATUS ntStatus = STATUS_SUCCESS;
7801 PACCESS_TOKEN hToken = NULL;
7802 PTOKEN_STATISTICS pTokenInfo = NULL;
7803 BOOLEAN bCopyOnOpen = FALSE;
7804 BOOLEAN bEffectiveOnly = FALSE;
7805 BOOLEAN bPrimaryToken = FALSE;
7806 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7811 hToken = PsReferenceImpersonationToken( peThread,
7814 &stImpersonationLevel);
7819 hToken = PsReferencePrimaryToken( peProcess);
7824 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7825 AFS_TRACE_LEVEL_ERROR,
7826 "AFSPerformGetAuthId Failed to retrieve impersonation or primary token\n"));
7828 try_return( ntStatus);
7831 bPrimaryToken = TRUE;
7834 ntStatus = SeQueryInformationToken( hToken,
7836 (PVOID *)&pTokenInfo);
7838 if( !NT_SUCCESS( ntStatus))
7841 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7842 AFS_TRACE_LEVEL_ERROR,
7843 "AFSPerformGetAuthId Failed to retrieve information Status %08lX\n",
7846 try_return( ntStatus);
7849 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7850 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7852 AFSDbgTrace(( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7853 AFS_TRACE_LEVEL_VERBOSE,
7854 "AFSPerformGetAuthId Successfully retrieved authentication ID %I64X\n",
7855 liAuthId.QuadPart));
7865 PsDereferenceImpersonationToken( hToken);
7870 PsDereferencePrimaryToken( hToken);
7874 if( pTokenInfo != NULL)
7877 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
7880 *outAuthId = liAuthId;
7887 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7891 UNREFERENCED_PARAMETER(Fcb);
7892 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7894 Fcb->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7897 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7899 Fcb->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7902 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7904 Fcb->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7907 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7909 Fcb->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7912 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7914 Fcb->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7921 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7924 BOOLEAN bIsValid = TRUE;
7926 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7928 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7930 while( pCurrentDirEntry != NULL)
7933 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7937 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7942 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7943 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7946 if( pDirEntry == NULL)
7953 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7956 if( ulCount != (ULONG) ObjectInfo->Specific.Directory.DirectoryNodeCount)
7959 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7961 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7963 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7972 AFSReferenceCacheFileObject()
7975 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7976 FILE_OBJECT *pCacheFileObject = NULL;
7978 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7981 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7983 if( pCacheFileObject != NULL)
7985 ObReferenceObject( pCacheFileObject);
7988 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7990 return pCacheFileObject;
7994 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7997 ASSERT( CacheFileObject != NULL);
7999 ObDereferenceObject( CacheFileObject);
8005 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
8008 NTSTATUS ntStatus = STATUS_SUCCESS;
8009 AFSDeviceExt *pControlDevExt = NULL;
8010 ULONG ulTimeIncrement = 0;
8016 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
8018 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
8020 AFSServerName = LibraryInit->AFSServerName;
8022 AFSMountRootName = LibraryInit->AFSMountRootName;
8024 AFSDebugFlags = LibraryInit->AFSDebugFlags;
8027 // Callbacks in the framework
8030 AFSProcessRequest = LibraryInit->AFSProcessRequest;
8032 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
8034 AFSDebugTraceFnc = AFSDbgLogMsg;
8036 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
8038 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
8040 AFSExFreePoolWithTag = LibraryInit->AFSExFreePoolWithTag;
8042 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
8044 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
8046 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
8048 if( LibraryInit->AFSCacheBaseAddress != NULL)
8051 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
8053 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
8055 AFSLibCacheLength = LibraryInit->AFSCacheLength;
8059 // Initialize some flush parameters
8062 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
8064 ulTimeIncrement = KeQueryTimeIncrement();
8066 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
8067 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_SERVER_PURGE_DELAY;
8068 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
8069 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_SERVER_FLUSH_DELAY / (ULONGLONG)ulTimeIncrement);
8070 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
8073 // Initialize the global root entry
8076 ntStatus = AFSInitVolume( NULL,
8077 &LibraryInit->GlobalRootFid,
8078 AFS_VOLUME_REFERENCE_GLOBAL_ROOT,
8081 if( !NT_SUCCESS( ntStatus))
8084 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8085 AFS_TRACE_LEVEL_ERROR,
8086 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
8089 try_return( ntStatus);
8092 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
8095 if( !NT_SUCCESS( ntStatus))
8098 AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
8099 AFS_TRACE_LEVEL_ERROR,
8100 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
8103 lCount = AFSVolumeDecrement( AFSGlobalRoot,
8104 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
8106 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8107 AFS_TRACE_LEVEL_VERBOSE,
8108 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8112 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8114 try_return( ntStatus);
8118 // Update the node type code to AFS_ROOT_ALL
8121 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
8123 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
8126 // Invalidate all known volumes since contact with the service and therefore
8127 // the file server was lost.
8130 AFSInvalidateAllVolumes();
8133 // Drop the locks acquired above
8136 AFSInitVolumeWorker( AFSGlobalRoot);
8138 lCount = AFSVolumeDecrement( AFSGlobalRoot,
8139 AFS_VOLUME_REFERENCE_GLOBAL_ROOT);
8141 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8142 AFS_TRACE_LEVEL_VERBOSE,
8143 "AFSInitializeLibrary Decrement count on volume %p Cnt %d\n",
8147 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
8149 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
8163 NTSTATUS ntStatus = STATUS_SUCCESS;
8164 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
8170 if( AFSGlobalDotDirEntry != NULL)
8173 lCount = AFSObjectInfoDecrement( AFSGlobalDotDirEntry->ObjectInformation,
8174 AFS_OBJECT_REFERENCE_GLOBAL);
8176 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8177 AFS_TRACE_LEVEL_VERBOSE,
8178 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
8179 AFSGlobalDotDirEntry->ObjectInformation,
8185 AFSDeleteObjectInfo( &AFSGlobalDotDirEntry->ObjectInformation);
8188 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
8190 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry->NonPaged,
8191 AFS_DIR_ENTRY_NP_TAG);
8193 AFSLibExFreePoolWithTag( AFSGlobalDotDirEntry,
8196 AFSGlobalDotDirEntry = NULL;
8199 if( AFSGlobalDotDotDirEntry != NULL)
8202 lCount = AFSObjectInfoDecrement( AFSGlobalDotDotDirEntry->ObjectInformation,
8203 AFS_OBJECT_REFERENCE_GLOBAL);
8205 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8206 AFS_TRACE_LEVEL_VERBOSE,
8207 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
8208 AFSGlobalDotDotDirEntry->ObjectInformation,
8214 AFSDeleteObjectInfo( &AFSGlobalDotDotDirEntry->ObjectInformation);
8217 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
8219 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry->NonPaged,
8220 AFS_DIR_ENTRY_NP_TAG);
8222 AFSLibExFreePoolWithTag( AFSGlobalDotDotDirEntry,
8225 AFSGlobalDotDotDirEntry = NULL;
8228 if( AFSSpecialShareNames != NULL)
8231 pDirNode = AFSSpecialShareNames;
8233 while( pDirNode != NULL)
8236 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
8238 lCount = AFSObjectInfoDecrement( pDirNode->ObjectInformation,
8239 AFS_OBJECT_REFERENCE_GLOBAL);
8241 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8242 AFS_TRACE_LEVEL_VERBOSE,
8243 "AFSCloseLibrary Decrement count on parent object %p Cnt %d\n",
8244 pDirNode->ObjectInformation,
8250 AFSDeleteObjectInfo( &pDirNode->ObjectInformation);
8253 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
8255 AFSLibExFreePoolWithTag( pDirNode->NonPaged,
8256 AFS_DIR_ENTRY_NP_TAG);
8258 AFSLibExFreePoolWithTag( pDirNode,
8261 pDirNode = pLastDirNode;
8264 AFSSpecialShareNames = NULL;
8272 AFSDefaultLogMsg( IN ULONG Subsystem,
8278 UNREFERENCED_PARAMETER(Subsystem);
8279 UNREFERENCED_PARAMETER(Level);
8280 NTSTATUS ntStatus = STATUS_SUCCESS;
8282 char chDebugBuffer[ 256];
8287 va_start( va_args, Format);
8289 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
8294 if( NT_SUCCESS( ntStatus))
8296 DbgPrint( chDebugBuffer);
8306 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
8307 IN ULONG InputBufferLength,
8308 IN AFSStatusInfoCB *StatusInfo,
8309 OUT ULONG *ReturnLength)
8312 NTSTATUS ntStatus = STATUS_SUCCESS;
8313 AFSVolumeCB *pVolumeCB = NULL;
8314 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8315 AFSVolumeCB *pNewVolumeCB = NULL;
8316 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8317 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
8318 AFSObjectInfoCB *pObjectInfo = NULL;
8319 ULONGLONG ullIndex = 0;
8320 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
8321 AFSNameArrayHdr *pNameArray = NULL;
8322 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
8323 AFSDirectoryCB *pNewParentDirEntry = NULL;
8330 // If we are given a FID then look up the entry by that, otherwise
8334 if( GetStatusInfo->FileID.Cell != 0 &&
8335 GetStatusInfo->FileID.Volume != 0 &&
8336 GetStatusInfo->FileID.Vnode != 0 &&
8337 GetStatusInfo->FileID.Unique != 0)
8340 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
8343 // Locate the volume node
8346 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
8348 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
8350 (AFSBTreeEntry **)&pVolumeCB);
8352 if( pVolumeCB != NULL)
8355 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8357 lCount = AFSVolumeIncrement( pVolumeCB,
8358 VolumeReferenceReason);
8360 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8361 AFS_TRACE_LEVEL_VERBOSE,
8362 "AFSGetObjectStatus Increment count on volume %p Reason %u Cnt %d\n",
8364 VolumeReferenceReason,
8368 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
8370 if( !NT_SUCCESS( ntStatus) ||
8373 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8376 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
8379 pObjectInfo = &pVolumeCB->ObjectInformation;
8381 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8384 lCount = AFSObjectInfoIncrement( pObjectInfo,
8385 AFS_OBJECT_REFERENCE_STATUS);
8387 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8388 AFS_TRACE_LEVEL_VERBOSE,
8389 "AFSGetObjectStatus Increment1 count on object %p Cnt %d\n",
8393 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8398 AFSAcquireExcl( pVolumeCB->ObjectInfoTree.TreeLock,
8401 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
8403 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
8405 (AFSBTreeEntry **)&pObjectInfo);
8407 if( pObjectInfo != NULL)
8411 // Reference the node so it won't be torn down
8414 lCount = AFSObjectInfoIncrement( pObjectInfo,
8415 AFS_OBJECT_REFERENCE_STATUS);
8417 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8418 AFS_TRACE_LEVEL_VERBOSE,
8419 "AFSGetObjectStatus Increment2 count on object %p Cnt %d\n",
8423 KeQueryTickCount( &pObjectInfo->LastAccessCount);
8426 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8428 if( !NT_SUCCESS( ntStatus) ||
8429 pObjectInfo == NULL)
8431 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8438 if( GetStatusInfo->FileNameLength == 0 ||
8439 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
8441 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8444 uniFullPathName.Length = GetStatusInfo->FileNameLength;
8445 uniFullPathName.MaximumLength = uniFullPathName.Length;
8447 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
8450 // This name should begin with the \afs server so parse it off and check it
8453 FsRtlDissectName( uniFullPathName,
8457 if( RtlCompareUnicodeString( &uniComponentName,
8461 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8462 AFS_TRACE_LEVEL_ERROR,
8463 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
8466 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
8469 uniFullPathName = uniRemainingPath;
8471 uniParsedName = uniFullPathName;
8477 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
8480 if( pNameArray == NULL)
8482 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8485 pVolumeCB = AFSGlobalRoot;
8487 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
8490 // Increment the ref count on the volume and dir entry for correct processing below
8493 VolumeReferenceReason = AFS_VOLUME_REFERENCE_GET_OBJECT;
8495 lCount = AFSVolumeIncrement( pVolumeCB,
8496 VolumeReferenceReason);
8498 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8499 AFS_TRACE_LEVEL_VERBOSE,
8500 "AFSGetObjectStatus Increment2 count on volume %p Reason %u Cnt %d\n",
8502 VolumeReferenceReason,
8505 lCount = InterlockedIncrement( &pParentDirEntry->DirOpenReferenceCount);
8507 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8508 AFS_TRACE_LEVEL_VERBOSE,
8509 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8510 &pParentDirEntry->NameInformation.FileName,
8515 ntStatus = AFSLocateNameEntry( NULL,
8520 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
8521 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
8525 &NewVolumeReferenceReason,
8526 &pNewParentDirEntry,
8531 if ( pNewVolumeCB != NULL)
8535 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
8536 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
8537 // the reference on pVolumeCB that was held prior to the call.
8538 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
8539 // will be released second.
8542 lCount = AFSVolumeDecrement( pVolumeCB,
8543 VolumeReferenceReason);
8545 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8546 AFS_TRACE_LEVEL_VERBOSE,
8547 "AFSGetObjectStatus Decrement count on volume %p Reason %u Cnt %d\n",
8549 VolumeReferenceReason,
8552 pVolumeCB = pNewVolumeCB;
8554 pNewVolumeCB = NULL;
8556 VolumeReferenceReason = NewVolumeReferenceReason;
8558 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
8562 // AFSLocateNameEntry does not alter the reference count of
8563 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
8564 // a reference held.
8567 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8569 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8570 AFS_TRACE_LEVEL_VERBOSE,
8571 "AFSGetObjectStatus DecrementX count on %wZ DE %p Cnt %d\n",
8572 &pParentDirEntry->NameInformation.FileName,
8576 pParentDirEntry = pNewParentDirEntry;
8578 pNewParentDirEntry = NULL;
8580 if( !NT_SUCCESS( ntStatus) ||
8581 ntStatus == STATUS_REPARSE)
8586 try_return( ntStatus);
8589 pObjectInfo = pDirectoryEntry->ObjectInformation;
8591 AFSAcquireExcl( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
8594 lCount = AFSObjectInfoIncrement( pObjectInfo,
8595 AFS_OBJECT_REFERENCE_STATUS);
8597 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8598 AFS_TRACE_LEVEL_VERBOSE,
8599 "AFSGetObjectStatus Increment3 count on object %p Cnt %d\n",
8603 AFSReleaseResource( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
8607 // At this point we have an object info block, return the information
8610 StatusInfo->FileId = pObjectInfo->FileId;
8612 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
8614 StatusInfo->Expiration = pObjectInfo->Expiration;
8616 StatusInfo->DataVersion = pObjectInfo->DataVersion;
8618 StatusInfo->FileType = pObjectInfo->FileType;
8620 StatusInfo->ObjectFlags = pObjectInfo->Flags;
8622 StatusInfo->CreationTime = pObjectInfo->CreationTime;
8624 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
8626 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
8628 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
8630 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
8632 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
8634 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
8636 StatusInfo->EaSize = pObjectInfo->EaSize;
8638 StatusInfo->Links = pObjectInfo->Links;
8641 // Return the information length
8644 *ReturnLength = sizeof( AFSStatusInfoCB);
8648 if( pDirectoryEntry != NULL)
8651 lCount = InterlockedDecrement( &pDirectoryEntry->DirOpenReferenceCount);
8653 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8654 AFS_TRACE_LEVEL_VERBOSE,
8655 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
8656 &pDirectoryEntry->NameInformation.FileName,
8661 ASSERT( lCount >= 0);
8664 if ( pParentDirEntry != NULL)
8667 lCount = InterlockedDecrement( &pParentDirEntry->DirOpenReferenceCount);
8669 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8670 AFS_TRACE_LEVEL_VERBOSE,
8671 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
8672 &pParentDirEntry->NameInformation.FileName,
8677 ASSERT( lCount >= 0);
8680 if( pVolumeCB != NULL)
8683 if( pObjectInfo != NULL)
8686 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
8689 lCount = AFSObjectInfoDecrement( pObjectInfo,
8690 AFS_OBJECT_REFERENCE_STATUS);
8692 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
8693 AFS_TRACE_LEVEL_VERBOSE,
8694 "AFSGetObjectStatus Decrement count on object %p Cnt %d\n",
8698 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
8701 lCount = AFSVolumeDecrement( pVolumeCB,
8702 VolumeReferenceReason);
8704 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
8705 AFS_TRACE_LEVEL_VERBOSE,
8706 "AFSGetObjectStatus Decrement4 count on volume %p Reason %u Cnt %d\n",
8708 VolumeReferenceReason,
8712 if( pNameArray != NULL)
8715 AFSFreeNameArray( pNameArray);
8723 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
8724 IN UNICODE_STRING *ComponentName)
8727 NTSTATUS ntStatus = STATUS_SUCCESS;
8728 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
8729 AFSDirectoryCB *pDirEntry = NULL;
8737 // Search for the entry in the parent
8740 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8741 AFS_TRACE_LEVEL_VERBOSE_2,
8742 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
8745 ulCRC = AFSGenerateCRC( ComponentName,
8748 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
8751 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
8755 if( pDirEntry == NULL)
8759 // Missed so perform a case insensitive lookup
8762 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8763 AFS_TRACE_LEVEL_VERBOSE_2,
8764 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
8767 ulCRC = AFSGenerateCRC( ComponentName,
8770 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
8774 if( pDirEntry == NULL)
8778 // OK, if this component is a valid short name then try
8779 // a lookup in the short name tree
8782 if( !BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_DISABLE_SHORTNAMES) &&
8783 RtlIsNameLegalDOS8Dot3( ComponentName,
8788 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8789 AFS_TRACE_LEVEL_VERBOSE_2,
8790 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8793 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8802 // Here we have a match on the case insensitive lookup for the name. If there
8803 // Is more than one link entry for this node then fail the lookup request
8806 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD) ||
8807 pDirEntry->CaseInsensitiveList.fLink != NULL)
8810 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8812 try_return(ntStatus = STATUS_OBJECT_NAME_COLLISION);
8817 if( pDirEntry != NULL)
8819 lCount = InterlockedIncrement( &pDirEntry->DirOpenReferenceCount);
8821 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8822 AFS_TRACE_LEVEL_VERBOSE,
8823 "AFSCheckSymlinkAccess Increment count on %wZ DE %p Ccb %p Cnt %d\n",
8824 &pDirEntry->NameInformation.FileName,
8829 ASSERT( lCount >= 0);
8832 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8834 if( pDirEntry == NULL)
8837 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8838 AFS_TRACE_LEVEL_VERBOSE_2,
8839 "AFSCheckSymlinkAccess Failed to locate entry %wZ ntStatus %08X\n",
8841 STATUS_OBJECT_NAME_NOT_FOUND));
8843 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8847 // We have the symlink object but previously failed to process it so return access
8851 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
8852 AFS_TRACE_LEVEL_VERBOSE_2,
8853 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8856 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8858 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
8860 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
8861 AFS_TRACE_LEVEL_VERBOSE,
8862 "AFSCheckSymlinkAccess Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
8863 &pDirEntry->NameInformation.FileName,
8868 ASSERT( lCount >= 0);
8879 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8880 OUT UNICODE_STRING *ComponentName)
8883 NTSTATUS ntStatus = STATUS_SUCCESS;
8884 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8886 uniFullPathName = *FullPathName;
8891 FsRtlDissectName( uniFullPathName,
8895 if( uniRemainingPath.Length == 0)
8900 uniFullPathName = uniRemainingPath;
8903 if( uniComponentName.Length > 0)
8905 *ComponentName = uniComponentName;
8912 AFSDumpTraceFiles_Default()
8918 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8921 BOOLEAN bIsValidName = TRUE;
8927 while( usIndex < FileName->Length/sizeof( WCHAR))
8930 if( FileName->Buffer[ usIndex] == L':' ||
8931 FileName->Buffer[ usIndex] == L'*' ||
8932 FileName->Buffer[ usIndex] == L'?' ||
8933 FileName->Buffer[ usIndex] == L'"' ||
8934 FileName->Buffer[ usIndex] == L'<' ||
8935 FileName->Buffer[ usIndex] == L'>')
8937 bIsValidName = FALSE;
8945 return bIsValidName;
8949 AFSCreateDefaultSecurityDescriptor()
8952 NTSTATUS ntStatus = STATUS_SUCCESS;
8954 ULONG ulSACLSize = 0;
8955 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8956 ULONG ulACESize = 0;
8957 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8958 ULONG ulSDLength = 0;
8959 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8960 PSID pWorldSID = NULL;
8961 ULONG *pulSubAuthority = NULL;
8962 ULONG ulWorldSIDLEngth = 0;
8967 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8969 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8971 AFS_GENERIC_MEMORY_29_TAG);
8973 if( pWorldSID == NULL)
8975 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8977 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8980 RtlZeroMemory( pWorldSID,
8983 RtlInitializeSid( pWorldSID,
8984 &SeWorldSidAuthority,
8987 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8988 *pulSubAuthority = SECURITY_WORLD_RID;
8990 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8993 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8998 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
9000 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
9002 AFS_GENERIC_MEMORY_29_TAG);
9007 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
9009 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9012 RtlZeroMemory( pACE,
9015 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
9016 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
9017 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
9018 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
9020 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
9022 SeExports->SeLowMandatorySid);
9024 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
9025 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
9027 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
9029 AFS_GENERIC_MEMORY_29_TAG);
9034 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
9036 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9039 ntStatus = RtlCreateAcl( pSACL,
9043 if( !NT_SUCCESS( ntStatus))
9046 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
9049 try_return( ntStatus);
9052 ntStatus = RtlAddAce( pSACL,
9056 pACE->Header.AceSize);
9058 if( !NT_SUCCESS( ntStatus))
9061 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
9064 try_return( ntStatus);
9068 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
9069 sizeof( SECURITY_DESCRIPTOR),
9070 AFS_GENERIC_MEMORY_27_TAG);
9072 if( pSecurityDescr == NULL)
9075 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9077 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9080 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
9081 SECURITY_DESCRIPTOR_REVISION);
9083 if( !NT_SUCCESS( ntStatus))
9086 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
9089 try_return( ntStatus);
9092 if( AFSRtlSetSaclSecurityDescriptor != NULL)
9094 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
9099 if( !NT_SUCCESS( ntStatus))
9102 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
9105 try_return( ntStatus);
9110 // Add in the group and owner to the SD
9113 if( AFSRtlSetGroupSecurityDescriptor != NULL)
9115 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
9119 if( !NT_SUCCESS( ntStatus))
9122 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
9125 try_return( ntStatus);
9129 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
9133 if( !NT_SUCCESS( ntStatus))
9136 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
9139 try_return( ntStatus);
9142 if( !RtlValidSecurityDescriptor( pSecurityDescr))
9145 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
9147 try_return( ntStatus = STATUS_INVALID_PARAMETER);
9150 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)AFSLibExAllocatePoolWithTag( NonPagedPool,
9152 AFS_GENERIC_MEMORY_27_TAG);
9154 if( pRelativeSecurityDescr == NULL)
9157 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
9159 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
9162 ulSDLength = PAGE_SIZE;
9164 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
9165 pRelativeSecurityDescr,
9168 if( !NT_SUCCESS( ntStatus))
9171 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
9174 try_return( ntStatus);
9177 AFSDefaultSD = pRelativeSecurityDescr;
9181 if( !NT_SUCCESS( ntStatus))
9184 if( pRelativeSecurityDescr != NULL)
9187 AFSLibExFreePoolWithTag( pRelativeSecurityDescr,
9188 AFS_GENERIC_MEMORY_27_TAG);
9192 if( pSecurityDescr != NULL)
9195 AFSLibExFreePoolWithTag( pSecurityDescr,
9196 AFS_GENERIC_MEMORY_27_TAG);
9202 AFSLibExFreePoolWithTag( pSACL,
9203 AFS_GENERIC_MEMORY_29_TAG);
9209 AFSLibExFreePoolWithTag( pACE,
9210 AFS_GENERIC_MEMORY_29_TAG);
9213 if( pWorldSID != NULL)
9216 AFSLibExFreePoolWithTag( pWorldSID,
9217 AFS_GENERIC_MEMORY_29_TAG);
9225 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
9226 OUT UNICODE_STRING *ParentPath)
9229 *ParentPath = *FullFileName;
9232 // If the final character is a \, jump over it
9235 if( ParentPath->Length >= sizeof( WCHAR)
9236 && ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
9238 ParentPath->Length -= sizeof( WCHAR);
9241 while( ParentPath->Length >= sizeof( WCHAR)
9242 && ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
9244 ParentPath->Length -= sizeof( WCHAR);
9248 // And the separator
9251 if ( ParentPath->Length >= sizeof( WCHAR))
9253 ParentPath->Length -= sizeof( WCHAR);
9260 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
9261 IN AFSObjectInfoCB *ObjectInfo,
9262 IN BOOLEAN WriteAccess,
9263 OUT GUID *AuthGroup)
9266 NTSTATUS ntStatus = STATUS_SUCCESS;
9267 GUID stAuthGroup, stZeroAuthGroup;
9268 BOOLEAN bFoundAuthGroup = FALSE;
9269 AFSCcb *pCcb = NULL;
9275 RtlZeroMemory( &stAuthGroup,
9278 RtlZeroMemory( &stZeroAuthGroup,
9284 if( ObjectInfo != NULL &&
9285 ObjectInfo->Fcb != NULL)
9287 pFcb = ObjectInfo->Fcb;
9294 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
9297 pCcb = Fcb->CcbListHead;
9299 while( pCcb != NULL)
9303 pCcb->GrantedAccess & FILE_WRITE_DATA)
9305 RtlCopyMemory( &stAuthGroup,
9309 bFoundAuthGroup = TRUE;
9313 else if( pCcb->GrantedAccess & FILE_READ_DATA)
9316 // At least get the read-only access
9319 RtlCopyMemory( &stAuthGroup,
9323 bFoundAuthGroup = TRUE;
9326 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
9329 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
9332 if( !bFoundAuthGroup)
9335 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
9336 (ULONGLONG)PsGetCurrentThreadId(),
9339 if( RtlCompareMemory( &stZeroAuthGroup,
9341 sizeof( GUID)) == sizeof( GUID))
9344 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
9346 try_return( ntStatus = STATUS_ACCESS_DENIED);
9350 RtlCopyMemory( AuthGroup,
9363 AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
9364 IN ULONG InvalidateReason)
9367 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
9368 NTSTATUS ntStatus = STATUS_SUCCESS;
9374 switch( InvalidateReason)
9377 case AFS_INVALIDATE_DELETED:
9380 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
9381 AFS_TRACE_LEVEL_VERBOSE,
9382 "AFSPerformObjectInvalidation on node type %d for FID %08lX-%08lX-%08lX-%08lX Reason DELETED\n",
9383 ObjectInfo->FileType,
9384 ObjectInfo->FileId.Cell,
9385 ObjectInfo->FileId.Volume,
9386 ObjectInfo->FileId.Vnode,
9387 ObjectInfo->FileId.Unique));
9389 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9390 ObjectInfo->Fcb != NULL)
9393 if( !BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
9396 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9399 ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_FILE_DELETED;
9401 KeSetEvent( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestComplete,
9406 // Clear out the extents
9407 // And get rid of them (note this involves waiting
9408 // for any writes or reads to the cache to complete)
9411 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9414 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource);
9418 ObjectInfo->Links = 0;
9423 case AFS_INVALIDATE_DATA_VERSION:
9426 if( ObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
9427 ObjectInfo->Fcb != NULL)
9430 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
9431 AFS_TRACE_LEVEL_VERBOSE,
9432 "AFSPerformObjectInvalidation on node type %d for FID %08lX-%08lX-%08lX-%08lX Reason DATA_VERSION FCB %0p\n",
9433 ObjectInfo->FileType,
9434 ObjectInfo->FileId.Cell,
9435 ObjectInfo->FileId.Volume,
9436 ObjectInfo->FileId.Vnode,
9437 ObjectInfo->FileId.Unique,
9440 if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_DIRECT_SERVICE_IO))
9443 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9444 AFS_TRACE_LEVEL_VERBOSE,
9445 "AFSPerformObjectInvalidate Acquiring Fcb lock %p EXCL %08lX\n",
9446 &ObjectInfo->Fcb->NPFcb->Resource,
9447 PsGetCurrentThread()));
9449 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9452 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9453 AFS_TRACE_LEVEL_VERBOSE,
9454 "AFSPerformObjectInvalidation DirectIO Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9455 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9456 PsGetCurrentThread()));
9458 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9464 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9465 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9471 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9472 AFS_TRACE_LEVEL_WARNING,
9473 "AFSPerformObjectInvalidation DirectIO CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9474 ObjectInfo->FileId.Cell,
9475 ObjectInfo->FileId.Volume,
9476 ObjectInfo->FileId.Vnode,
9477 ObjectInfo->FileId.Unique));
9479 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9481 SetFlag( ObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
9484 __except( EXCEPTION_EXECUTE_HANDLER)
9487 ntStatus = GetExceptionCode();
9491 "EXCEPTION - AFSPerformObjectInvalidation DirectIO FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9492 ObjectInfo->FileId.Cell,
9493 ObjectInfo->FileId.Volume,
9494 ObjectInfo->FileId.Vnode,
9495 ObjectInfo->FileId.Unique,
9498 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9500 SetFlag( ObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
9503 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9504 AFS_TRACE_LEVEL_VERBOSE,
9505 "AFSPerformObjectInvalidation DirectIO Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9506 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9507 PsGetCurrentThread()));
9509 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9511 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9512 AFS_TRACE_LEVEL_VERBOSE,
9513 "AFSPerformObjectInvalidation DirectIO Releasing Fcb lock %p EXCL %08lX\n",
9514 &ObjectInfo->Fcb->NPFcb->Resource,
9515 PsGetCurrentThread()));
9517 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9523 ULONG ulProcessCount = 0;
9525 LARGE_INTEGER liCurrentOffset = {0,0};
9526 LARGE_INTEGER liFlushLength = {0,0};
9527 ULONG ulFlushLength = 0;
9528 BOOLEAN bLocked = FALSE;
9529 BOOLEAN bExtentsLocked = FALSE;
9530 BOOLEAN bCleanExtents = FALSE;
9532 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9533 AFS_TRACE_LEVEL_VERBOSE,
9534 "AFSPerformObjectInvalidate Acquiring Fcb lock %p EXCL %08lX\n",
9535 &ObjectInfo->Fcb->NPFcb->Resource,
9536 PsGetCurrentThread()));
9538 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Resource,
9543 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
9544 AFS_TRACE_LEVEL_VERBOSE,
9545 "AFSPerformObjectInvalidate Acquiring Fcb extents lock %p SHARED %08lX\n",
9546 &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9547 PsGetCurrentThread()));
9549 AFSAcquireShared( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9552 bExtentsLocked = TRUE;
9555 // There are several possibilities here:
9557 // 0. If there are no extents or all of the extents are dirty, do nothing.
9559 // 1. There could be nothing dirty and an open reference count of zero
9560 // in which case we can just tear down all of the extents without
9561 // holding any resources.
9563 // 2. There could be nothing dirty and a non-zero open reference count
9564 // in which case we can issue a CcPurge against the entire file
9565 // while holding just the Fcb Resource.
9567 // 3. There can be dirty extents in which case we need to identify
9568 // the non-dirty ranges and then perform a CcPurge on just the
9569 // non-dirty ranges while holding just the Fcb Resource.
9572 if ( ObjectInfo->Fcb->Specific.File.ExtentCount != ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount)
9575 if ( ObjectInfo->Fcb->Specific.File.ExtentsDirtyCount == 0)
9578 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9580 bExtentsLocked = FALSE;
9582 if ( ObjectInfo->Fcb->OpenReferenceCount == 0)
9585 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9589 AFSTearDownFcbExtents( ObjectInfo->Fcb,
9595 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9596 AFS_TRACE_LEVEL_VERBOSE,
9597 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9598 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9599 PsGetCurrentThread()));
9601 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9607 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9608 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9614 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9615 AFS_TRACE_LEVEL_WARNING,
9616 "AFSPerformObjectInvalidation CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9617 ObjectInfo->FileId.Cell,
9618 ObjectInfo->FileId.Volume,
9619 ObjectInfo->FileId.Vnode,
9620 ObjectInfo->FileId.Unique));
9622 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9624 SetFlag( ObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
9629 bCleanExtents = TRUE;
9632 __except( EXCEPTION_EXECUTE_HANDLER)
9635 ntStatus = GetExceptionCode();
9639 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
9640 ObjectInfo->FileId.Cell,
9641 ObjectInfo->FileId.Volume,
9642 ObjectInfo->FileId.Vnode,
9643 ObjectInfo->FileId.Unique,
9646 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9648 SetFlag( ObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
9651 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9652 AFS_TRACE_LEVEL_VERBOSE,
9653 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9654 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9655 PsGetCurrentThread()));
9657 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9659 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9667 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9669 bExtentsLocked = FALSE;
9671 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9672 AFS_TRACE_LEVEL_VERBOSE,
9673 "AFSPerformObjectInvalidation Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
9674 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9675 PsGetCurrentThread()));
9677 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9681 // Must build a list of non-dirty ranges from the beginning of the file
9682 // to the end. There can be at most (Fcb->Specific.File.ExtentsDirtyCount + 1)
9683 // ranges. In all but the most extreme random data write scenario there will
9684 // be significantly fewer.
9686 // For each range we need offset and size.
9689 AFSByteRange * ByteRangeList = NULL;
9690 ULONG ulByteRangeCount = 0;
9692 BOOLEAN bPurgeOnClose = FALSE;
9697 ulByteRangeCount = AFSConstructCleanByteRangeList( ObjectInfo->Fcb,
9700 if ( ByteRangeList != NULL ||
9701 ulByteRangeCount == 0)
9704 for ( ulIndex = 0; ulIndex < ulByteRangeCount; ulIndex++)
9711 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
9716 if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
9717 !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9718 &ByteRangeList[ulIndex].FileOffset,
9723 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9724 AFS_TRACE_LEVEL_WARNING,
9725 "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9726 ObjectInfo->FileId.Cell,
9727 ObjectInfo->FileId.Volume,
9728 ObjectInfo->FileId.Vnode,
9729 ObjectInfo->FileId.Unique));
9731 bPurgeOnClose = TRUE;
9736 bCleanExtents = TRUE;
9739 __except( EXCEPTION_EXECUTE_HANDLER)
9742 ntStatus = GetExceptionCode();
9746 "EXCEPTION - AFSPerformObjectInvalidation CcPurgeCacheSection (1) FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9747 ObjectInfo->FileId.Cell,
9748 ObjectInfo->FileId.Volume,
9749 ObjectInfo->FileId.Vnode,
9750 ObjectInfo->FileId.Unique,
9754 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
9756 ByteRangeList[ulIndex].FileOffset.QuadPart += ulSize;
9758 } while ( ByteRangeList[ulIndex].Length.QuadPart > 0);
9765 // We couldn't allocate the memory to build the purge list
9766 // so just walk the extent list while holding the ExtentsList Resource.
9767 // This could deadlock but we do not have much choice.
9770 AFSAcquireExcl( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource,
9772 bExtentsLocked = TRUE;
9774 le = ObjectInfo->Fcb->Specific.File.ExtentsLists[AFS_EXTENTS_LIST].Flink;
9778 ulCount = (ULONG)ObjectInfo->Fcb->Specific.File.ExtentCount;
9782 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9784 while( ulProcessCount < ulCount)
9786 pEntry = ExtentFor( le, AFS_EXTENTS_LIST );
9788 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
9792 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9793 &pEntry->FileOffset,
9798 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9799 AFS_TRACE_LEVEL_WARNING,
9800 "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9801 ObjectInfo->FileId.Cell,
9802 ObjectInfo->FileId.Volume,
9803 ObjectInfo->FileId.Vnode,
9804 ObjectInfo->FileId.Unique));
9806 bPurgeOnClose = TRUE;
9811 bCleanExtents = TRUE;
9814 __except( EXCEPTION_EXECUTE_HANDLER)
9817 ntStatus = GetExceptionCode();
9821 "EXCEPTION - AFSPerformObjectInvalidation CcPurgeCacheSection (2) FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9822 ObjectInfo->FileId.Cell,
9823 ObjectInfo->FileId.Volume,
9824 ObjectInfo->FileId.Vnode,
9825 ObjectInfo->FileId.Unique,
9830 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
9833 liFlushLength.QuadPart = pEntry->FileOffset.QuadPart - liCurrentOffset.QuadPart;
9835 while( liFlushLength.QuadPart > 0)
9838 if( liFlushLength.QuadPart > 512 * 1024000)
9840 ulFlushLength = 512 * 1024000;
9844 ulFlushLength = liFlushLength.LowPart;
9849 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9855 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9856 AFS_TRACE_LEVEL_WARNING,
9857 "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9858 ObjectInfo->FileId.Cell,
9859 ObjectInfo->FileId.Volume,
9860 ObjectInfo->FileId.Vnode,
9861 ObjectInfo->FileId.Unique));
9863 bPurgeOnClose = TRUE;
9868 bCleanExtents = TRUE;
9871 __except( EXCEPTION_EXECUTE_HANDLER)
9874 ntStatus = GetExceptionCode();
9878 "EXCEPTION - AFSPerformObjectInvalidation CcPurgeCacheSection (3) FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9879 ObjectInfo->FileId.Cell,
9880 ObjectInfo->FileId.Volume,
9881 ObjectInfo->FileId.Vnode,
9882 ObjectInfo->FileId.Unique,
9886 liFlushLength.QuadPart -= ulFlushLength;
9890 liCurrentOffset.QuadPart = pEntry->FileOffset.QuadPart + pEntry->Size;
9900 if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
9906 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
9907 AFS_TRACE_LEVEL_WARNING,
9908 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
9909 ObjectInfo->FileId.Cell,
9910 ObjectInfo->FileId.Volume,
9911 ObjectInfo->FileId.Vnode,
9912 ObjectInfo->FileId.Unique));
9914 bPurgeOnClose = TRUE;
9919 bCleanExtents = TRUE;
9922 __except( EXCEPTION_EXECUTE_HANDLER)
9925 ntStatus = GetExceptionCode();
9929 "EXCEPTION - AFSPerformObjectInvalidation CcPurgeCacheSection (4) FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9930 ObjectInfo->FileId.Cell,
9931 ObjectInfo->FileId.Volume,
9932 ObjectInfo->FileId.Vnode,
9933 ObjectInfo->FileId.Unique,
9941 SetFlag( ObjectInfo->Fcb->Flags, AFS_FCB_FLAG_PURGE_ON_CLOSE);
9945 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
9948 ntStatus = GetExceptionCode();
9952 "EXCEPTION - AFSPerformObjectInvalidation FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
9953 ObjectInfo->FileId.Cell,
9954 ObjectInfo->FileId.Volume,
9955 ObjectInfo->FileId.Vnode,
9956 ObjectInfo->FileId.Unique,
9960 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
9961 AFS_TRACE_LEVEL_VERBOSE,
9962 "AFSPerformObjectInvalidation Releasing Fcb SectionObject lock %p EXCL %08lX\n",
9963 &ObjectInfo->Fcb->NPFcb->SectionObjectResource,
9964 PsGetCurrentThread()));
9966 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->SectionObjectResource);
9968 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9974 if ( bExtentsLocked)
9977 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Specific.File.ExtentsResource );
9983 AFSReleaseResource( &ObjectInfo->Fcb->NPFcb->Resource);
9989 AFSReleaseCleanExtents( ObjectInfo->Fcb,
9994 else if ( ObjectInfo->FileType == AFS_FILE_TYPE_FILE)
9997 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
9998 AFS_TRACE_LEVEL_VERBOSE,
9999 "AFSPerformObjectInvalidation on node type %d for FID %08lX-%08lX-%08lX-%08lX Reason DATA_VERSION FCB NULL\n",
10000 ObjectInfo->FileType,
10001 ObjectInfo->FileId.Cell,
10002 ObjectInfo->FileId.Volume,
10003 ObjectInfo->FileId.Vnode,
10004 ObjectInfo->FileId.Unique));
10006 SetFlag( ObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
10014 // Destroy the reference passed in by the caller to AFSInvalidateObject
10015 // or AFSQueueInvalidateObject
10018 AFSAcquireShared( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
10021 lCount = AFSObjectInfoDecrement( ObjectInfo,
10022 AFS_OBJECT_REFERENCE_INVALIDATION);
10024 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
10025 AFS_TRACE_LEVEL_VERBOSE,
10026 "AFSPerformObjectInvalidation Decrement count on object %p Cnt %d\n",
10030 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
10037 AFSIgnoreReparsePointToFile( void)
10039 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
10040 BOOLEAN bIgnoreReparsePoint;
10044 bIgnoreReparsePoint = BooleanFlagOn( pDeviceExt->Specific.RDR.ReparsePointPolicy,
10045 AFS_REPARSE_POINT_TO_FILE_AS_FILE);
10048 return bIgnoreReparsePoint;
10052 AFSRetrieveTargetFileInfo( IN PUNICODE_STRING TargetName,
10053 OUT AFSFileInfoCB *FileInfo)
10056 NTSTATUS ntStatus = STATUS_SUCCESS;
10057 OBJECT_ATTRIBUTES stObjectAttribs;
10058 HANDLE hFile = NULL;
10059 IO_STATUS_BLOCK stIoStatus;
10060 FILE_NETWORK_OPEN_INFORMATION stFileInfo;
10065 InitializeObjectAttributes( &stObjectAttribs,
10067 OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
10071 ntStatus = ZwCreateFile( &hFile,
10072 FILE_READ_ATTRIBUTES,
10077 FILE_SHARE_READ | FILE_SHARE_WRITE,
10079 FILE_SYNCHRONOUS_IO_NONALERT,
10083 if( !NT_SUCCESS( ntStatus))
10086 try_return( ntStatus);
10089 ntStatus = ZwQueryInformationFile( hFile,
10092 sizeof( FILE_NETWORK_OPEN_INFORMATION),
10093 FileNetworkOpenInformation);
10095 if( !NT_SUCCESS( ntStatus))
10098 try_return( ntStatus);
10101 FileInfo->FileAttributes = stFileInfo.FileAttributes;
10103 FileInfo->AllocationSize = stFileInfo.AllocationSize;
10105 FileInfo->EndOfFile = stFileInfo.EndOfFile;
10107 FileInfo->CreationTime = stFileInfo.CreationTime;
10109 FileInfo->LastAccessTime = stFileInfo.LastAccessTime;
10111 FileInfo->LastWriteTime = stFileInfo.LastWriteTime;
10113 FileInfo->ChangeTime = stFileInfo.ChangeTime;
10127 AFSIsShareName( IN UNICODE_STRING *FileName)
10130 BOOLEAN bIsShareName = TRUE;
10131 USHORT usIndex = 1; // Skip the first \
10134 // A share name will be of the form \Share so only a single \ at the beginning
10137 while( usIndex < FileName->Length/sizeof( WCHAR))
10140 if( FileName->Buffer[ usIndex] == L'\\')
10142 bIsShareName = FALSE;
10149 return bIsShareName;