2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 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
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSGeneric.cpp
39 #include "AFSCommon.h"
42 // Function: AFSExceptionFilter
46 // This function is the exception handler
50 // A status is returned for the function
54 AFSExceptionFilter( IN ULONG Code,
55 IN PEXCEPTION_POINTERS ExceptPtrs)
58 PEXCEPTION_RECORD ExceptRec;
64 ExceptRec = ExceptPtrs->ExceptionRecord;
66 Context = ExceptPtrs->ContextRecord;
70 "AFSExceptionFilter (Library) - EXR %p CXR %p Code %08lX Address %p Routine %p\n",
73 ExceptRec->ExceptionCode,
74 ExceptRec->ExceptionAddress,
75 (void *)AFSExceptionFilter);
77 DbgPrint("**** Exception Caught in AFS Redirector Library ****\n");
79 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
80 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
82 DbgPrint("**** Exception Complete from AFS Redirector Library ****\n");
84 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
87 KeBugCheck( (ULONG)-2);
95 __except( EXCEPTION_EXECUTE_HANDLER)
101 return EXCEPTION_EXECUTE_HANDLER;
105 // Function: AFSLibExAllocatePoolWithTag()
107 // Purpose: Allocate Pool Memory. If BugCheck Exception flag
108 // is configured on, then bugcheck the system if
109 // a memory allocation fails. The routine should be
110 // used for all memory allocations that are to be freed
111 // when the library is unloaded. Memory allocations that
112 // are to survive library unload and reload should be
113 // performed using AFSExAllocatePoolWithTag() which is
114 // provided by the AFS Framework.
117 // POOL_TYPE PoolType - Paged or NonPaged
118 // SIZE_T NumberOfBytes - requested allocation size
119 // ULONG Tag - Pool Allocation Tag to be applied for tracking
122 // void * - the memory allocation
126 AFSLibExAllocatePoolWithTag( IN POOL_TYPE PoolType,
127 IN SIZE_T NumberOfBytes,
131 void *pBuffer = NULL;
133 pBuffer = ExAllocatePoolWithTag( PoolType,
140 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
143 KeBugCheck( (ULONG)-2);
150 "AFSLibExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
154 PsGetCurrentThread());
164 // Function: AFSAcquireExcl()
166 // Purpose: Called to acquire a resource exclusive with optional wait
169 // PERESOURCE Resource - Resource to acquire
170 // BOOLEAN Wait - Whether to block
173 // BOOLEAN - Whether the mask was acquired
177 AFSAcquireExcl( IN PERESOURCE Resource,
181 BOOLEAN bStatus = FALSE;
184 // Normal kernel APCs must be disabled before calling
185 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
188 KeEnterCriticalRegion();
190 bStatus = ExAcquireResourceExclusiveLite( Resource,
196 KeLeaveCriticalRegion();
203 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
207 BOOLEAN bStatus = FALSE;
209 KeEnterCriticalRegion();
211 bStatus = ExAcquireSharedStarveExclusive( Resource,
217 KeLeaveCriticalRegion();
224 // Function: AFSAcquireShared()
226 // Purpose: Called to acquire a resource shared with optional wait
229 // PERESOURCE Resource - Resource to acquire
230 // BOOLEAN Wait - Whether to block
233 // BOOLEAN - Whether the mask was acquired
237 AFSAcquireShared( IN PERESOURCE Resource,
241 BOOLEAN bStatus = FALSE;
243 KeEnterCriticalRegion();
245 bStatus = ExAcquireResourceSharedLite( Resource,
251 KeLeaveCriticalRegion();
258 // Function: AFSReleaseResource()
260 // Purpose: Called to release a resource
263 // PERESOURCE Resource - Resource to release
270 AFSReleaseResource( IN PERESOURCE Resource)
273 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
274 AFS_TRACE_LEVEL_VERBOSE,
275 "AFSReleaseResource Releasing lock %08lX Thread %08lX\n",
277 PsGetCurrentThread());
279 ExReleaseResourceLite( Resource);
281 KeLeaveCriticalRegion();
287 AFSConvertToShared( IN PERESOURCE Resource)
290 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
291 AFS_TRACE_LEVEL_VERBOSE,
292 "AFSConvertToShared Converting lock %08lX Thread %08lX\n",
294 PsGetCurrentThread());
296 ExConvertExclusiveToSharedLite( Resource);
302 // Function: AFSCompleteRequest
306 // This function completes irps
310 // A status is returned for the function
314 AFSCompleteRequest( IN PIRP Irp,
318 Irp->IoStatus.Status = Status;
320 IoCompleteRequest( Irp,
327 // Function: AFSGenerateCRC
331 // Given a device and filename this function generates a CRC
335 // A status is returned for the function
339 AFSGenerateCRC( IN PUNICODE_STRING FileName,
340 IN BOOLEAN UpperCaseName)
344 NTSTATUS ntStatus = STATUS_SUCCESS;
346 ntStatus = RtlHashUnicodeString( FileName,
348 HASH_STRING_ALGORITHM_DEFAULT,
351 if( !NT_SUCCESS( ntStatus))
360 AFSLockSystemBuffer( IN PIRP Irp,
364 NTSTATUS Status = STATUS_SUCCESS;
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( GetExceptionCode(), GetExceptionInformation()) )
409 IoFreeMdl( Irp->MdlAddress );
410 Irp->MdlAddress = NULL;
420 AFSLockUserBuffer( IN void *UserBuffer,
421 IN ULONG BufferLength,
425 NTSTATUS ntStatus = STATUS_SUCCESS;
426 void *pAddress = NULL;
432 pMdl = IoAllocateMdl( UserBuffer,
441 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
445 // Lock the new Mdl in memory.
451 MmProbeAndLockPages( pMdl,
455 pAddress = MmGetSystemAddressForMdlSafe( pMdl,
458 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
481 AFSMapToService( IN PIRP Irp,
485 NTSTATUS ntStatus = STATUS_SUCCESS;
486 void *pMappedBuffer = NULL;
487 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
493 if( pDevExt->Specific.Control.ServiceProcess == NULL)
496 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
499 if( Irp->MdlAddress == NULL)
502 if( AFSLockSystemBuffer( Irp,
506 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
511 // Attach to the service process for mapping
514 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
515 (PRKAPC_STATE)&stApcState);
517 pMappedBuffer = MmMapLockedPagesSpecifyCache( Irp->MdlAddress,
524 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
531 return pMappedBuffer;
535 AFSUnmapServiceMappedBuffer( IN void *MappedBuffer,
539 NTSTATUS ntStatus = STATUS_SUCCESS;
540 void *pMappedBuffer = NULL;
541 AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
547 if( pDevExt->Specific.Control.ServiceProcess == NULL)
550 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
557 // Attach to the service process for mapping
560 KeStackAttachProcess( pDevExt->Specific.Control.ServiceProcess,
561 (PRKAPC_STATE)&stApcState);
563 MmUnmapLockedPages( MappedBuffer,
566 KeUnstackDetachProcess( (PRKAPC_STATE)&stApcState);
578 AFSInitializeLibraryDevice()
581 NTSTATUS ntStatus = STATUS_SUCCESS;
582 AFSDeviceExt *pDeviceExt = NULL;
587 pDeviceExt = (AFSDeviceExt *)AFSLibraryDeviceObject->DeviceExtension;
590 // The PIOCtl file name
593 RtlInitUnicodeString( &AFSPIOCtlName,
594 AFS_PIOCTL_FILE_INTERFACE_NAME);
597 // And the global root share name
600 RtlInitUnicodeString( &AFSGlobalRootName,
601 AFS_GLOBAL_ROOT_SHARE_NAME);
609 AFSRemoveLibraryDevice()
612 NTSTATUS ntStatus = STATUS_SUCCESS;
623 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
627 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
628 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
630 AFSCompleteRequest( Irp,
637 AFSInitializeGlobalDirectoryEntries()
640 NTSTATUS ntStatus = STATUS_SUCCESS;
641 AFSDirectoryCB *pDirNode = NULL;
642 ULONG ulEntryLength = 0;
643 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
644 AFSObjectInfoCB *pObjectInfoCB = NULL;
645 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
651 // Initialize the global . entry
654 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
657 if( pObjectInfoCB == NULL)
660 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
661 AFS_TRACE_LEVEL_ERROR,
662 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
665 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
668 InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
670 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
671 AFS_TRACE_LEVEL_VERBOSE,
672 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
674 pObjectInfoCB->ObjectReferenceCount);
676 ntStatus = STATUS_SUCCESS;
678 ulEntryLength = sizeof( AFSDirectoryCB) +
681 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
685 if( pDirNode == NULL)
688 AFSDeleteObjectInfo( pObjectInfoCB);
690 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
691 AFS_TRACE_LEVEL_ERROR,
692 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
694 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
697 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
698 sizeof( AFSNonPagedDirectoryCB),
699 AFS_DIR_ENTRY_NP_TAG);
701 if( pNonPagedDirEntry == NULL)
704 ExFreePool( pDirNode);
706 AFSDeleteObjectInfo( pObjectInfoCB);
708 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
709 AFS_TRACE_LEVEL_ERROR,
710 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
712 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
715 RtlZeroMemory( pDirNode,
718 RtlZeroMemory( pNonPagedDirEntry,
719 sizeof( AFSNonPagedDirectoryCB));
721 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
723 pDirNode->NonPaged = pNonPagedDirEntry;
725 pDirNode->ObjectInformation = pObjectInfoCB;
731 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
733 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
736 // Setup the names in the entry
739 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
741 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
743 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
745 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
748 // Populate the rest of the data
751 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
753 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
755 AFSGlobalDotDirEntry = pDirNode;
761 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
764 if( pObjectInfoCB == NULL)
767 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
768 AFS_TRACE_LEVEL_ERROR,
769 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
772 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
775 InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
777 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
778 AFS_TRACE_LEVEL_VERBOSE,
779 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
781 pObjectInfoCB->ObjectReferenceCount);
783 ntStatus = STATUS_SUCCESS;
785 ulEntryLength = sizeof( AFSDirectoryCB) +
786 ( 2 * sizeof( WCHAR));
788 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
792 if( pDirNode == NULL)
795 AFSDeleteObjectInfo( pObjectInfoCB);
797 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
800 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
801 sizeof( AFSNonPagedDirectoryCB),
802 AFS_DIR_ENTRY_NP_TAG);
804 if( pNonPagedDirEntry == NULL)
807 ExFreePool( pDirNode);
809 AFSDeleteObjectInfo( pObjectInfoCB);
811 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
814 RtlZeroMemory( pDirNode,
817 RtlZeroMemory( pNonPagedDirEntry,
818 sizeof( AFSNonPagedDirectoryCB));
820 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
822 pDirNode->NonPaged = pNonPagedDirEntry;
824 pDirNode->ObjectInformation = pObjectInfoCB;
830 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
832 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
835 // Setup the names in the entry
838 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
840 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
842 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
844 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
846 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
849 // Populate the rest of the data
852 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
854 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
856 AFSGlobalDotDotDirEntry = pDirNode;
860 if( !NT_SUCCESS( ntStatus))
863 if( AFSGlobalDotDirEntry != NULL)
866 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
868 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
870 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
872 ExFreePool( AFSGlobalDotDirEntry);
874 AFSGlobalDotDirEntry = NULL;
877 if( AFSGlobalDotDotDirEntry != NULL)
880 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
882 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
884 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
886 ExFreePool( AFSGlobalDotDotDirEntry);
888 AFSGlobalDotDotDirEntry = NULL;
897 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
898 IN PUNICODE_STRING FileName,
899 IN PUNICODE_STRING TargetName,
900 IN AFSDirEnumEntry *DirEnumEntry,
904 AFSDirectoryCB *pDirNode = NULL;
905 NTSTATUS ntStatus = STATUS_SUCCESS;
906 ULONG ulEntryLength = 0;
907 AFSDirEnumEntry *pDirEnumCB = NULL;
908 AFSFileID stTargetFileID;
910 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
911 AFSObjectInfoCB *pObjectInfoCB = NULL;
912 BOOLEAN bAllocatedObjectCB = FALSE;
913 ULONGLONG ullIndex = 0;
914 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
919 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
920 AFS_TRACE_LEVEL_VERBOSE,
921 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
923 ParentObjectInfo->FileId.Cell,
924 ParentObjectInfo->FileId.Volume,
925 ParentObjectInfo->FileId.Vnode,
926 ParentObjectInfo->FileId.Unique);
929 // First thing is to locate/create our object information block
933 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
936 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
938 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
940 (AFSBTreeEntry **)&pObjectInfoCB);
942 if( !NT_SUCCESS( ntStatus) ||
943 pObjectInfoCB == NULL)
947 // Allocate our object info cb
950 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
953 if( pObjectInfoCB == NULL)
956 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
958 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
961 bAllocatedObjectCB = TRUE;
963 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
964 AFS_TRACE_LEVEL_VERBOSE,
965 "AFSInitDirEntry initialized object %08lX Parent Object %08lX for %wZ\n",
971 InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
973 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
974 AFS_TRACE_LEVEL_VERBOSE,
975 "AFSInitDirEntry Increment count on object %08lX Cnt %d\n",
977 pObjectInfoCB->ObjectReferenceCount);
979 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
981 ntStatus = STATUS_SUCCESS;
983 ulEntryLength = sizeof( AFSDirectoryCB) +
986 if( TargetName != NULL)
989 ulEntryLength += TargetName->Length;
992 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
996 if( pDirNode == NULL)
999 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1002 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1003 sizeof( AFSNonPagedDirectoryCB),
1004 AFS_DIR_ENTRY_NP_TAG);
1006 if( pNonPagedDirEntry == NULL)
1009 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1012 RtlZeroMemory( pDirNode,
1015 RtlZeroMemory( pNonPagedDirEntry,
1016 sizeof( AFSNonPagedDirectoryCB));
1018 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1020 pDirNode->NonPaged = pNonPagedDirEntry;
1022 pDirNode->ObjectInformation = pObjectInfoCB;
1025 // Set valid entry and NOT_IN_PARENT flag
1028 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1030 pDirNode->FileIndex = FileIndex;
1033 // Setup the names in the entry
1036 if( FileName->Length > 0)
1039 pDirNode->NameInformation.FileName.Length = FileName->Length;
1041 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1043 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1045 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1047 pDirNode->NameInformation.FileName.Length);
1050 // Create a CRC for the file
1053 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1056 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1060 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1061 AFS_TRACE_LEVEL_VERBOSE,
1062 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1065 ParentObjectInfo->FileId.Cell,
1066 ParentObjectInfo->FileId.Volume,
1067 ParentObjectInfo->FileId.Vnode,
1068 ParentObjectInfo->FileId.Unique);
1070 if( TargetName != NULL &&
1071 TargetName->Length > 0)
1074 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1076 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1078 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1079 sizeof( AFSDirectoryCB) +
1080 pDirNode->NameInformation.FileName.Length);
1082 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1084 pDirNode->NameInformation.TargetName.Length);
1088 // If we allocated the object information cb then update the information
1091 if( bAllocatedObjectCB)
1095 // Populate the rest of the data
1098 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1100 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1102 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1104 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1106 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1108 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1110 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1112 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1114 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1116 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1118 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1119 pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1120 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1123 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1126 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1129 // Object specific information
1132 pObjectInfoCB->Links = DirEnumEntry->Links;
1134 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1136 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1139 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1140 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1144 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1145 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1146 pObjectInfoCB->TargetFileId.Unique == 0 &&
1147 pDirNode->NameInformation.TargetName.Length == 0)
1151 // This will ensure we perform a validation on the node
1154 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1157 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1160 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1166 if( !NT_SUCCESS( ntStatus))
1169 if( pNonPagedDirEntry != NULL)
1172 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1174 AFSExFreePool( pNonPagedDirEntry);
1177 if( pDirNode != NULL)
1180 AFSExFreePool( pDirNode);
1186 // Dereference our object info block if we have one
1189 if( pObjectInfoCB != NULL)
1192 InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
1194 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1195 AFS_TRACE_LEVEL_VERBOSE,
1196 "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
1198 pObjectInfoCB->ObjectReferenceCount);
1200 if( bAllocatedObjectCB)
1203 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1205 AFSDeleteObjectInfo( pObjectInfoCB);
1215 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1216 IN BOOLEAN DirectoryEntry)
1219 BOOLEAN bReturn = TRUE;
1220 ACCESS_MASK stAccessMask = 0;
1223 // Get rid of anything we don't know about
1226 DesiredAccess = (DesiredAccess &
1232 ACCESS_SYSTEM_SECURITY |
1236 FILE_READ_ATTRIBUTES |
1237 FILE_WRITE_ATTRIBUTES |
1238 FILE_LIST_DIRECTORY |
1244 // Our 'read only' access mask. These are the accesses we will
1245 // allow for a read only file
1248 stAccessMask = DELETE |
1253 ACCESS_SYSTEM_SECURITY |
1257 FILE_READ_ATTRIBUTES |
1258 FILE_WRITE_ATTRIBUTES |
1260 FILE_LIST_DIRECTORY |
1264 // For a directory, add in the directory specific accesses
1270 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1275 if( FlagOn( DesiredAccess, ~stAccessMask))
1279 // A write access is set ...
1289 AFSEvaluateNode( IN GUID *AuthGroup,
1290 IN AFSDirectoryCB *DirEntry)
1293 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1294 NTSTATUS ntStatus = STATUS_SUCCESS;
1295 AFSDirEnumEntry *pDirEntry = NULL;
1296 UNICODE_STRING uniTargetName;
1301 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1306 if( !NT_SUCCESS( ntStatus))
1309 try_return( ntStatus);
1312 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1314 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1316 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1318 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1320 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1322 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1324 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1326 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1328 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1330 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1332 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1334 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1335 pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1336 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1339 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1342 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1344 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1347 // If we have a target name then see if it needs updating ...
1350 if( pDirEntry->TargetNameLength > 0)
1354 // Update the target name information if needed
1357 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1359 uniTargetName.MaximumLength = uniTargetName.Length;
1361 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1363 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1366 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1367 RtlCompareUnicodeString( &uniTargetName,
1368 &DirEntry->NameInformation.TargetName,
1373 // Update the target name
1376 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1378 uniTargetName.Buffer,
1379 uniTargetName.Length);
1381 if( !NT_SUCCESS( ntStatus))
1384 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1386 try_return( ntStatus);
1390 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1395 if( pDirEntry != NULL)
1398 AFSExFreePool( pDirEntry);
1406 AFSValidateSymLink( IN GUID *AuthGroup,
1407 IN AFSDirectoryCB *DirEntry)
1410 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1411 NTSTATUS ntStatus = STATUS_SUCCESS;
1412 AFSDirEnumEntry *pDirEntry = NULL;
1413 UNICODE_STRING uniTargetName;
1418 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1423 if( !NT_SUCCESS( ntStatus))
1426 try_return( ntStatus);
1429 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1430 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1433 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1436 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1438 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1440 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1443 // Update the target name information if needed
1446 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1448 uniTargetName.MaximumLength = uniTargetName.Length;
1450 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1452 if( uniTargetName.Length > 0)
1455 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1458 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1459 RtlCompareUnicodeString( &uniTargetName,
1460 &DirEntry->NameInformation.TargetName,
1465 // Update the target name
1468 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1470 uniTargetName.Buffer,
1471 uniTargetName.Length);
1473 if( !NT_SUCCESS( ntStatus))
1476 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1478 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1482 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1486 // If the FileType is the same then nothing to do since it IS
1490 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1493 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1495 try_return( ntStatus = STATUS_SUCCESS);
1498 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1500 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1502 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1504 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1506 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1508 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1510 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1512 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1514 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1515 pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1516 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1519 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1522 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1524 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1528 if( pDirEntry != NULL)
1531 AFSExFreePool( pDirEntry);
1539 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1542 NTSTATUS ntStatus = STATUS_SUCCESS;
1543 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1544 AFSVolumeCB *pVolumeCB = NULL;
1545 AFSFcb *pTargetDcb = NULL;
1546 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1547 AFSDirectoryCB *pCurrentDirEntry = NULL;
1548 BOOLEAN bIsChild = FALSE;
1549 ULONGLONG ullIndex = 0;
1550 AFSObjectInfoCB *pObjectInfo = NULL;
1551 IO_STATUS_BLOCK stIoStatus;
1558 // Need to locate the Fcb for the directory to purge
1561 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1562 AFS_TRACE_LEVEL_VERBOSE,
1563 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1564 &pDevExt->Specific.RDR.VolumeTreeLock,
1565 PsGetCurrentThread());
1568 // Starve any exclusive waiters on this paticular call
1571 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1574 // Locate the volume node
1577 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1579 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1581 (AFSBTreeEntry **)&pVolumeCB);
1583 if( pVolumeCB != NULL)
1586 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1588 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1589 AFS_TRACE_LEVEL_VERBOSE,
1590 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1592 pVolumeCB->VolumeReferenceCount);
1595 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1597 if( !NT_SUCCESS( ntStatus) ||
1600 try_return( ntStatus = STATUS_SUCCESS);
1604 // If this is a whole volume invalidation then go do it now
1607 if( InvalidateCB->WholeVolume ||
1608 AFSIsVolumeFID( &InvalidateCB->FileID))
1611 ntStatus = AFSInvalidateVolume( pVolumeCB,
1612 InvalidateCB->Reason);
1614 AFSFsRtlNotifyFullReportChange( &pVolumeCB->ObjectInformation,
1616 FILE_NOTIFY_CHANGE_FILE_NAME |
1617 FILE_NOTIFY_CHANGE_DIR_NAME |
1618 FILE_NOTIFY_CHANGE_NAME |
1619 FILE_NOTIFY_CHANGE_ATTRIBUTES |
1620 FILE_NOTIFY_CHANGE_SIZE,
1621 FILE_ACTION_MODIFIED);
1623 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1625 try_return( ntStatus);
1628 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1631 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1633 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1634 AFS_TRACE_LEVEL_VERBOSE,
1635 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
1637 pVolumeCB->VolumeReferenceCount);
1639 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
1641 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
1643 (AFSBTreeEntry **)&pObjectInfo);
1645 if( pObjectInfo != NULL)
1649 // Reference the node so it won't be torn down
1652 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
1654 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1655 AFS_TRACE_LEVEL_VERBOSE,
1656 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
1658 pObjectInfo->ObjectReferenceCount);
1661 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1663 if( !NT_SUCCESS( ntStatus) ||
1664 pObjectInfo == NULL)
1666 try_return( ntStatus = STATUS_SUCCESS);
1669 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
1670 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK ||
1671 pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1674 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1675 AFS_TRACE_LEVEL_VERBOSE,
1676 "AFSInvalidateCache Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1677 pObjectInfo->FileType,
1678 pObjectInfo->FileId.Cell,
1679 pObjectInfo->FileId.Volume,
1680 pObjectInfo->FileId.Vnode,
1681 pObjectInfo->FileId.Unique,
1682 InvalidateCB->Reason);
1685 // We only act on the mount point itself, not the target. If the
1686 // node has been deleted then mark it as such otherwise indicate
1687 // it requires verification
1690 if( InvalidateCB->Reason == AFS_INVALIDATE_DELETED)
1692 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1697 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
1698 InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1700 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1703 pObjectInfo->Expiration.QuadPart = 0;
1705 pObjectInfo->TargetFileId.Vnode = 0;
1707 pObjectInfo->TargetFileId.Unique = 0;
1709 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1710 AFS_TRACE_LEVEL_VERBOSE,
1711 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1712 pObjectInfo->FileId.Cell,
1713 pObjectInfo->FileId.Volume,
1714 pObjectInfo->FileId.Vnode,
1715 pObjectInfo->FileId.Unique);
1717 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1720 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1722 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1724 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1727 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1729 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1733 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1736 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1738 FILE_NOTIFY_CHANGE_FILE_NAME |
1739 FILE_NOTIFY_CHANGE_ATTRIBUTES,
1740 FILE_ACTION_MODIFIED);
1742 try_return( ntStatus);
1746 // Depending on the reason for invalidation then perform work on the node
1749 switch( InvalidateCB->Reason)
1752 case AFS_INVALIDATE_DELETED:
1756 // Mark this node as invalid
1759 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
1761 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1762 AFS_TRACE_LEVEL_VERBOSE,
1763 "AFSInvalidateCache Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1764 pObjectInfo->FileId.Cell,
1765 pObjectInfo->FileId.Volume,
1766 pObjectInfo->FileId.Vnode,
1767 pObjectInfo->FileId.Unique);
1769 if( pObjectInfo->ParentObjectInformation != NULL)
1772 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1773 AFS_TRACE_LEVEL_VERBOSE,
1774 "AFSInvalidateCache Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1775 pObjectInfo->ParentObjectInformation->FileId.Cell,
1776 pObjectInfo->ParentObjectInformation->FileId.Volume,
1777 pObjectInfo->ParentObjectInformation->FileId.Vnode,
1778 pObjectInfo->ParentObjectInformation->FileId.Unique);
1780 SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1781 pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1782 pObjectInfo->ParentObjectInformation->Expiration.QuadPart = 0;
1785 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1787 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1791 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1794 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1797 FILE_ACTION_REMOVED);
1802 case AFS_INVALIDATE_FLUSHED:
1805 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
1806 pObjectInfo->Fcb != NULL)
1809 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1810 AFS_TRACE_LEVEL_VERBOSE,
1811 "AFSInvalidateCache Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1812 pObjectInfo->FileId.Cell,
1813 pObjectInfo->FileId.Volume,
1814 pObjectInfo->FileId.Vnode,
1815 pObjectInfo->FileId.Unique);
1817 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
1823 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1828 if( !NT_SUCCESS( stIoStatus.Status))
1831 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1832 AFS_TRACE_LEVEL_ERROR,
1833 "AFSInvalidateCache CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1834 pObjectInfo->FileId.Cell,
1835 pObjectInfo->FileId.Volume,
1836 pObjectInfo->FileId.Vnode,
1837 pObjectInfo->FileId.Unique,
1839 stIoStatus.Information);
1841 ntStatus = stIoStatus.Status;
1844 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1849 __except( EXCEPTION_EXECUTE_HANDLER)
1852 ntStatus = GetExceptionCode();
1855 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
1858 // Clear out the extents
1859 // Get rid of them (note this involves waiting
1860 // for any writes or reads to the cache to complete)
1863 (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb);
1866 // Fall through to the default processing
1872 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1874 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1878 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1881 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1883 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1886 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1888 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1892 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1895 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1898 FILE_ACTION_MODIFIED);
1901 // Indicate this node requires re-evaluation for the remaining reasons
1904 pObjectInfo->Expiration.QuadPart = 0;
1906 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1907 AFS_TRACE_LEVEL_VERBOSE,
1908 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1909 pObjectInfo->FileId.Cell,
1910 pObjectInfo->FileId.Volume,
1911 pObjectInfo->FileId.Vnode,
1912 pObjectInfo->FileId.Unique);
1914 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1916 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
1917 InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1919 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1921 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
1924 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1925 AFS_TRACE_LEVEL_VERBOSE,
1926 "AFSInvalidateCache Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1927 pObjectInfo->FileId.Cell,
1928 pObjectInfo->FileId.Volume,
1929 pObjectInfo->FileId.Vnode,
1930 pObjectInfo->FileId.Unique);
1932 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1942 if( pObjectInfo != NULL)
1945 InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
1947 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1948 AFS_TRACE_LEVEL_VERBOSE,
1949 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
1951 pObjectInfo->ObjectReferenceCount);
1959 AFSIsChildOfParent( IN AFSFcb *Dcb,
1963 BOOLEAN bIsChild = FALSE;
1964 AFSFcb *pCurrentFcb = Fcb;
1966 while( pCurrentFcb != NULL)
1969 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
1977 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
1985 AFSCreateHighIndex( IN AFSFileID *FileID)
1988 ULONGLONG ullIndex = 0;
1990 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
1997 AFSCreateLowIndex( IN AFSFileID *FileID)
2000 ULONGLONG ullIndex = 0;
2002 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2008 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2009 IN ACCESS_MASK GrantedAccess,
2010 IN BOOLEAN DirectoryEntry)
2013 BOOLEAN bAccessGranted = TRUE;
2016 // Check if we are asking for read/write and granted only read only
2017 // NOTE: There will be more checks here
2020 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2022 AFSCheckForReadOnlyAccess( GrantedAccess,
2026 bAccessGranted = FALSE;
2029 return bAccessGranted;
2033 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2036 NTSTATUS ntStatus = STATUS_SUCCESS;
2037 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2043 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2045 if( AFSGlobalRoot == NULL)
2052 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2055 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2062 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2069 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2070 IN UNICODE_STRING *SubstituteName,
2071 IN ULONG StringIndex)
2074 NTSTATUS ntStatus = STATUS_SUCCESS;
2075 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2076 AFSSysNameCB *pSysName = NULL;
2077 ERESOURCE *pSysNameLock = NULL;
2080 UNICODE_STRING uniSysName;
2087 if( IoIs32bitProcess( NULL))
2090 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2092 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2097 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2099 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2103 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2105 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2109 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2110 AFS_TRACE_LEVEL_VERBOSE,
2111 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2113 PsGetCurrentThread());
2115 AFSAcquireShared( pSysNameLock,
2119 // Find where we are in the list
2122 while( pSysName != NULL &&
2123 ulIndex < StringIndex)
2126 pSysName = pSysName->fLink;
2131 if( pSysName == NULL)
2134 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2137 RtlInitUnicodeString( &uniSysName,
2140 // If it is a full component of @SYS then just substitue the
2144 if( RtlCompareUnicodeString( &uniSysName,
2149 SubstituteName->Length = pSysName->SysName.Length;
2150 SubstituteName->MaximumLength = SubstituteName->Length;
2152 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2153 SubstituteName->Length,
2154 AFS_SUBST_BUFFER_TAG);
2156 if( SubstituteName->Buffer == NULL)
2159 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2162 RtlCopyMemory( SubstituteName->Buffer,
2163 pSysName->SysName.Buffer,
2164 pSysName->SysName.Length);
2171 while( ComponentName->Buffer[ usIndex] != L'@')
2177 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2178 SubstituteName->MaximumLength = SubstituteName->Length;
2180 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2181 SubstituteName->Length,
2182 AFS_SUBST_BUFFER_TAG);
2184 if( SubstituteName->Buffer == NULL)
2187 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2190 RtlCopyMemory( SubstituteName->Buffer,
2191 ComponentName->Buffer,
2192 usIndex * sizeof( WCHAR));
2194 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2195 pSysName->SysName.Buffer,
2196 pSysName->SysName.Length);
2201 AFSReleaseResource( pSysNameLock);
2208 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2209 IN OUT UNICODE_STRING *ComponentName,
2210 IN UNICODE_STRING *SubstituteName,
2211 IN OUT UNICODE_STRING *RemainingPath,
2212 IN BOOLEAN FreePathName)
2215 NTSTATUS ntStatus = STATUS_SUCCESS;
2216 UNICODE_STRING uniPathName;
2217 USHORT usPrefixNameLen = 0;
2218 SHORT sNameLenDelta = 0;
2224 // If the passed in name can handle the additional length
2225 // then just moves things around
2228 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2230 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2232 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2235 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2238 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2239 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2240 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2243 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2244 SubstituteName->Buffer,
2245 SubstituteName->Length);
2247 FullPathName->Length += sNameLenDelta;
2249 ComponentName->Length += sNameLenDelta;
2251 ComponentName->MaximumLength = ComponentName->Length;
2253 if ( RemainingPath->Buffer)
2256 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2259 try_return( ntStatus);
2263 // Need to re-allocate the buffer
2266 uniPathName.Length = FullPathName->Length -
2267 ComponentName->Length +
2268 SubstituteName->Length;
2270 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2272 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2273 uniPathName.MaximumLength,
2274 AFS_NAME_BUFFER_FOUR_TAG);
2276 if( uniPathName.Buffer == NULL)
2279 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2282 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2284 usPrefixNameLen *= sizeof( WCHAR);
2286 RtlZeroMemory( uniPathName.Buffer,
2287 uniPathName.MaximumLength);
2289 RtlCopyMemory( uniPathName.Buffer,
2290 FullPathName->Buffer,
2293 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2294 SubstituteName->Buffer,
2295 SubstituteName->Length);
2297 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2300 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2301 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2302 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2305 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2307 ComponentName->Length += sNameLenDelta;
2309 ComponentName->MaximumLength = ComponentName->Length;
2311 if ( RemainingPath->Buffer)
2314 RemainingPath->Buffer = uniPathName.Buffer
2315 + (RemainingPath->Buffer - FullPathName->Buffer)
2316 + sNameLenDelta/sizeof( WCHAR);
2321 AFSExFreePool( FullPathName->Buffer);
2324 *FullPathName = uniPathName;
2335 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2339 NTSTATUS ntStatus = STATUS_SUCCESS;
2340 AFSFcb *pFcb = NULL;
2341 AFSObjectInfoCB *pCurrentObject = NULL;
2347 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2348 AFS_TRACE_LEVEL_VERBOSE,
2349 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2350 VolumeCB->ObjectInformation.FileId.Cell,
2351 VolumeCB->ObjectInformation.FileId.Volume,
2352 VolumeCB->ObjectInformation.FileId.Vnode,
2353 VolumeCB->ObjectInformation.FileId.Unique,
2357 // Depending on the reason for invalidation then perform work on the node
2363 case AFS_INVALIDATE_DELETED:
2367 // Mark this volume as invalid
2370 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2372 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2374 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2376 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2378 FILE_NOTIFY_CHANGE_DIR_NAME,
2379 FILE_ACTION_REMOVED);
2381 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2384 pCurrentObject = VolumeCB->ObjectInfoListHead;
2386 while( pCurrentObject != NULL)
2389 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2391 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2395 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2398 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2401 FILE_ACTION_REMOVED);
2403 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2405 pFcb = pCurrentObject->Fcb;
2408 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2413 // Clear out the extents
2414 // And get rid of them (note this involves waiting
2415 // for any writes or reads to the cache to complete)
2418 (VOID) AFSTearDownFcbExtents( pFcb);
2421 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2424 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2433 // Indicate this node requires re-evaluation for the remaining reasons
2436 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2438 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2439 AFS_TRACE_LEVEL_VERBOSE,
2440 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2441 VolumeCB->ObjectInformation.FileId.Cell,
2442 VolumeCB->ObjectInformation.FileId.Volume,
2443 VolumeCB->ObjectInformation.FileId.Vnode,
2444 VolumeCB->ObjectInformation.FileId.Unique);
2446 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY);
2448 if( Reason == AFS_INVALIDATE_FLUSHED ||
2449 Reason == AFS_INVALIDATE_DATA_VERSION)
2452 VolumeCB->ObjectInformation.DataVersion.QuadPart = (ULONGLONG)-1;
2456 // Notify anyone that cares
2459 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2461 if( Reason == AFS_INVALIDATE_CREDS)
2463 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2466 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2468 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2472 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2475 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2478 FILE_ACTION_MODIFIED);
2481 // Volume invalidations require all objects in the volume be re-verified
2484 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2487 pCurrentObject = VolumeCB->ObjectInfoListHead;
2489 while( pCurrentObject != NULL)
2492 pCurrentObject->Expiration.QuadPart = 0;
2494 pCurrentObject->TargetFileId.Vnode = 0;
2496 pCurrentObject->TargetFileId.Unique = 0;
2498 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2499 AFS_TRACE_LEVEL_VERBOSE,
2500 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2501 pCurrentObject->FileId.Cell,
2502 pCurrentObject->FileId.Volume,
2503 pCurrentObject->FileId.Vnode,
2504 pCurrentObject->FileId.Unique);
2506 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
2508 if( Reason == AFS_INVALIDATE_FLUSHED ||
2509 Reason == AFS_INVALIDATE_DATA_VERSION)
2512 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
2514 if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
2517 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2518 AFS_TRACE_LEVEL_VERBOSE,
2519 "AFSInvalidateVolume Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
2520 pCurrentObject->FileId.Cell,
2521 pCurrentObject->FileId.Volume,
2522 pCurrentObject->FileId.Vnode,
2523 pCurrentObject->FileId.Unique);
2525 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2529 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2531 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2535 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2538 if( Reason == AFS_INVALIDATE_CREDS)
2540 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2543 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2545 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2549 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2552 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2555 FILE_ACTION_MODIFIED);
2557 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2560 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2571 AFSVerifyEntry( IN GUID *AuthGroup,
2572 IN AFSDirectoryCB *DirEntry)
2575 NTSTATUS ntStatus = STATUS_SUCCESS;
2576 AFSDirEnumEntry *pDirEnumEntry = NULL;
2577 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2578 IO_STATUS_BLOCK stIoStatus;
2583 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2584 AFS_TRACE_LEVEL_VERBOSE_2,
2585 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2586 &DirEntry->NameInformation.FileName,
2587 pObjectInfo->FileId.Cell,
2588 pObjectInfo->FileId.Volume,
2589 pObjectInfo->FileId.Vnode,
2590 pObjectInfo->FileId.Unique);
2592 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2597 if( !NT_SUCCESS( ntStatus))
2600 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2601 AFS_TRACE_LEVEL_ERROR,
2602 "AFSValidateEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2603 &DirEntry->NameInformation.FileName,
2604 pObjectInfo->FileId.Cell,
2605 pObjectInfo->FileId.Volume,
2606 pObjectInfo->FileId.Vnode,
2607 pObjectInfo->FileId.Unique,
2610 try_return( ntStatus);
2614 // Check the data version of the file
2617 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2618 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2621 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2622 AFS_TRACE_LEVEL_VERBOSE,
2623 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2624 pObjectInfo->DataVersion.QuadPart,
2625 &DirEntry->NameInformation.FileName,
2626 pObjectInfo->FileId.Cell,
2627 pObjectInfo->FileId.Volume,
2628 pObjectInfo->FileId.Vnode,
2629 pObjectInfo->FileId.Unique);
2632 // We are ok, just get out
2635 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2637 try_return( ntStatus = STATUS_SUCCESS);
2641 // New data version so we will need to process the node based on the type
2644 switch( pDirEnumEntry->FileType)
2647 case AFS_FILE_TYPE_MOUNTPOINT:
2651 // For a mount point we need to ensure the target is the same
2654 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2655 &pDirEnumEntry->TargetFileId))
2661 // Update the metadata for the entry
2664 ntStatus = AFSUpdateMetaData( DirEntry,
2667 if( NT_SUCCESS( ntStatus))
2670 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2676 case AFS_FILE_TYPE_SYMLINK:
2679 ASSERT( pDirEnumEntry->TargetNameLength > 0);
2682 // Update the metadata for the entry
2685 ntStatus = AFSUpdateMetaData( DirEntry,
2688 if( NT_SUCCESS( ntStatus))
2691 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2697 case AFS_FILE_TYPE_FILE:
2699 FILE_OBJECT * pCCFileObject = NULL;
2700 BOOLEAN bPurgeExtents = FALSE;
2702 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2704 bPurgeExtents = TRUE;
2706 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2707 AFS_TRACE_LEVEL_VERBOSE,
2708 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2709 &DirEntry->NameInformation.FileName,
2710 pObjectInfo->FileId.Cell,
2711 pObjectInfo->FileId.Volume,
2712 pObjectInfo->FileId.Vnode,
2713 pObjectInfo->FileId.Unique);
2715 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2719 // Update the metadata for the entry
2722 ntStatus = AFSUpdateMetaData( DirEntry,
2725 if( !NT_SUCCESS( ntStatus))
2728 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2729 AFS_TRACE_LEVEL_ERROR,
2730 "AFSInvalidateCache Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2731 &DirEntry->NameInformation.FileName,
2732 pObjectInfo->FileId.Cell,
2733 pObjectInfo->FileId.Volume,
2734 pObjectInfo->FileId.Vnode,
2735 pObjectInfo->FileId.Unique,
2741 if( pObjectInfo->Fcb != NULL)
2744 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2745 AFS_TRACE_LEVEL_VERBOSE,
2746 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2747 &DirEntry->NameInformation.FileName,
2748 pObjectInfo->FileId.Cell,
2749 pObjectInfo->FileId.Volume,
2750 pObjectInfo->FileId.Vnode,
2751 pObjectInfo->FileId.Unique);
2753 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2759 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2764 if( !NT_SUCCESS( stIoStatus.Status))
2767 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2768 AFS_TRACE_LEVEL_ERROR,
2769 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2770 &DirEntry->NameInformation.FileName,
2771 pObjectInfo->FileId.Cell,
2772 pObjectInfo->FileId.Volume,
2773 pObjectInfo->FileId.Vnode,
2774 pObjectInfo->FileId.Unique,
2776 stIoStatus.Information);
2778 ntStatus = stIoStatus.Status;
2784 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2790 __except( EXCEPTION_EXECUTE_HANDLER)
2792 ntStatus = GetExceptionCode();
2794 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2795 AFS_TRACE_LEVEL_ERROR,
2796 "AFSVerifyEntry CcFlushCache or CcPurgeCacheSection Exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2797 &DirEntry->NameInformation.FileName,
2798 pObjectInfo->FileId.Cell,
2799 pObjectInfo->FileId.Volume,
2800 pObjectInfo->FileId.Vnode,
2801 pObjectInfo->FileId.Unique,
2805 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2809 AFSFlushExtents( pObjectInfo->Fcb);
2813 // Reacquire the Fcb to purge the cache
2816 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2817 AFS_TRACE_LEVEL_VERBOSE,
2818 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2819 &pObjectInfo->Fcb->NPFcb->Resource,
2820 PsGetCurrentThread());
2822 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2826 // Update file sizes
2829 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2830 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2831 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2833 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2835 if ( pCCFileObject != NULL)
2837 CcSetFileSizes( pCCFileObject,
2838 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
2841 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2845 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2846 AFS_TRACE_LEVEL_WARNING,
2847 "AFSValidateEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2848 &DirEntry->NameInformation.FileName,
2849 pObjectInfo->FileId.Cell,
2850 pObjectInfo->FileId.Volume,
2851 pObjectInfo->FileId.Vnode,
2852 pObjectInfo->FileId.Unique);
2855 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2860 case AFS_FILE_TYPE_DIRECTORY:
2863 AFSFcb *pCurrentFcb = NULL;
2864 AFSDirectoryCB *pCurrentDirEntry = NULL;
2867 // For a directory or root entry flush the content of
2868 // the directory enumeration.
2871 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2874 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2875 AFS_TRACE_LEVEL_VERBOSE_2,
2876 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2877 &DirEntry->NameInformation.FileName,
2878 pObjectInfo->FileId.Cell,
2879 pObjectInfo->FileId.Volume,
2880 pObjectInfo->FileId.Vnode,
2881 pObjectInfo->FileId.Unique);
2883 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2886 AFSValidateDirectoryCache( pObjectInfo,
2889 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2893 // Update the metadata for the entry
2896 ntStatus = AFSUpdateMetaData( DirEntry,
2899 if( NT_SUCCESS( ntStatus))
2902 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2908 case AFS_FILE_TYPE_DFSLINK:
2911 UNICODE_STRING uniTargetName;
2914 // For a DFS link need to check the target name has not changed
2917 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
2919 uniTargetName.MaximumLength = uniTargetName.Length;
2921 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
2923 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
2926 if( DirEntry->NameInformation.TargetName.Length == 0 ||
2927 RtlCompareUnicodeString( &uniTargetName,
2928 &DirEntry->NameInformation.TargetName,
2933 // Update the target name
2936 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
2938 uniTargetName.Buffer,
2939 uniTargetName.Length);
2941 if( !NT_SUCCESS( ntStatus))
2944 AFSReleaseResource( &DirEntry->NonPaged->Lock);
2950 AFSReleaseResource( &DirEntry->NonPaged->Lock);
2953 // Update the metadata for the entry
2956 ntStatus = AFSUpdateMetaData( DirEntry,
2959 if( NT_SUCCESS( ntStatus))
2962 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2970 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2971 AFS_TRACE_LEVEL_WARNING,
2972 "AFSVerifyEntry Attempt to verify node of type %d\n",
2973 pObjectInfo->FileType);
2980 if( pDirEnumEntry != NULL)
2983 AFSExFreePool( pDirEnumEntry);
2991 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
2994 NTSTATUS ntStatus = STATUS_SUCCESS;
2995 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2996 ULONGLONG ullIndex = 0;
2997 AFSVolumeCB *pVolumeCB = NULL;
2998 AFSFcb *pFcb = NULL;
2999 AFSObjectInfoCB *pCurrentObject = NULL;
3004 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3005 AFS_TRACE_LEVEL_VERBOSE,
3006 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3007 VolumeStatus->Online,
3008 VolumeStatus->FileID.Cell,
3009 VolumeStatus->FileID.Volume);
3012 // Need to locate the Fcb for the directory to purge
3015 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3016 AFS_TRACE_LEVEL_VERBOSE,
3017 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3018 &pDevExt->Specific.RDR.VolumeTreeLock,
3019 PsGetCurrentThread());
3021 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3024 // Locate the volume node
3027 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3029 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3031 (AFSBTreeEntry **)&pVolumeCB);
3033 if( pVolumeCB != NULL)
3036 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3038 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3041 // Set the volume state accordingly
3044 if( VolumeStatus->Online)
3047 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3052 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3055 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3058 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3060 while( pCurrentObject != NULL)
3063 if( VolumeStatus->Online)
3066 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3068 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3070 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3075 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3078 pFcb = pCurrentObject->Fcb;
3081 !(VolumeStatus->Online) &&
3082 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3085 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3086 AFS_TRACE_LEVEL_ERROR,
3087 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3088 VolumeStatus->FileID.Cell,
3089 VolumeStatus->FileID.Volume);
3092 // Clear out the extents
3095 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3096 AFS_TRACE_LEVEL_VERBOSE,
3097 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3098 &pFcb->NPFcb->Specific.File.ExtentsResource,
3099 PsGetCurrentThread());
3101 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3104 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3106 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3110 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3111 AFS_TRACE_LEVEL_VERBOSE,
3112 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3113 &pFcb->NPFcb->Specific.File.ExtentsResource,
3114 PsGetCurrentThread());
3116 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3119 // And get rid of them (note this involves waiting
3120 // for any writes or reads to the cache to complete)
3123 (VOID) AFSTearDownFcbExtents( pFcb);
3126 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3129 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3131 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3136 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3144 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3147 NTSTATUS ntStatus = STATUS_SUCCESS;
3152 if( AFSGlobalRoot == NULL)
3155 try_return( ntStatus);
3158 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3162 // Set the network state according to the information
3165 if( NetworkStatus->Online)
3168 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3173 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3176 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3187 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3191 NTSTATUS ntStatus = STATUS_SUCCESS;
3192 BOOLEAN bAcquiredLock = FALSE;
3193 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3194 AFSFcb *pFcb = NULL;
3199 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3200 AFS_TRACE_LEVEL_VERBOSE,
3201 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3202 ObjectInfo->FileId.Cell,
3203 ObjectInfo->FileId.Volume,
3204 ObjectInfo->FileId.Vnode,
3205 ObjectInfo->FileId.Unique);
3207 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3210 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3211 AFS_TRACE_LEVEL_VERBOSE,
3212 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3213 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3214 PsGetCurrentThread());
3216 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3219 bAcquiredLock = TRUE;
3223 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3226 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3227 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3230 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3231 AFS_TRACE_LEVEL_ERROR,
3232 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
3233 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3234 ObjectInfo->FileId.Cell,
3235 ObjectInfo->FileId.Volume,
3236 ObjectInfo->FileId.Vnode,
3237 ObjectInfo->FileId.Unique);
3241 // Reset the directory list information by clearing all valid entries
3244 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3246 while( pCurrentDirEntry != NULL)
3249 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3251 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3255 // If this entry has been deleted then process it here
3258 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3259 pCurrentDirEntry->OpenReferenceCount == 0)
3262 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3263 AFS_TRACE_LEVEL_VERBOSE,
3264 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3266 &pCurrentDirEntry->NameInformation.FileName);
3268 AFSDeleteDirEntry( ObjectInfo,
3274 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3276 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3277 AFS_TRACE_LEVEL_VERBOSE,
3278 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3280 pCurrentDirEntry->OpenReferenceCount);
3283 // We pull the short name from the parent tree since it could change below
3286 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3289 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3290 AFS_TRACE_LEVEL_VERBOSE,
3291 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3293 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3294 &pCurrentDirEntry->NameInformation.FileName);
3296 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3299 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3304 pCurrentDirEntry = pNextDirEntry;
3308 // Reget the directory contents
3311 AFSVerifyDirectoryContent( ObjectInfo,
3315 // Now start again and tear down any entries not valid
3318 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3320 while( pCurrentDirEntry != NULL)
3323 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3325 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3328 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3329 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3332 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3335 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3337 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3338 AFS_TRACE_LEVEL_VERBOSE,
3339 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3341 &pCurrentDirEntry->NameInformation.FileName);
3343 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3348 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3351 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3352 AFS_TRACE_LEVEL_VERBOSE,
3353 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3355 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3356 &pCurrentDirEntry->NameInformation.FileName);
3360 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3362 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3363 AFS_TRACE_LEVEL_VERBOSE,
3364 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3366 &pCurrentDirEntry->NameInformation.FileName);
3371 pCurrentDirEntry = pNextDirEntry;
3376 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3377 AFS_TRACE_LEVEL_VERBOSE,
3378 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3380 pCurrentDirEntry->OpenReferenceCount);
3382 if( pCurrentDirEntry->OpenReferenceCount == 0)
3385 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3386 AFS_TRACE_LEVEL_VERBOSE,
3387 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3388 &pCurrentDirEntry->NameInformation.FileName,
3389 ObjectInfo->FileId.Cell,
3390 ObjectInfo->FileId.Volume,
3391 ObjectInfo->FileId.Vnode,
3392 ObjectInfo->FileId.Unique);
3394 AFSDeleteDirEntry( ObjectInfo,
3400 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3401 AFS_TRACE_LEVEL_VERBOSE,
3402 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3404 &pCurrentDirEntry->NameInformation.FileName,
3405 ObjectInfo->FileId.Cell,
3406 ObjectInfo->FileId.Volume,
3407 ObjectInfo->FileId.Vnode,
3408 ObjectInfo->FileId.Unique);
3410 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3412 AFSRemoveNameEntry( ObjectInfo,
3416 pCurrentDirEntry = pNextDirEntry;
3420 if( !AFSValidateDirList( ObjectInfo))
3423 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3430 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3438 AFSIsVolumeFID( IN AFSFileID *FileID)
3441 BOOLEAN bIsVolume = FALSE;
3443 if( FileID->Vnode == 1 &&
3444 FileID->Unique == 1)
3454 AFSIsFinalNode( IN AFSFcb *Fcb)
3457 BOOLEAN bIsFinalNode = FALSE;
3459 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3460 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3461 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3462 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3463 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3466 bIsFinalNode = TRUE;
3471 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3472 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3475 return bIsFinalNode;
3479 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3480 IN AFSDirEnumEntry *DirEnumEntry)
3483 NTSTATUS ntStatus = STATUS_SUCCESS;
3484 UNICODE_STRING uniTargetName;
3485 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3490 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3492 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3494 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3496 pObjectInfo->FileType = DirEnumEntry->FileType;
3498 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3500 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3502 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3504 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3506 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3508 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3510 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3512 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3513 pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3514 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3517 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3520 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3522 pObjectInfo->Links = DirEnumEntry->Links;
3524 if( DirEnumEntry->TargetNameLength > 0)
3528 // Update the target name information if needed
3531 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3533 uniTargetName.MaximumLength = uniTargetName.Length;
3535 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3537 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3540 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3541 RtlCompareUnicodeString( &uniTargetName,
3542 &DirEntry->NameInformation.TargetName,
3547 // Update the target name
3550 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3552 uniTargetName.Buffer,
3553 uniTargetName.Length);
3555 if( !NT_SUCCESS( ntStatus))
3558 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3560 try_return( ntStatus);
3564 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3566 else if( DirEntry->NameInformation.TargetName.Length > 0)
3569 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3572 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3573 DirEntry->NameInformation.TargetName.Buffer != NULL)
3575 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
3578 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3580 DirEntry->NameInformation.TargetName.Length = 0;
3581 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3582 DirEntry->NameInformation.TargetName.Buffer = NULL;
3584 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3596 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3598 IN BOOLEAN PurgeContent,
3599 IN BOOLEAN FastCall)
3602 NTSTATUS ntStatus = STATUS_SUCCESS;
3603 LARGE_INTEGER liSystemTime;
3604 AFSDirEnumEntry *pDirEnumEntry = NULL;
3605 AFSFcb *pCurrentFcb = NULL;
3606 BOOLEAN bReleaseFcb = FALSE;
3607 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3613 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3617 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3618 AFS_TRACE_LEVEL_VERBOSE_2,
3619 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3620 &DirEntry->NameInformation.FileName,
3621 pObjectInfo->FileId.Cell,
3622 pObjectInfo->FileId.Volume,
3623 pObjectInfo->FileId.Vnode,
3624 pObjectInfo->FileId.Unique);
3627 // If this is a fake node then bail since the service knows nothing about it
3630 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3633 try_return( ntStatus);
3637 pObjectInfo->Fcb != NULL)
3640 pCurrentFcb = pObjectInfo->Fcb;
3642 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3645 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3646 AFS_TRACE_LEVEL_VERBOSE,
3647 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3648 &pCurrentFcb->NPFcb->Resource,
3649 PsGetCurrentThread());
3651 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3659 // This routine ensures that the current entry is valid by:
3661 // 1) Checking that the expiration time is non-zero and after where we
3665 KeQuerySystemTime( &liSystemTime);
3667 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3668 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3669 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3670 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3673 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3674 AFS_TRACE_LEVEL_VERBOSE_2,
3675 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3676 &DirEntry->NameInformation.FileName,
3677 pObjectInfo->FileId.Cell,
3678 pObjectInfo->FileId.Volume,
3679 pObjectInfo->FileId.Vnode,
3680 pObjectInfo->FileId.Unique);
3682 try_return( ntStatus);
3686 // This node requires updating
3689 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3694 if( !NT_SUCCESS( ntStatus))
3697 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3698 AFS_TRACE_LEVEL_ERROR,
3699 "AFSValidateEntry Failed to evaluate entry %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3700 &DirEntry->NameInformation.FileName,
3701 pObjectInfo->FileId.Cell,
3702 pObjectInfo->FileId.Volume,
3703 pObjectInfo->FileId.Vnode,
3704 pObjectInfo->FileId.Unique,
3708 // Failed validation of node so return access-denied
3711 try_return( ntStatus);
3714 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3715 AFS_TRACE_LEVEL_VERBOSE,
3716 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3717 &DirEntry->NameInformation.FileName,
3718 pObjectInfo->FileId.Cell,
3719 pObjectInfo->FileId.Volume,
3720 pObjectInfo->FileId.Vnode,
3721 pObjectInfo->FileId.Unique,
3722 pObjectInfo->DataVersion.QuadPart,
3723 pDirEnumEntry->DataVersion.QuadPart,
3724 pDirEnumEntry->FileType);
3728 // Based on the file type, process the node
3731 switch( pDirEnumEntry->FileType)
3734 case AFS_FILE_TYPE_MOUNTPOINT:
3738 // Update the metadata for the entry
3741 ntStatus = AFSUpdateMetaData( DirEntry,
3744 if( NT_SUCCESS( ntStatus))
3747 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3753 case AFS_FILE_TYPE_SYMLINK:
3754 case AFS_FILE_TYPE_DFSLINK:
3758 // Update the metadata for the entry
3761 ntStatus = AFSUpdateMetaData( DirEntry,
3764 if( NT_SUCCESS( ntStatus))
3767 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3773 case AFS_FILE_TYPE_FILE:
3777 // For a file where the data version has become invalid we need to
3778 // fail any current extent requests and purge the cache for the file
3779 // Can't hold the Fcb resource while doing this
3782 if( pCurrentFcb != NULL &&
3783 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3784 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3787 IO_STATUS_BLOCK stIoStatus;
3788 BOOLEAN bPurgeExtents = FALSE;
3790 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3791 AFS_TRACE_LEVEL_VERBOSE_2,
3792 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3793 &DirEntry->NameInformation.FileName,
3794 pObjectInfo->FileId.Cell,
3795 pObjectInfo->FileId.Volume,
3796 pObjectInfo->FileId.Vnode,
3797 pObjectInfo->FileId.Unique);
3799 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3801 bPurgeExtents = TRUE;
3803 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3804 AFS_TRACE_LEVEL_VERBOSE,
3805 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3806 &DirEntry->NameInformation.FileName,
3807 pObjectInfo->FileId.Cell,
3808 pObjectInfo->FileId.Volume,
3809 pObjectInfo->FileId.Vnode,
3810 pObjectInfo->FileId.Unique);
3812 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3818 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
3823 if( !NT_SUCCESS( stIoStatus.Status))
3826 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3827 AFS_TRACE_LEVEL_ERROR,
3828 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3829 &DirEntry->NameInformation.FileName,
3830 pObjectInfo->FileId.Cell,
3831 pObjectInfo->FileId.Volume,
3832 pObjectInfo->FileId.Vnode,
3833 pObjectInfo->FileId.Unique,
3835 stIoStatus.Information);
3837 ntStatus = stIoStatus.Status;
3843 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3849 __except( EXCEPTION_EXECUTE_HANDLER)
3851 ntStatus = GetExceptionCode();
3853 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3854 AFS_TRACE_LEVEL_ERROR,
3855 "AFSValidateEntry CcFlushCache or CcPurgeCacheSection exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3856 &DirEntry->NameInformation.FileName,
3857 pObjectInfo->FileId.Cell,
3858 pObjectInfo->FileId.Volume,
3859 pObjectInfo->FileId.Vnode,
3860 pObjectInfo->FileId.Unique,
3865 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3869 AFSFlushExtents( pCurrentFcb);
3873 // Reacquire the Fcb to purge the cache
3876 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3877 AFS_TRACE_LEVEL_VERBOSE,
3878 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3879 &pCurrentFcb->NPFcb->Resource,
3880 PsGetCurrentThread());
3882 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3887 // Update the metadata for the entry
3890 ntStatus = AFSUpdateMetaData( DirEntry,
3893 if( !NT_SUCCESS( ntStatus))
3896 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3897 AFS_TRACE_LEVEL_ERROR,
3898 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3899 &DirEntry->NameInformation.FileName,
3900 pObjectInfo->FileId.Cell,
3901 pObjectInfo->FileId.Volume,
3902 pObjectInfo->FileId.Vnode,
3903 pObjectInfo->FileId.Unique,
3909 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3912 // Update file sizes
3915 if( pObjectInfo->Fcb != NULL)
3917 FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3919 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3920 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3921 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3923 if ( pCCFileObject != NULL)
3925 CcSetFileSizes( pCCFileObject,
3926 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3933 case AFS_FILE_TYPE_DIRECTORY:
3936 AFSDirectoryCB *pCurrentDirEntry = NULL;
3938 if( pCurrentFcb != NULL &&
3939 pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3943 // For a directory or root entry flush the content of
3944 // the directory enumeration.
3947 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3948 AFS_TRACE_LEVEL_VERBOSE,
3949 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3950 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3951 PsGetCurrentThread());
3953 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3956 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3957 AFS_TRACE_LEVEL_VERBOSE_2,
3958 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3959 &DirEntry->NameInformation.FileName,
3960 pObjectInfo->FileId.Cell,
3961 pObjectInfo->FileId.Volume,
3962 pObjectInfo->FileId.Vnode,
3963 pObjectInfo->FileId.Unique);
3965 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3968 AFSValidateDirectoryCache( pCurrentFcb->ObjectInformation,
3971 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3974 if( !NT_SUCCESS( ntStatus))
3977 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3978 AFS_TRACE_LEVEL_ERROR,
3979 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3980 &DirEntry->NameInformation.FileName,
3981 pObjectInfo->FileId.Cell,
3982 pObjectInfo->FileId.Volume,
3983 pObjectInfo->FileId.Vnode,
3984 pObjectInfo->FileId.Unique,
3992 // Update the metadata for the entry
3995 ntStatus = AFSUpdateMetaData( DirEntry,
3998 if( NT_SUCCESS( ntStatus))
4001 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4009 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4010 AFS_TRACE_LEVEL_WARNING,
4011 "AFSValidateEntry Attempt to verify node of type %d\n",
4012 pObjectInfo->FileType);
4022 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4025 if( pDirEnumEntry != NULL)
4028 AFSExFreePool( pDirEnumEntry);
4036 AFSInitializeSpecialShareNameList()
4039 NTSTATUS ntStatus = STATUS_SUCCESS;
4040 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4041 AFSObjectInfoCB *pObjectInfoCB = NULL;
4042 UNICODE_STRING uniShareName;
4043 ULONG ulEntryLength = 0;
4044 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4049 RtlInitUnicodeString( &uniShareName,
4052 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4055 if( pObjectInfoCB == NULL)
4058 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4061 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4062 AFS_TRACE_LEVEL_VERBOSE,
4063 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
4066 pObjectInfoCB->ObjectReferenceCount = 1;
4068 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4070 ulEntryLength = sizeof( AFSDirectoryCB) +
4071 uniShareName.Length;
4073 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4077 if( pDirNode == NULL)
4080 AFSDeleteObjectInfo( pObjectInfoCB);
4082 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4085 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4086 sizeof( AFSNonPagedDirectoryCB),
4087 AFS_DIR_ENTRY_NP_TAG);
4089 if( pNonPagedDirEntry == NULL)
4092 ExFreePool( pDirNode);
4094 AFSDeleteObjectInfo( pObjectInfoCB);
4096 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4099 RtlZeroMemory( pDirNode,
4102 RtlZeroMemory( pNonPagedDirEntry,
4103 sizeof( AFSNonPagedDirectoryCB));
4105 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4107 pDirNode->NonPaged = pNonPagedDirEntry;
4109 pDirNode->ObjectInformation = pObjectInfoCB;
4115 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
4117 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4119 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4121 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4123 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4124 uniShareName.Buffer,
4125 pDirNode->NameInformation.FileName.Length);
4127 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4130 AFSSpecialShareNames = pDirNode;
4132 pLastDirNode = pDirNode;
4134 RtlInitUnicodeString( &uniShareName,
4137 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4140 if( pObjectInfoCB == NULL)
4143 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4146 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4147 AFS_TRACE_LEVEL_VERBOSE,
4148 "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
4151 pObjectInfoCB->ObjectReferenceCount = 1;
4153 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4155 ulEntryLength = sizeof( AFSDirectoryCB) +
4156 uniShareName.Length;
4158 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4162 if( pDirNode == NULL)
4165 AFSDeleteObjectInfo( pObjectInfoCB);
4167 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4170 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4171 sizeof( AFSNonPagedDirectoryCB),
4172 AFS_DIR_ENTRY_NP_TAG);
4174 if( pNonPagedDirEntry == NULL)
4177 ExFreePool( pDirNode);
4179 AFSDeleteObjectInfo( pObjectInfoCB);
4181 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4184 RtlZeroMemory( pDirNode,
4187 RtlZeroMemory( pNonPagedDirEntry,
4188 sizeof( AFSNonPagedDirectoryCB));
4190 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4192 pDirNode->NonPaged = pNonPagedDirEntry;
4194 pDirNode->ObjectInformation = pObjectInfoCB;
4200 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
4202 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4204 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4206 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4208 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4209 uniShareName.Buffer,
4210 pDirNode->NameInformation.FileName.Length);
4212 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4215 pLastDirNode->ListEntry.fLink = pDirNode;
4217 pDirNode->ListEntry.bLink = pLastDirNode;
4219 pLastDirNode = pDirNode;
4221 RtlInitUnicodeString( &uniShareName,
4224 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4227 if( pObjectInfoCB == NULL)
4230 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4233 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4234 AFS_TRACE_LEVEL_VERBOSE,
4235 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4238 pObjectInfoCB->ObjectReferenceCount = 1;
4240 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4242 ulEntryLength = sizeof( AFSDirectoryCB) +
4243 uniShareName.Length;
4245 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4249 if( pDirNode == NULL)
4252 AFSDeleteObjectInfo( pObjectInfoCB);
4254 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4257 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4258 sizeof( AFSNonPagedDirectoryCB),
4259 AFS_DIR_ENTRY_NP_TAG);
4261 if( pNonPagedDirEntry == NULL)
4264 ExFreePool( pDirNode);
4266 AFSDeleteObjectInfo( pObjectInfoCB);
4268 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4271 RtlZeroMemory( pDirNode,
4274 RtlZeroMemory( pNonPagedDirEntry,
4275 sizeof( AFSNonPagedDirectoryCB));
4277 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4279 pDirNode->NonPaged = pNonPagedDirEntry;
4281 pDirNode->ObjectInformation = pObjectInfoCB;
4287 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4289 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4291 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4293 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4295 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4296 uniShareName.Buffer,
4297 pDirNode->NameInformation.FileName.Length);
4299 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4302 pLastDirNode->ListEntry.fLink = pDirNode;
4304 pDirNode->ListEntry.bLink = pLastDirNode;
4308 if( !NT_SUCCESS( ntStatus))
4311 if( AFSSpecialShareNames != NULL)
4314 pDirNode = AFSSpecialShareNames;
4316 while( pDirNode != NULL)
4319 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4321 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4323 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4325 ExFreePool( pDirNode->NonPaged);
4327 ExFreePool( pDirNode);
4329 pDirNode = pLastDirNode;
4332 AFSSpecialShareNames = NULL;
4341 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4342 IN UNICODE_STRING *SecondaryName)
4345 AFSDirectoryCB *pDirectoryCB = NULL;
4346 ULONGLONG ullHash = 0;
4347 UNICODE_STRING uniFullShareName;
4353 // Build up the entire name here. We are guaranteed that if there is a
4354 // secondary name, it is pointing to a portion of the share name buffer
4357 if( SecondaryName->Length > 0 &&
4358 SecondaryName->Buffer != NULL)
4361 uniFullShareName = *SecondaryName;
4364 // The calling routine strips off the leading slash so add it back in
4367 uniFullShareName.Buffer--;
4368 uniFullShareName.Length += sizeof( WCHAR);
4369 uniFullShareName.MaximumLength += sizeof( WCHAR);
4372 // And the share name
4375 uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
4376 uniFullShareName.Length += ShareName->Length;
4377 uniFullShareName.MaximumLength += ShareName->Length;
4382 uniFullShareName = *ShareName;
4386 // Generate our hash value
4389 ullHash = AFSGenerateCRC( &uniFullShareName,
4393 // Loop through our special share names to see if this is one of them
4396 pDirectoryCB = AFSSpecialShareNames;
4398 while( pDirectoryCB != NULL)
4401 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4407 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4411 return pDirectoryCB;
4415 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4419 // Block on the queue flush event
4422 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4432 AFSWaitOnQueuedReleases()
4435 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4438 // Block on the queue flush event
4441 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4451 AFSIsEqualFID( IN AFSFileID *FileId1,
4452 IN AFSFileID *FileId2)
4455 BOOLEAN bIsEqual = FALSE;
4457 if( FileId1->Unique == FileId2->Unique &&
4458 FileId1->Vnode == FileId2->Vnode &&
4459 FileId1->Volume == FileId2->Volume &&
4460 FileId1->Cell == FileId2->Cell)
4470 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4473 NTSTATUS ntStatus = STATUS_SUCCESS;
4474 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4479 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4482 // Reset the directory list information
4485 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4487 while( pCurrentDirEntry != NULL)
4490 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4492 if( pCurrentDirEntry->OpenReferenceCount == 0)
4495 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4496 AFS_TRACE_LEVEL_VERBOSE,
4497 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4499 &pCurrentDirEntry->NameInformation.FileName);
4501 AFSDeleteDirEntry( ObjectInfoCB,
4507 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4508 AFS_TRACE_LEVEL_VERBOSE,
4509 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4511 &pCurrentDirEntry->NameInformation.FileName);
4513 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4515 AFSRemoveNameEntry( ObjectInfoCB,
4519 pCurrentDirEntry = pNextDirEntry;
4522 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4524 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4526 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4528 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4530 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4532 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4534 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4535 AFS_TRACE_LEVEL_VERBOSE,
4536 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4537 ObjectInfoCB->FileId.Cell,
4538 ObjectInfoCB->FileId.Volume,
4539 ObjectInfoCB->FileId.Vnode,
4540 ObjectInfoCB->FileId.Unique);
4547 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4550 NTSTATUS ntStatus = STATUS_SUCCESS;
4551 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4552 UNICODE_STRING uniFullName;
4557 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4558 AFS_TRACE_LEVEL_VERBOSE,
4559 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4560 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4561 PsGetCurrentThread());
4563 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4566 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4569 try_return( ntStatus);
4573 // Initialize the root information
4576 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4579 // Enumerate the shares in the volume
4582 ntStatus = AFSEnumerateDirectory( AuthGroup,
4583 &AFSGlobalRoot->ObjectInformation,
4586 if( !NT_SUCCESS( ntStatus))
4589 try_return( ntStatus);
4592 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4595 // Indicate the node is initialized
4598 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4600 uniFullName.MaximumLength = PAGE_SIZE;
4601 uniFullName.Length = 0;
4603 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4604 uniFullName.MaximumLength,
4605 AFS_GENERIC_MEMORY_12_TAG);
4607 if( uniFullName.Buffer == NULL)
4611 // Reset the directory content
4614 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4616 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4618 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4622 // Populate our list of entries in the NP enumeration list
4625 while( pDirGlobalDirNode != NULL)
4628 uniFullName.Buffer[ 0] = L'\\';
4629 uniFullName.Buffer[ 1] = L'\\';
4631 uniFullName.Length = 2 * sizeof( WCHAR);
4633 RtlCopyMemory( &uniFullName.Buffer[ 2],
4634 AFSServerName.Buffer,
4635 AFSServerName.Length);
4637 uniFullName.Length += AFSServerName.Length;
4639 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4641 uniFullName.Length += sizeof( WCHAR);
4643 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4644 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4645 pDirGlobalDirNode->NameInformation.FileName.Length);
4647 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4649 AFSAddConnectionEx( &uniFullName,
4650 RESOURCEDISPLAYTYPE_SHARE,
4653 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4656 AFSExFreePool( uniFullName.Buffer);
4660 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4667 AFSIsRelativeName( IN UNICODE_STRING *Name)
4670 BOOLEAN bIsRelative = FALSE;
4672 if( Name->Buffer[ 0] != L'\\')
4682 AFSUpdateName( IN UNICODE_STRING *Name)
4687 while( usIndex < Name->Length/sizeof( WCHAR))
4690 if( Name->Buffer[ usIndex] == L'/')
4693 Name->Buffer[ usIndex] = L'\\';
4703 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4704 IN OUT ULONG *Flags,
4705 IN WCHAR *NameBuffer,
4706 IN USHORT NameLength)
4709 NTSTATUS ntStatus = STATUS_SUCCESS;
4710 WCHAR *pTmpBuffer = NULL;
4716 // If we have enough space then just move in the name otherwise
4717 // allocate a new buffer
4720 if( TargetName->Length < NameLength)
4723 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4725 AFS_NAME_BUFFER_FIVE_TAG);
4727 if( pTmpBuffer == NULL)
4730 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4733 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4736 AFSExFreePool( TargetName->Buffer);
4739 TargetName->MaximumLength = NameLength;
4741 TargetName->Buffer = pTmpBuffer;
4743 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4746 TargetName->Length = NameLength;
4748 RtlCopyMemory( TargetName->Buffer,
4750 TargetName->Length);
4753 // Update the name in the buffer
4756 AFSUpdateName( TargetName);
4767 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4768 IN ULONG InitialElementCount)
4771 AFSNameArrayHdr *pNameArray = NULL;
4772 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4777 if( InitialElementCount == 0)
4780 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
4783 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
4784 sizeof( AFSNameArrayHdr) +
4785 (InitialElementCount * sizeof( AFSNameArrayCB)),
4786 AFS_NAME_ARRAY_TAG);
4788 if( pNameArray == NULL)
4791 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4792 AFS_TRACE_LEVEL_ERROR,
4793 "AFSInitNameArray Failed to allocate name array\n");
4795 try_return( pNameArray);
4798 RtlZeroMemory( pNameArray,
4799 sizeof( AFSNameArrayHdr) +
4800 (InitialElementCount * sizeof( AFSNameArrayCB)));
4802 pNameArray->MaxElementCount = InitialElementCount;
4804 if( DirectoryCB != NULL)
4807 pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
4809 InterlockedIncrement( &pNameArray->Count);
4811 InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
4813 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4814 AFS_TRACE_LEVEL_VERBOSE,
4815 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
4816 &DirectoryCB->NameInformation.FileName,
4818 DirectoryCB->OpenReferenceCount);
4820 pNameArray->CurrentEntry->DirectoryCB = DirectoryCB;
4822 pNameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
4824 pNameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
4836 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
4837 IN UNICODE_STRING *Path,
4838 IN AFSDirectoryCB *DirectoryCB)
4841 NTSTATUS ntStatus = STATUS_SUCCESS;
4842 AFSNameArrayCB *pCurrentElement = NULL;
4843 UNICODE_STRING uniComponentName, uniRemainingPath;
4844 AFSObjectInfoCB *pCurrentObject = NULL;
4845 ULONG ulTotalCount = 0;
4847 USHORT usLength = 0;
4853 // Init some info in the header
4856 pCurrentElement = &NameArray->ElementArray[ 0];
4858 NameArray->CurrentEntry = pCurrentElement;
4861 // The first entry points at the root
4864 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
4866 InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4868 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4869 AFS_TRACE_LEVEL_VERBOSE,
4870 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
4871 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4872 pCurrentElement->DirectoryCB,
4873 pCurrentElement->DirectoryCB->OpenReferenceCount);
4875 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
4877 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
4879 NameArray->Count = 1;
4881 NameArray->LinkCount = 0;
4884 // If the root is the parent then we are done ...
4887 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
4889 try_return( ntStatus);
4901 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
4902 IN AFSNameArrayHdr *RelatedNameArray,
4903 IN AFSDirectoryCB *DirectoryCB)
4906 NTSTATUS ntStatus = STATUS_SUCCESS;
4907 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
4908 UNICODE_STRING uniComponentName, uniRemainingPath;
4909 AFSObjectInfoCB *pObjectInfo = NULL;
4910 ULONG ulTotalCount = 0;
4912 USHORT usLength = 0;
4918 // Init some info in the header
4921 pCurrentElement = &NameArray->ElementArray[ 0];
4923 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
4925 NameArray->Count = 0;
4927 NameArray->LinkCount = RelatedNameArray->LinkCount;
4930 // Populate the name array with the data from the related array
4936 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
4938 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
4940 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
4942 InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4944 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4945 AFS_TRACE_LEVEL_VERBOSE,
4946 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
4947 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4948 pCurrentElement->DirectoryCB,
4949 pCurrentElement->DirectoryCB->OpenReferenceCount);
4951 InterlockedIncrement( &NameArray->Count);
4953 if( pCurrentElement->DirectoryCB == DirectoryCB ||
4954 NameArray->Count == RelatedNameArray->Count)
4966 pCurrentRelatedElement++;
4969 if( NameArray->Count > 0)
4971 NameArray->CurrentEntry = pCurrentElement;
4979 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
4982 NTSTATUS ntStatus = STATUS_SUCCESS;
4983 AFSNameArrayCB *pCurrentElement = NULL;
4988 pCurrentElement = &NameArray->ElementArray[ 0];
4993 if( pCurrentElement->DirectoryCB == NULL)
4999 InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5001 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5002 AFS_TRACE_LEVEL_VERBOSE,
5003 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
5004 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5005 pCurrentElement->DirectoryCB,
5006 pCurrentElement->DirectoryCB->OpenReferenceCount);
5011 AFSExFreePool( NameArray);
5018 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5019 IN AFSDirectoryCB *DirEntry)
5022 NTSTATUS ntStatus = STATUS_SUCCESS;
5023 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5028 if( NameArray->Count == NameArray->MaxElementCount)
5031 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5034 if( NameArray->CurrentEntry != NULL &&
5035 NameArray->CurrentEntry->DirectoryCB == DirEntry)
5038 try_return( ntStatus);
5041 if( NameArray->Count > 0)
5044 NameArray->CurrentEntry++;
5048 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5051 InterlockedIncrement( &NameArray->Count);
5053 InterlockedIncrement( &DirEntry->OpenReferenceCount);
5055 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5056 AFS_TRACE_LEVEL_VERBOSE,
5057 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
5058 &DirEntry->NameInformation.FileName,
5060 DirEntry->OpenReferenceCount);
5062 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5064 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5066 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5077 AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
5078 IN AFSDirectoryCB *DirectoryCB)
5081 ASSERT( NameArray->CurrentEntry != NULL);
5083 InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5085 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5086 AFS_TRACE_LEVEL_VERBOSE,
5087 "AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
5088 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5089 NameArray->CurrentEntry->DirectoryCB,
5090 NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5092 InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5094 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5095 AFS_TRACE_LEVEL_VERBOSE,
5096 "AFSReplaceCurrentElement Increment count on %wZ DE %p Cnt %d\n",
5097 &DirectoryCB->NameInformation.FileName,
5099 DirectoryCB->OpenReferenceCount);
5101 NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
5103 NameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
5105 NameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
5107 if( DirectoryCB->ObjectInformation->ParentObjectInformation == NULL)
5110 SetFlag( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5117 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5120 AFSDirectoryCB *pCurrentDirEntry = NULL;
5125 if( NameArray->Count == 0)
5127 try_return( pCurrentDirEntry);
5130 InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5132 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5133 AFS_TRACE_LEVEL_VERBOSE,
5134 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5135 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5136 NameArray->CurrentEntry->DirectoryCB,
5137 NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5139 NameArray->CurrentEntry->DirectoryCB = NULL;
5141 if( InterlockedDecrement( &NameArray->Count) == 0)
5143 NameArray->CurrentEntry = NULL;
5147 NameArray->CurrentEntry--;
5148 pCurrentDirEntry = NameArray->CurrentEntry->DirectoryCB;
5156 return pCurrentDirEntry;
5160 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5163 AFSDirectoryCB *pDirEntry = NULL;
5164 AFSNameArrayCB *pElement = NULL;
5169 if( NameArray->Count == 0 ||
5170 NameArray->Count == 1)
5173 try_return( pDirEntry = NULL);
5176 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5178 pDirEntry = pElement->DirectoryCB;
5189 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5190 IN AFSDirectoryCB *DirEntry)
5193 AFSNameArrayCB *pCurrentElement = NULL;
5194 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5199 pCurrentElement = &NameArray->ElementArray[ 0];
5204 if( pCurrentElement->DirectoryCB == NULL)
5210 InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5212 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5213 AFS_TRACE_LEVEL_VERBOSE,
5214 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5215 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5216 pCurrentElement->DirectoryCB,
5217 pCurrentElement->DirectoryCB->OpenReferenceCount);
5222 RtlZeroMemory( NameArray,
5223 sizeof( AFSNameArrayHdr) +
5224 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5226 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5228 if( DirEntry != NULL)
5231 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5233 InterlockedIncrement( &NameArray->Count);
5235 InterlockedIncrement( &DirEntry->OpenReferenceCount);
5237 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5238 AFS_TRACE_LEVEL_VERBOSE,
5239 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5240 &DirEntry->NameInformation.FileName,
5242 DirEntry->OpenReferenceCount);
5244 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5246 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5248 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5256 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5259 AFSNameArrayCB *pCurrentElement = NULL;
5261 pCurrentElement = &NameArray->ElementArray[ 0];
5263 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5265 while( pCurrentElement->DirectoryCB != NULL)
5268 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5269 pCurrentElement->FileId.Cell,
5270 pCurrentElement->FileId.Volume,
5271 pCurrentElement->FileId.Vnode,
5272 pCurrentElement->FileId.Unique,
5273 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5278 AFSPrint("AFSDumpNameArray End\n\n");
5284 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5288 // Depending on the type of node, set the event
5291 switch( Fcb->Header.NodeTypeCode)
5294 case AFS_DIRECTORY_FCB:
5297 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5301 InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5310 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5314 InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5324 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5328 // Depending on the type of node, set the event
5331 switch( Fcb->Header.NodeTypeCode)
5334 case AFS_DIRECTORY_FCB:
5337 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5339 if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
5342 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5352 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5354 if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
5357 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5368 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5371 BOOLEAN bIsInProcess = FALSE;
5376 if( ObjectInfo->Fcb == NULL)
5379 try_return( bIsInProcess);
5383 // Depending on the type of node, set the event
5386 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5389 case AFS_DIRECTORY_FCB:
5392 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5395 bIsInProcess = TRUE;
5405 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5408 bIsInProcess = TRUE;
5420 return bIsInProcess;
5424 AFSVerifyVolume( IN ULONGLONG ProcessId,
5425 IN AFSVolumeCB *VolumeCB)
5428 NTSTATUS ntStatus = STATUS_SUCCESS;
5435 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5438 NTSTATUS ntStatus = STATUS_SUCCESS;
5439 AFSObjectInfoCB *pObjectInfoCB = NULL;
5440 AFSDirectoryCB *pDirNode = NULL;
5441 ULONG ulEntryLength = 0;
5442 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5447 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5450 if( pObjectInfoCB == NULL)
5453 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5456 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5457 AFS_TRACE_LEVEL_VERBOSE,
5458 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5461 pObjectInfoCB->ObjectReferenceCount = 1;
5463 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5465 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5467 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5469 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5473 if( pDirNode == NULL)
5476 AFSDeleteObjectInfo( pObjectInfoCB);
5478 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5481 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5482 sizeof( AFSNonPagedDirectoryCB),
5483 AFS_DIR_ENTRY_NP_TAG);
5485 if( pNonPagedDirEntry == NULL)
5488 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5491 RtlZeroMemory( pDirNode,
5494 RtlZeroMemory( pNonPagedDirEntry,
5495 sizeof( AFSNonPagedDirectoryCB));
5497 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5499 pDirNode->NonPaged = pNonPagedDirEntry;
5501 pDirNode->ObjectInformation = pObjectInfoCB;
5503 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5509 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5511 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5513 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5515 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5517 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5518 AFSPIOCtlName.Buffer,
5519 pDirNode->NameInformation.FileName.Length);
5521 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5524 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB = pDirNode;
5528 if ( !NT_SUCCESS( ntStatus))
5531 if ( pDirNode != NULL)
5534 AFSExFreePool( pDirNode);
5537 if ( pObjectInfoCB != NULL)
5540 AFSDeleteObjectInfo( pObjectInfoCB);
5549 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5550 IN AFSDirectoryCB *DirectoryCB,
5551 IN UNICODE_STRING *ParentPathName,
5552 IN AFSNameArrayHdr *RelatedNameArray,
5553 OUT AFSFileInfoCB *FileInfo)
5556 NTSTATUS ntStatus = STATUS_SUCCESS;
5557 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
5558 UNICODE_STRING uniFullPathName;
5559 AFSNameArrayHdr *pNameArray = NULL;
5560 AFSVolumeCB *pVolumeCB = NULL;
5561 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5562 WCHAR *pwchBuffer = NULL;
5563 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5564 ULONG ulNameDifference = 0;
5565 GUID *pAuthGroup = NULL;
5571 // Retrieve a target name for the entry
5574 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5577 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5580 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5582 if( ParentDirectoryCB->ObjectInformation->Fcb != NULL)
5584 pAuthGroup = &ParentDirectoryCB->ObjectInformation->Fcb->AuthGroup;
5586 else if( DirectoryCB->ObjectInformation->Fcb != NULL)
5588 pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
5591 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5596 if( !NT_SUCCESS( ntStatus) ||
5597 pDirEntry->TargetNameLength == 0)
5600 if( pDirEntry != NULL)
5603 ntStatus = STATUS_ACCESS_DENIED;
5606 try_return( ntStatus);
5609 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5612 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5616 // Update the target name
5619 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5620 &DirectoryCB->Flags,
5621 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5622 (USHORT)pDirEntry->TargetNameLength);
5624 if( !NT_SUCCESS( ntStatus))
5627 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5629 try_return( ntStatus);
5633 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5637 // Need to pass the full path in for parsing.
5640 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5643 uniFullPathName.Length = 0;
5644 uniFullPathName.MaximumLength = ParentPathName->Length +
5646 DirectoryCB->NameInformation.TargetName.Length;
5648 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5649 uniFullPathName.MaximumLength,
5650 AFS_NAME_BUFFER_SIX_TAG);
5652 if( uniFullPathName.Buffer == NULL)
5655 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5657 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5660 pwchBuffer = uniFullPathName.Buffer;
5662 RtlZeroMemory( uniFullPathName.Buffer,
5663 uniFullPathName.MaximumLength);
5665 RtlCopyMemory( uniFullPathName.Buffer,
5666 ParentPathName->Buffer,
5667 ParentPathName->Length);
5669 uniFullPathName.Length = ParentPathName->Length;
5671 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5672 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5675 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5677 uniFullPathName.Length += sizeof( WCHAR);
5680 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5681 DirectoryCB->NameInformation.TargetName.Buffer,
5682 DirectoryCB->NameInformation.TargetName.Length);
5684 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5686 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5687 uniParsedName.MaximumLength = uniParsedName.Length;
5689 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5691 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5694 // We populate up to the current parent
5697 if( RelatedNameArray != NULL)
5700 pNameArray = AFSInitNameArray( NULL,
5701 RelatedNameArray->MaxElementCount);
5703 if( pNameArray == NULL)
5706 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5709 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5716 pNameArray = AFSInitNameArray( NULL,
5719 if( pNameArray == NULL)
5722 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5725 ntStatus = AFSPopulateNameArray( pNameArray,
5730 if( !NT_SUCCESS( ntStatus))
5733 try_return( ntStatus);
5736 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5738 AFSAcquireShared( pVolumeCB->VolumeLock,
5741 pParentDirEntry = ParentDirectoryCB;
5746 uniFullPathName.Length = 0;
5747 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5749 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5750 uniFullPathName.MaximumLength,
5751 AFS_NAME_BUFFER_SEVEN_TAG);
5753 if( uniFullPathName.Buffer == NULL)
5756 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5758 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5761 pwchBuffer = uniFullPathName.Buffer;
5763 RtlZeroMemory( uniFullPathName.Buffer,
5764 uniFullPathName.MaximumLength);
5766 RtlCopyMemory( uniFullPathName.Buffer,
5767 DirectoryCB->NameInformation.TargetName.Buffer,
5768 DirectoryCB->NameInformation.TargetName.Length);
5770 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5773 // This name should begin with the \afs server so parse it off and check it
5776 FsRtlDissectName( uniFullPathName,
5780 if( RtlCompareUnicodeString( &uniComponentName,
5785 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5787 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5788 AFS_TRACE_LEVEL_ERROR,
5789 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5792 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5795 uniFullPathName = uniRemainingPath;
5797 uniParsedName = uniFullPathName;
5799 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5801 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5807 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5810 if( pNameArray == NULL)
5813 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5816 pVolumeCB = AFSGlobalRoot;
5818 AFSAcquireShared( pVolumeCB->VolumeLock,
5821 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5825 // Increment the ref count on the volume and dir entry for correct processing below
5828 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
5830 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5831 AFS_TRACE_LEVEL_VERBOSE,
5832 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
5834 pVolumeCB->VolumeReferenceCount);
5836 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
5838 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5839 AFS_TRACE_LEVEL_VERBOSE,
5840 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5841 &pParentDirEntry->NameInformation.FileName,
5844 pParentDirEntry->OpenReferenceCount);
5846 ntStatus = AFSLocateNameEntry( NULL,
5851 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5857 if( !NT_SUCCESS( ntStatus))
5861 // The volume lock was released on failure above
5862 // Except for STATUS_OBJECT_NAME_NOT_FOUND
5865 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
5868 if( pVolumeCB != NULL)
5871 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5873 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5874 AFS_TRACE_LEVEL_VERBOSE,
5875 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
5877 pVolumeCB->VolumeReferenceCount);
5879 AFSReleaseResource( pVolumeCB->VolumeLock);
5882 if( pDirectoryEntry != NULL)
5885 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5887 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5888 AFS_TRACE_LEVEL_VERBOSE,
5889 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5890 &pDirectoryEntry->NameInformation.FileName,
5893 pDirectoryEntry->OpenReferenceCount);
5898 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
5900 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5901 AFS_TRACE_LEVEL_VERBOSE,
5902 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5903 &pParentDirEntry->NameInformation.FileName,
5906 pParentDirEntry->OpenReferenceCount);
5912 try_return( ntStatus);
5916 // Store off the information
5919 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5922 // Check for the mount point being returned
5925 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
5928 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5930 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
5931 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5934 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5937 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5939 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5941 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5943 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5945 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5947 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5950 // Remove the reference made above
5953 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5955 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5956 AFS_TRACE_LEVEL_VERBOSE,
5957 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
5958 &pDirectoryEntry->NameInformation.FileName,
5961 pDirectoryEntry->OpenReferenceCount);
5965 if( pDirEntry != NULL)
5968 AFSExFreePool( pDirEntry);
5971 if( pVolumeCB != NULL)
5974 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5976 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5977 AFS_TRACE_LEVEL_VERBOSE,
5978 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
5980 pVolumeCB->VolumeReferenceCount);
5982 AFSReleaseResource( pVolumeCB->VolumeLock);
5985 if( pNameArray != NULL)
5988 AFSFreeNameArray( pNameArray);
5991 if( pwchBuffer != NULL)
5995 // Always free the buffer that we allocated as AFSLocateNameEntry
5996 // will not free it. If uniFullPathName.Buffer was allocated by
5997 // AFSLocateNameEntry, then we must free that as well.
5998 // Check that the uniFullPathName.Buffer in the string is not the same
5999 // offset by the length of the server name
6002 if( uniFullPathName.Length > 0 &&
6003 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6006 AFSExFreePool( uniFullPathName.Buffer);
6009 AFSExFreePool( pwchBuffer);
6017 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6018 IN ULONGLONG HashIndex)
6021 NTSTATUS ntStatus = STATUS_SUCCESS;
6022 AFSObjectInfoCB *pObjectInfo = NULL;
6027 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6028 sizeof( AFSObjectInfoCB),
6029 AFS_OBJECT_INFO_TAG);
6031 if( pObjectInfo == NULL)
6034 try_return( pObjectInfo);
6037 RtlZeroMemory( pObjectInfo,
6038 sizeof( AFSObjectInfoCB));
6040 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6041 sizeof( AFSNonPagedObjectInfoCB),
6042 AFS_NP_OBJECT_INFO_TAG);
6044 if( pObjectInfo->NonPagedInfo == NULL)
6047 AFSExFreePool( pObjectInfo);
6049 try_return( pObjectInfo = NULL);
6052 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6054 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6056 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6058 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6060 if( ParentObjectInfo != NULL)
6062 InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
6066 // Initialize the access time
6069 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6075 // Insert the entry into the object tree and list
6078 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6080 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6083 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6088 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6089 &pObjectInfo->TreeEntry);
6091 ASSERT( NT_SUCCESS( ntStatus));
6095 // And the object list in the volume
6098 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6101 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6106 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6108 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6111 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6114 // Indicate the object is in the hash tree and linked list in the volume
6117 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6129 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6132 BOOLEAN bAcquiredTreeLock = FALSE;
6134 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6137 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6139 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6142 bAcquiredTreeLock = TRUE;
6146 // Remove it from the tree and list if it was inserted
6149 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6152 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6153 &ObjectInfo->TreeEntry);
6156 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6159 if( ObjectInfo->ListEntry.fLink == NULL)
6162 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6164 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6167 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6173 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6176 if( ObjectInfo->ListEntry.bLink == NULL)
6179 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6181 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6184 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6190 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6194 if( ObjectInfo->ParentObjectInformation != NULL)
6196 InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
6199 if( bAcquiredTreeLock)
6202 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6206 // Release the fid in the service
6209 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6212 AFSReleaseFid( &ObjectInfo->FileId);
6215 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6217 AFSExFreePool( ObjectInfo->NonPagedInfo);
6219 AFSExFreePool( ObjectInfo);
6225 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6226 OUT AFSDirectoryCB **TargetDirEntry)
6229 NTSTATUS ntStatus = STATUS_SUCCESS;
6230 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6231 UNICODE_STRING uniFullPathName;
6232 AFSNameArrayHdr *pNameArray = NULL;
6233 AFSVolumeCB *pVolumeCB = NULL;
6234 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6235 WCHAR *pwchBuffer = NULL;
6236 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6237 ULONG ulNameDifference = 0;
6238 GUID *pAuthGroup = NULL;
6244 // Retrieve a target name for the entry
6247 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6250 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6253 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6255 if( DirectoryCB->ObjectInformation->Fcb != NULL)
6257 pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
6260 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6265 if( !NT_SUCCESS( ntStatus) ||
6266 pDirEntry->TargetNameLength == 0)
6269 if( pDirEntry != NULL)
6272 ntStatus = STATUS_ACCESS_DENIED;
6275 try_return( ntStatus);
6278 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6281 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6285 // Update the target name
6288 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6289 &DirectoryCB->Flags,
6290 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6291 (USHORT)pDirEntry->TargetNameLength);
6293 if( !NT_SUCCESS( ntStatus))
6296 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6298 try_return( ntStatus);
6302 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6306 // Need to pass the full path in for parsing.
6309 uniFullPathName.Length = 0;
6310 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6312 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6313 uniFullPathName.MaximumLength,
6314 AFS_NAME_BUFFER_EIGHT_TAG);
6316 if( uniFullPathName.Buffer == NULL)
6319 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6321 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6324 pwchBuffer = uniFullPathName.Buffer;
6326 RtlZeroMemory( uniFullPathName.Buffer,
6327 uniFullPathName.MaximumLength);
6329 RtlCopyMemory( uniFullPathName.Buffer,
6330 DirectoryCB->NameInformation.TargetName.Buffer,
6331 DirectoryCB->NameInformation.TargetName.Length);
6333 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6336 // This name should begin with the \afs server so parse it off and chech it
6339 FsRtlDissectName( uniFullPathName,
6343 if( RtlCompareUnicodeString( &uniComponentName,
6349 // Try evaluating the full path
6352 uniFullPathName.Buffer = pwchBuffer;
6354 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6356 uniFullPathName.MaximumLength = uniFullPathName.Length;
6361 uniFullPathName = uniRemainingPath;
6364 uniParsedName = uniFullPathName;
6366 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6368 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6374 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6377 if( pNameArray == NULL)
6380 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6383 pVolumeCB = AFSGlobalRoot;
6385 AFSAcquireShared( pVolumeCB->VolumeLock,
6388 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6390 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6392 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6393 AFS_TRACE_LEVEL_VERBOSE,
6394 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6396 pVolumeCB->VolumeReferenceCount);
6398 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6400 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6401 AFS_TRACE_LEVEL_VERBOSE,
6402 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6403 &pParentDirEntry->NameInformation.FileName,
6406 pParentDirEntry->OpenReferenceCount);
6408 ntStatus = AFSLocateNameEntry( NULL,
6419 if( !NT_SUCCESS( ntStatus))
6423 // The volume lock was released on failure above
6424 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6427 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6430 if( pVolumeCB != NULL)
6433 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6435 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6436 AFS_TRACE_LEVEL_VERBOSE,
6437 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
6439 pVolumeCB->VolumeReferenceCount);
6441 AFSReleaseResource( pVolumeCB->VolumeLock);
6444 if( pDirectoryEntry != NULL)
6447 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6449 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6450 AFS_TRACE_LEVEL_VERBOSE,
6451 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6452 &pDirectoryEntry->NameInformation.FileName,
6455 pDirectoryEntry->OpenReferenceCount);
6460 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6462 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6463 AFS_TRACE_LEVEL_VERBOSE,
6464 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6465 &pParentDirEntry->NameInformation.FileName,
6468 pParentDirEntry->OpenReferenceCount);
6474 try_return( ntStatus);
6478 // Pass back the target dir entry for this request
6481 *TargetDirEntry = pDirectoryEntry;
6485 if( pDirEntry != NULL)
6488 AFSExFreePool( pDirEntry);
6491 if( pVolumeCB != NULL)
6494 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6496 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6497 AFS_TRACE_LEVEL_VERBOSE,
6498 "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
6500 pVolumeCB->VolumeReferenceCount);
6502 AFSReleaseResource( pVolumeCB->VolumeLock);
6505 if( pNameArray != NULL)
6508 AFSFreeNameArray( pNameArray);
6511 if( pwchBuffer != NULL)
6515 // Always free the buffer that we allocated as AFSLocateNameEntry
6516 // will not free it. If uniFullPathName.Buffer was allocated by
6517 // AFSLocateNameEntry, then we must free that as well.
6518 // Check that the uniFullPathName.Buffer in the string is not the same
6519 // offset by the length of the server name
6522 if( uniFullPathName.Length > 0 &&
6523 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6526 AFSExFreePool( uniFullPathName.Buffer);
6529 AFSExFreePool( pwchBuffer);
6537 AFSCleanupFcb( IN AFSFcb *Fcb,
6538 IN BOOLEAN ForceFlush)
6541 NTSTATUS ntStatus = STATUS_SUCCESS;
6542 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6543 LARGE_INTEGER liTime;
6544 IO_STATUS_BLOCK stIoStatus;
6549 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6551 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6553 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6556 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6557 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6560 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6563 if( Fcb->OpenReferenceCount > 0)
6569 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6574 if( !NT_SUCCESS( stIoStatus.Status))
6577 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6578 AFS_TRACE_LEVEL_ERROR,
6579 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6580 Fcb->ObjectInformation->FileId.Cell,
6581 Fcb->ObjectInformation->FileId.Volume,
6582 Fcb->ObjectInformation->FileId.Vnode,
6583 Fcb->ObjectInformation->FileId.Unique,
6585 stIoStatus.Information);
6587 ntStatus = stIoStatus.Status;
6590 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6595 __except( EXCEPTION_EXECUTE_HANDLER)
6597 ntStatus = GetExceptionCode();
6601 AFSReleaseResource( &Fcb->NPFcb->Resource);
6604 // Wait for any currently running flush or release requests to complete
6607 AFSWaitOnQueuedFlushes( Fcb);
6610 // Now perform another flush on the file
6613 if( !NT_SUCCESS( AFSFlushExtents( Fcb)))
6616 AFSReleaseExtentsWithFlush( Fcb);
6620 if( Fcb->OpenReferenceCount == 0 ||
6621 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6622 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6625 AFSTearDownFcbExtents( Fcb);
6628 try_return( ntStatus);
6631 KeQueryTickCount( &liTime);
6634 // First up are there dirty extents in the cache to flush?
6638 ( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6639 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
6640 ( Fcb->Specific.File.ExtentsDirtyCount ||
6641 Fcb->Specific.File.ExtentCount) &&
6642 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6643 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6646 if( !NT_SUCCESS( AFSFlushExtents( Fcb)) &&
6647 Fcb->OpenReferenceCount == 0)
6650 AFSReleaseExtentsWithFlush( Fcb);
6653 else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6654 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6658 // The file has been marked as invalid. Dump it
6661 AFSTearDownFcbExtents( Fcb);
6665 // If there are extents and they haven't been used recently *and*
6666 // are not being used
6670 ( 0 != Fcb->Specific.File.ExtentCount &&
6671 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6672 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6673 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
6674 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6681 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6686 if( !NT_SUCCESS( stIoStatus.Status))
6689 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6690 AFS_TRACE_LEVEL_ERROR,
6691 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6692 Fcb->ObjectInformation->FileId.Cell,
6693 Fcb->ObjectInformation->FileId.Volume,
6694 Fcb->ObjectInformation->FileId.Vnode,
6695 Fcb->ObjectInformation->FileId.Unique,
6697 stIoStatus.Information);
6699 ntStatus = stIoStatus.Status;
6705 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6711 __except( EXCEPTION_EXECUTE_HANDLER)
6713 ntStatus = GetExceptionCode();
6716 AFSReleaseResource( &Fcb->NPFcb->Resource);
6718 if( Fcb->OpenReferenceCount == 0)
6722 // Tear em down we'll not be needing them again
6725 AFSTearDownFcbExtents( Fcb);
6738 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
6739 IN UNICODE_STRING *NewFileName)
6742 NTSTATUS ntStatus = STATUS_SUCCESS;
6743 WCHAR *pTmpBuffer = NULL;
6748 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
6751 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
6754 AFSExFreePool( DirectoryCB->NameInformation.FileName.Buffer);
6756 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6758 DirectoryCB->NameInformation.FileName.Buffer = NULL;
6762 // OK, we need to allocate a new name buffer
6765 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6766 NewFileName->Length,
6767 AFS_NAME_BUFFER_NINE_TAG);
6769 if( pTmpBuffer == NULL)
6772 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6775 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
6777 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
6779 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6782 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
6784 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
6785 NewFileName->Buffer,
6786 NewFileName->Length);
6797 AFSReadCacheFile( IN void *ReadBuffer,
6798 IN LARGE_INTEGER *ReadOffset,
6799 IN ULONG RequestedDataLength,
6800 IN OUT PULONG BytesRead)
6803 NTSTATUS ntStatus = STATUS_SUCCESS;
6806 PIO_STACK_LOCATION pIoStackLocation = NULL;
6807 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6808 DEVICE_OBJECT *pTargetDeviceObject = NULL;
6809 FILE_OBJECT *pCacheFileObject = NULL;
6814 pCacheFileObject = AFSReferenceCacheFileObject();
6816 if( pCacheFileObject == NULL)
6818 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
6821 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
6824 // Initialize the event
6827 KeInitializeEvent( &kEvent,
6828 SynchronizationEvent,
6832 // Allocate an irp for this request. This could also come from a
6833 // private pool, for instance.
6836 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
6842 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6846 // Build the IRP's main body
6849 pIrp->UserBuffer = ReadBuffer;
6851 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
6852 pIrp->RequestorMode = KernelMode;
6853 pIrp->Flags |= IRP_READ_OPERATION;
6856 // Set up the I/O stack location.
6859 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
6860 pIoStackLocation->MajorFunction = IRP_MJ_READ;
6861 pIoStackLocation->DeviceObject = pTargetDeviceObject;
6862 pIoStackLocation->FileObject = pCacheFileObject;
6863 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
6865 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
6868 // Set the completion routine.
6871 IoSetCompletionRoutine( pIrp,
6879 // Send it to the FSD
6882 ntStatus = IoCallDriver( pTargetDeviceObject,
6885 if( NT_SUCCESS( ntStatus))
6892 ntStatus = KeWaitForSingleObject( &kEvent,
6898 if( NT_SUCCESS( ntStatus))
6901 ntStatus = pIrp->IoStatus.Status;
6903 *BytesRead = (ULONG)pIrp->IoStatus.Information;
6909 if( pCacheFileObject != NULL)
6911 AFSReleaseCacheFileObject( pCacheFileObject);
6917 if( pIrp->MdlAddress != NULL)
6920 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
6923 MmUnlockPages( pIrp->MdlAddress);
6926 IoFreeMdl( pIrp->MdlAddress);
6929 pIrp->MdlAddress = NULL;
6943 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
6948 KEVENT *pEvent = (KEVENT *)Context;
6954 return STATUS_MORE_PROCESSING_REQUIRED;
6958 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
6961 BOOLEAN bIsEmpty = FALSE;
6962 AFSDirectoryCB *pDirEntry = NULL;
6967 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
6972 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
6975 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
6977 while( pDirEntry != NULL)
6980 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
6981 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
6989 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
6994 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7001 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7002 IN AFSDirectoryCB *DirEntry)
7005 NTSTATUS ntStatus = STATUS_SUCCESS;
7010 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7013 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7014 AFS_TRACE_LEVEL_VERBOSE,
7015 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7017 &DirEntry->NameInformation.FileName);
7019 try_return( ntStatus);
7022 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7025 // Remove the entry from the parent tree
7028 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7029 AFS_TRACE_LEVEL_VERBOSE,
7030 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7032 &DirEntry->NameInformation.FileName);
7034 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7037 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7038 AFS_TRACE_LEVEL_VERBOSE,
7039 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7041 &DirEntry->NameInformation.FileName);
7043 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7046 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7050 // From the short name tree
7053 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7054 AFS_TRACE_LEVEL_VERBOSE,
7055 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7057 &DirEntry->NameInformation.FileName);
7059 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7062 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7065 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7066 AFS_TRACE_LEVEL_VERBOSE,
7067 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7069 &DirEntry->NameInformation.FileName);
7071 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7073 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7084 AFSGetAuthenticationId()
7087 LARGE_INTEGER liAuthId = {0,0};
7088 NTSTATUS ntStatus = STATUS_SUCCESS;
7089 PACCESS_TOKEN hToken = NULL;
7090 PTOKEN_STATISTICS pTokenInfo = NULL;
7091 BOOLEAN bCopyOnOpen = FALSE;
7092 BOOLEAN bEffectiveOnly = FALSE;
7093 BOOLEAN bPrimaryToken = FALSE;
7094 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7099 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7102 &stImpersonationLevel);
7107 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7112 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7113 AFS_TRACE_LEVEL_ERROR,
7114 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7116 try_return( ntStatus);
7119 bPrimaryToken = TRUE;
7122 ntStatus = SeQueryInformationToken( hToken,
7124 (PVOID *)&pTokenInfo);
7126 if( !NT_SUCCESS( ntStatus))
7129 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7130 AFS_TRACE_LEVEL_ERROR,
7131 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7133 try_return( ntStatus);
7136 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7137 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7139 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7140 AFS_TRACE_LEVEL_VERBOSE,
7141 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7152 PsDereferenceImpersonationToken( hToken);
7157 PsDereferencePrimaryToken( hToken);
7161 if( pTokenInfo != NULL)
7164 AFSExFreePool( pTokenInfo);
7172 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7176 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7178 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7181 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7183 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7186 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7188 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7191 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7193 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7196 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7198 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7205 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7208 BOOLEAN bIsValid = TRUE;
7210 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7212 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7214 while( pCurrentDirEntry != NULL)
7217 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7221 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7226 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7227 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7230 if( pDirEntry == NULL)
7237 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7240 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7243 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7245 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7247 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7256 AFSReferenceCacheFileObject()
7259 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7260 FILE_OBJECT *pCacheFileObject = NULL;
7262 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7265 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7267 if( pCacheFileObject != NULL)
7269 ObReferenceObject( pCacheFileObject);
7272 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7274 return pCacheFileObject;
7278 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7281 ASSERT( CacheFileObject != NULL);
7283 ObDereferenceObject( CacheFileObject);
7289 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7292 NTSTATUS ntStatus = STATUS_SUCCESS;
7293 AFSDeviceExt *pControlDevExt = NULL;
7294 ULONG ulTimeIncrement = 0;
7299 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7301 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7303 AFSServerName = LibraryInit->AFSServerName;
7305 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7308 // Callbacks in the framework
7311 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7313 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7315 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7317 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7319 AFSExFreePool = LibraryInit->AFSExFreePool;
7321 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7323 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7325 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7327 if( LibraryInit->AFSCacheBaseAddress != NULL)
7330 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7332 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7334 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7338 // Initialize some flush parameters
7341 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7343 ulTimeIncrement = KeQueryTimeIncrement();
7345 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7346 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_ONE_SECOND;
7347 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart *= AFS_SERVER_PURGE_DELAY;
7348 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7349 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)(AFS_ONE_SECOND * AFS_SERVER_FLUSH_DELAY) / (ULONGLONG)ulTimeIncrement);
7350 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7353 // Initialize the global root entry
7356 ntStatus = AFSInitVolume( NULL,
7357 &LibraryInit->GlobalRootFid,
7360 if( !NT_SUCCESS( ntStatus))
7363 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7364 AFS_TRACE_LEVEL_ERROR,
7365 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7368 try_return( ntStatus);
7371 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7374 if( !NT_SUCCESS( ntStatus))
7377 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7378 AFS_TRACE_LEVEL_ERROR,
7379 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7382 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7384 try_return( ntStatus);
7388 // Update the node type code to AFS_ROOT_ALL
7391 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7393 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7396 // Drop the locks acquired above
7399 AFSInitVolumeWorker( AFSGlobalRoot);
7401 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7403 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7417 NTSTATUS ntStatus = STATUS_SUCCESS;
7418 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7423 if( AFSGlobalDotDirEntry != NULL)
7426 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
7428 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7430 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7432 ExFreePool( AFSGlobalDotDirEntry);
7434 AFSGlobalDotDirEntry = NULL;
7437 if( AFSGlobalDotDotDirEntry != NULL)
7440 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
7442 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7444 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7446 ExFreePool( AFSGlobalDotDotDirEntry);
7448 AFSGlobalDotDotDirEntry = NULL;
7451 if( AFSSpecialShareNames != NULL)
7454 pDirNode = AFSSpecialShareNames;
7456 while( pDirNode != NULL)
7459 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7461 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
7463 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7465 ExFreePool( pDirNode->NonPaged);
7467 ExFreePool( pDirNode);
7469 pDirNode = pLastDirNode;
7472 AFSSpecialShareNames = NULL;
7480 AFSDefaultLogMsg( IN ULONG Subsystem,
7486 NTSTATUS ntStatus = STATUS_SUCCESS;
7488 char chDebugBuffer[ 256];
7493 va_start( va_args, Format);
7495 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7500 if( NT_SUCCESS( ntStatus))
7502 DbgPrint( chDebugBuffer);
7512 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7513 IN ULONG InputBufferLength,
7514 IN AFSStatusInfoCB *StatusInfo,
7515 OUT ULONG *ReturnLength)
7518 NTSTATUS ntStatus = STATUS_SUCCESS;
7519 AFSFcb *pFcb = NULL;
7520 AFSVolumeCB *pVolumeCB = NULL;
7521 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7522 AFSObjectInfoCB *pObjectInfo = NULL;
7523 ULONGLONG ullIndex = 0;
7524 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7525 AFSNameArrayHdr *pNameArray = NULL;
7526 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7532 // If we are given a FID then look up the entry by that, otherwise
7536 if( GetStatusInfo->FileID.Cell != 0 &&
7537 GetStatusInfo->FileID.Volume != 0 &&
7538 GetStatusInfo->FileID.Vnode != 0 &&
7539 GetStatusInfo->FileID.Unique != 0)
7542 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7545 // Locate the volume node
7548 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7550 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7552 (AFSBTreeEntry **)&pVolumeCB);
7554 if( pVolumeCB != NULL)
7557 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7559 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7560 AFS_TRACE_LEVEL_VERBOSE,
7561 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7563 pVolumeCB->VolumeReferenceCount);
7566 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7568 if( !NT_SUCCESS( ntStatus) ||
7571 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7574 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
7577 pObjectInfo = &pVolumeCB->ObjectInformation;
7579 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7581 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7586 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
7589 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7591 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7592 AFS_TRACE_LEVEL_VERBOSE,
7593 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7595 pVolumeCB->VolumeReferenceCount);
7597 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
7599 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
7601 (AFSBTreeEntry **)&pObjectInfo);
7603 if( pObjectInfo != NULL)
7607 // Reference the node so it won't be torn down
7610 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7612 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7613 AFS_TRACE_LEVEL_VERBOSE,
7614 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
7616 pObjectInfo->ObjectReferenceCount);
7619 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
7621 if( !NT_SUCCESS( ntStatus) ||
7622 pObjectInfo == NULL)
7624 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7631 if( GetStatusInfo->FileNameLength == 0 ||
7632 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
7634 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7637 uniFullPathName.Length = GetStatusInfo->FileNameLength;
7638 uniFullPathName.MaximumLength = uniFullPathName.Length;
7640 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
7643 // This name should begin with the \afs server so parse it off and check it
7646 FsRtlDissectName( uniFullPathName,
7650 if( RtlCompareUnicodeString( &uniComponentName,
7654 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7655 AFS_TRACE_LEVEL_ERROR,
7656 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
7659 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
7662 uniFullPathName = uniRemainingPath;
7664 uniParsedName = uniFullPathName;
7670 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7673 if( pNameArray == NULL)
7675 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7678 pVolumeCB = AFSGlobalRoot;
7680 AFSAcquireShared( pVolumeCB->VolumeLock,
7683 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7686 // Increment the ref count on the volume and dir entry for correct processing below
7689 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7691 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7692 AFS_TRACE_LEVEL_VERBOSE,
7693 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7695 pVolumeCB->VolumeReferenceCount);
7697 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
7699 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7700 AFS_TRACE_LEVEL_VERBOSE,
7701 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7702 &pParentDirEntry->NameInformation.FileName,
7705 pParentDirEntry->OpenReferenceCount);
7707 ntStatus = AFSLocateNameEntry( NULL,
7712 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
7713 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
7719 if( !NT_SUCCESS( ntStatus))
7723 // The volume lock was released on failure above
7724 // Except for STATUS_OBJECT_NAME_NOT_FOUND
7727 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
7730 if( pVolumeCB != NULL)
7733 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7735 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7736 AFS_TRACE_LEVEL_VERBOSE,
7737 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7739 pVolumeCB->VolumeReferenceCount);
7741 AFSReleaseResource( pVolumeCB->VolumeLock);
7744 if( pDirectoryEntry != NULL)
7747 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7749 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7750 AFS_TRACE_LEVEL_VERBOSE,
7751 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7752 &pDirectoryEntry->NameInformation.FileName,
7755 pDirectoryEntry->OpenReferenceCount);
7760 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
7762 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7763 AFS_TRACE_LEVEL_VERBOSE,
7764 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7765 &pParentDirEntry->NameInformation.FileName,
7768 pParentDirEntry->OpenReferenceCount);
7774 try_return( ntStatus);
7778 // Remove the reference made above
7781 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7783 pObjectInfo = pDirectoryEntry->ObjectInformation;
7785 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7787 if( pVolumeCB != NULL)
7790 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7792 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7793 AFS_TRACE_LEVEL_VERBOSE,
7794 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
7796 pVolumeCB->VolumeReferenceCount);
7798 AFSReleaseResource( pVolumeCB->VolumeLock);
7803 // At this point we have an object info block, return the information
7806 StatusInfo->FileId = pObjectInfo->FileId;
7808 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
7810 StatusInfo->Expiration = pObjectInfo->Expiration;
7812 StatusInfo->DataVersion = pObjectInfo->DataVersion;
7814 StatusInfo->FileType = pObjectInfo->FileType;
7816 StatusInfo->ObjectFlags = pObjectInfo->Flags;
7818 StatusInfo->CreationTime = pObjectInfo->CreationTime;
7820 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
7822 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
7824 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
7826 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
7828 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
7830 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
7832 StatusInfo->EaSize = pObjectInfo->EaSize;
7834 StatusInfo->Links = pObjectInfo->Links;
7837 // Return the information length
7840 *ReturnLength = sizeof( AFSStatusInfoCB);
7844 if( pObjectInfo != NULL)
7847 InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
7850 if( pNameArray != NULL)
7853 AFSFreeNameArray( pNameArray);
7861 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
7862 IN UNICODE_STRING *ComponentName)
7865 NTSTATUS ntStatus = STATUS_SUCCESS;
7866 AFSDirectoryCB *pDirEntry = NULL;
7873 // Search for the entry in the parent
7876 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7877 AFS_TRACE_LEVEL_VERBOSE_2,
7878 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
7881 ulCRC = AFSGenerateCRC( ComponentName,
7884 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7887 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7891 if( pDirEntry == NULL)
7895 // Missed so perform a case insensitive lookup
7898 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7899 AFS_TRACE_LEVEL_VERBOSE_2,
7900 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
7903 ulCRC = AFSGenerateCRC( ComponentName,
7906 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7910 if( pDirEntry == NULL)
7914 // OK, if this component is a valid short name then try
7915 // a lookup in the short name tree
7918 if( RtlIsNameLegalDOS8Dot3( ComponentName,
7923 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7924 AFS_TRACE_LEVEL_VERBOSE_2,
7925 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
7928 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
7935 if( pDirEntry != NULL)
7937 InterlockedIncrement( &pDirEntry->OpenReferenceCount);
7940 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7942 if( pDirEntry == NULL)
7945 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7946 AFS_TRACE_LEVEL_VERBOSE_2,
7947 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
7950 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
7954 // We have the symlink object but previously failed to process it so return access
7958 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7959 AFS_TRACE_LEVEL_VERBOSE_2,
7960 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ ACCESS_DENIED\n",
7963 ntStatus = STATUS_ACCESS_DENIED;
7965 InterlockedDecrement( &pDirEntry->OpenReferenceCount);
7976 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
7977 OUT UNICODE_STRING *ComponentName)
7980 NTSTATUS ntStatus = STATUS_SUCCESS;
7981 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
7983 uniFullPathName = *FullPathName;
7988 FsRtlDissectName( uniFullPathName,
7992 if( uniRemainingPath.Length == 0)
7997 uniFullPathName = uniRemainingPath;
8000 if( uniComponentName.Length > 0)
8002 *ComponentName = uniComponentName;
8009 AFSDumpTraceFiles_Default()
8015 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8018 BOOLEAN bIsValidName = TRUE;
8024 while( usIndex < FileName->Length/sizeof( WCHAR))
8027 if( FileName->Buffer[ usIndex] == L':' ||
8028 FileName->Buffer[ usIndex] == L'*' ||
8029 FileName->Buffer[ usIndex] == L'?' ||
8030 FileName->Buffer[ usIndex] == L'"' ||
8031 FileName->Buffer[ usIndex] == L'<' ||
8032 FileName->Buffer[ usIndex] == L'>')
8034 bIsValidName = FALSE;
8042 return bIsValidName;
8046 AFSCreateDefaultSecurityDescriptor()
8049 NTSTATUS ntStatus = STATUS_SUCCESS;
8051 ULONG ulSACLSize = 0;
8052 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8053 ULONG ulACESize = 0;
8054 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8055 ULONG ulSDLength = 0;
8056 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8061 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8064 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8069 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8071 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8073 AFS_GENERIC_MEMORY_29_TAG);
8078 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8080 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8083 RtlZeroMemory( pACE,
8086 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8087 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8088 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8089 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8091 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8093 SeExports->SeLowMandatorySid);
8095 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8096 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8098 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8100 AFS_GENERIC_MEMORY_29_TAG);
8105 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8107 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8110 ntStatus = RtlCreateAcl( pSACL,
8114 if( !NT_SUCCESS( ntStatus))
8117 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8120 try_return( ntStatus);
8123 ntStatus = RtlAddAce( pSACL,
8127 pACE->Header.AceSize);
8129 if( !NT_SUCCESS( ntStatus))
8132 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8135 try_return( ntStatus);
8139 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8140 sizeof( SECURITY_DESCRIPTOR),
8141 AFS_GENERIC_MEMORY_27_TAG);
8143 if( pSecurityDescr == NULL)
8146 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8148 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8151 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8152 SECURITY_DESCRIPTOR_REVISION);
8154 if( !NT_SUCCESS( ntStatus))
8157 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8160 try_return( ntStatus);
8163 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8165 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8170 if( !NT_SUCCESS( ntStatus))
8173 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8176 try_return( ntStatus);
8180 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8183 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8185 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8188 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8190 AFS_GENERIC_MEMORY_27_TAG);
8192 if( pRelativeSecurityDescr == NULL)
8195 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8197 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8200 ulSDLength = PAGE_SIZE;
8202 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8203 pRelativeSecurityDescr,
8206 if( !NT_SUCCESS( ntStatus))
8209 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8212 try_return( ntStatus);
8215 AFSDefaultSD = pRelativeSecurityDescr;
8219 if( !NT_SUCCESS( ntStatus))
8222 if( pRelativeSecurityDescr != NULL)
8224 ExFreePool( pRelativeSecurityDescr);
8228 if( pSecurityDescr != NULL)
8230 ExFreePool( pSecurityDescr);