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)
1121 pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1124 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1125 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1128 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1131 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1134 // Object specific information
1137 pObjectInfoCB->Links = DirEnumEntry->Links;
1139 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1141 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1144 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1145 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1149 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1150 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1151 pObjectInfoCB->TargetFileId.Unique == 0 &&
1152 pDirNode->NameInformation.TargetName.Length == 0)
1156 // This will ensure we perform a validation on the node
1159 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1162 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1165 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1171 if( !NT_SUCCESS( ntStatus))
1174 if( pNonPagedDirEntry != NULL)
1177 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1179 AFSExFreePool( pNonPagedDirEntry);
1182 if( pDirNode != NULL)
1185 AFSExFreePool( pDirNode);
1191 // Dereference our object info block if we have one
1194 if( pObjectInfoCB != NULL)
1197 InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
1199 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1200 AFS_TRACE_LEVEL_VERBOSE,
1201 "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
1203 pObjectInfoCB->ObjectReferenceCount);
1205 if( bAllocatedObjectCB)
1208 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1210 AFSDeleteObjectInfo( pObjectInfoCB);
1220 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1221 IN BOOLEAN DirectoryEntry)
1224 BOOLEAN bReturn = TRUE;
1225 ACCESS_MASK stAccessMask = 0;
1228 // Get rid of anything we don't know about
1231 DesiredAccess = (DesiredAccess &
1237 ACCESS_SYSTEM_SECURITY |
1241 FILE_READ_ATTRIBUTES |
1242 FILE_WRITE_ATTRIBUTES |
1243 FILE_LIST_DIRECTORY |
1249 // Our 'read only' access mask. These are the accesses we will
1250 // allow for a read only file
1253 stAccessMask = DELETE |
1258 ACCESS_SYSTEM_SECURITY |
1262 FILE_READ_ATTRIBUTES |
1263 FILE_WRITE_ATTRIBUTES |
1265 FILE_LIST_DIRECTORY |
1269 // For a directory, add in the directory specific accesses
1275 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1280 if( FlagOn( DesiredAccess, ~stAccessMask))
1284 // A write access is set ...
1294 AFSEvaluateNode( IN GUID *AuthGroup,
1295 IN AFSDirectoryCB *DirEntry)
1298 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1299 NTSTATUS ntStatus = STATUS_SUCCESS;
1300 AFSDirEnumEntry *pDirEntry = NULL;
1301 UNICODE_STRING uniTargetName;
1306 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1311 if( !NT_SUCCESS( ntStatus))
1314 try_return( ntStatus);
1317 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1319 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1321 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1323 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1325 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1327 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1329 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1331 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1333 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1335 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1337 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1339 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1342 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1345 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1346 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1349 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1352 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1354 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1357 // If we have a target name then see if it needs updating ...
1360 if( pDirEntry->TargetNameLength > 0)
1364 // Update the target name information if needed
1367 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1369 uniTargetName.MaximumLength = uniTargetName.Length;
1371 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1373 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1376 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1377 RtlCompareUnicodeString( &uniTargetName,
1378 &DirEntry->NameInformation.TargetName,
1383 // Update the target name
1386 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1388 uniTargetName.Buffer,
1389 uniTargetName.Length);
1391 if( !NT_SUCCESS( ntStatus))
1394 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1396 try_return( ntStatus);
1400 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1405 if( pDirEntry != NULL)
1408 AFSExFreePool( pDirEntry);
1416 AFSValidateSymLink( IN GUID *AuthGroup,
1417 IN AFSDirectoryCB *DirEntry)
1420 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1421 NTSTATUS ntStatus = STATUS_SUCCESS;
1422 AFSDirEnumEntry *pDirEntry = NULL;
1423 UNICODE_STRING uniTargetName;
1428 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1433 if( !NT_SUCCESS( ntStatus))
1436 try_return( ntStatus);
1439 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1440 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1443 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1446 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1448 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1450 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1453 // Update the target name information if needed
1456 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1458 uniTargetName.MaximumLength = uniTargetName.Length;
1460 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1462 if( uniTargetName.Length > 0)
1465 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1468 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1469 RtlCompareUnicodeString( &uniTargetName,
1470 &DirEntry->NameInformation.TargetName,
1475 // Update the target name
1478 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1480 uniTargetName.Buffer,
1481 uniTargetName.Length);
1483 if( !NT_SUCCESS( ntStatus))
1486 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1488 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1492 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1496 // If the FileType is the same then nothing to do since it IS
1500 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1503 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1505 try_return( ntStatus = STATUS_SUCCESS);
1508 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1510 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1512 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1514 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1516 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1518 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1520 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1522 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1524 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1527 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1530 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1531 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1534 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1537 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1539 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1543 if( pDirEntry != NULL)
1546 AFSExFreePool( pDirEntry);
1554 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1557 NTSTATUS ntStatus = STATUS_SUCCESS;
1558 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1559 AFSVolumeCB *pVolumeCB = NULL;
1560 AFSFcb *pTargetDcb = NULL;
1561 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1562 AFSDirectoryCB *pCurrentDirEntry = NULL;
1563 BOOLEAN bIsChild = FALSE;
1564 ULONGLONG ullIndex = 0;
1565 AFSObjectInfoCB *pObjectInfo = NULL;
1566 IO_STATUS_BLOCK stIoStatus;
1573 // Need to locate the Fcb for the directory to purge
1576 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1577 AFS_TRACE_LEVEL_VERBOSE,
1578 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1579 &pDevExt->Specific.RDR.VolumeTreeLock,
1580 PsGetCurrentThread());
1583 // Starve any exclusive waiters on this paticular call
1586 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1589 // Locate the volume node
1592 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1594 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1596 (AFSBTreeEntry **)&pVolumeCB);
1598 if( pVolumeCB != NULL)
1601 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1603 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1604 AFS_TRACE_LEVEL_VERBOSE,
1605 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1607 pVolumeCB->VolumeReferenceCount);
1610 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1612 if( !NT_SUCCESS( ntStatus) ||
1615 try_return( ntStatus = STATUS_SUCCESS);
1619 // If this is a whole volume invalidation then go do it now
1622 if( InvalidateCB->WholeVolume ||
1623 AFSIsVolumeFID( &InvalidateCB->FileID))
1626 ntStatus = AFSInvalidateVolume( pVolumeCB,
1627 InvalidateCB->Reason);
1629 AFSFsRtlNotifyFullReportChange( &pVolumeCB->ObjectInformation,
1631 FILE_NOTIFY_CHANGE_FILE_NAME |
1632 FILE_NOTIFY_CHANGE_DIR_NAME |
1633 FILE_NOTIFY_CHANGE_NAME |
1634 FILE_NOTIFY_CHANGE_ATTRIBUTES |
1635 FILE_NOTIFY_CHANGE_SIZE,
1636 FILE_ACTION_MODIFIED);
1638 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1640 try_return( ntStatus);
1643 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1646 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1648 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1649 AFS_TRACE_LEVEL_VERBOSE,
1650 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
1652 pVolumeCB->VolumeReferenceCount);
1654 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
1656 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
1658 (AFSBTreeEntry **)&pObjectInfo);
1660 if( pObjectInfo != NULL)
1664 // Reference the node so it won't be torn down
1667 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
1669 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1670 AFS_TRACE_LEVEL_VERBOSE,
1671 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
1673 pObjectInfo->ObjectReferenceCount);
1676 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1678 if( !NT_SUCCESS( ntStatus) ||
1679 pObjectInfo == NULL)
1681 try_return( ntStatus = STATUS_SUCCESS);
1684 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
1685 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK ||
1686 pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1689 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1690 AFS_TRACE_LEVEL_VERBOSE,
1691 "AFSInvalidateCache Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1692 pObjectInfo->FileType,
1693 pObjectInfo->FileId.Cell,
1694 pObjectInfo->FileId.Volume,
1695 pObjectInfo->FileId.Vnode,
1696 pObjectInfo->FileId.Unique,
1697 InvalidateCB->Reason);
1700 // We only act on the mount point itself, not the target. If the
1701 // node has been deleted then mark it as such otherwise indicate
1702 // it requires verification
1705 if( InvalidateCB->Reason == AFS_INVALIDATE_DELETED)
1707 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1712 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
1713 InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1715 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1718 pObjectInfo->Expiration.QuadPart = 0;
1720 pObjectInfo->TargetFileId.Vnode = 0;
1722 pObjectInfo->TargetFileId.Unique = 0;
1724 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1725 AFS_TRACE_LEVEL_VERBOSE,
1726 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1727 pObjectInfo->FileId.Cell,
1728 pObjectInfo->FileId.Volume,
1729 pObjectInfo->FileId.Vnode,
1730 pObjectInfo->FileId.Unique);
1732 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1735 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1737 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1739 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1742 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1744 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1748 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1751 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1753 FILE_NOTIFY_CHANGE_FILE_NAME |
1754 FILE_NOTIFY_CHANGE_ATTRIBUTES,
1755 FILE_ACTION_MODIFIED);
1757 try_return( ntStatus);
1761 // Depending on the reason for invalidation then perform work on the node
1764 switch( InvalidateCB->Reason)
1767 case AFS_INVALIDATE_DELETED:
1771 // Mark this node as invalid
1774 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
1776 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1777 AFS_TRACE_LEVEL_VERBOSE,
1778 "AFSInvalidateCache Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1779 pObjectInfo->FileId.Cell,
1780 pObjectInfo->FileId.Volume,
1781 pObjectInfo->FileId.Vnode,
1782 pObjectInfo->FileId.Unique);
1784 if( pObjectInfo->ParentObjectInformation != NULL)
1787 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1788 AFS_TRACE_LEVEL_VERBOSE,
1789 "AFSInvalidateCache Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1790 pObjectInfo->ParentObjectInformation->FileId.Cell,
1791 pObjectInfo->ParentObjectInformation->FileId.Volume,
1792 pObjectInfo->ParentObjectInformation->FileId.Vnode,
1793 pObjectInfo->ParentObjectInformation->FileId.Unique);
1795 SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1796 pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1797 pObjectInfo->ParentObjectInformation->Expiration.QuadPart = 0;
1800 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1802 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1806 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1809 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1812 FILE_ACTION_REMOVED);
1817 case AFS_INVALIDATE_FLUSHED:
1820 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
1821 pObjectInfo->Fcb != NULL)
1824 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1825 AFS_TRACE_LEVEL_VERBOSE,
1826 "AFSInvalidateCache Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1827 pObjectInfo->FileId.Cell,
1828 pObjectInfo->FileId.Volume,
1829 pObjectInfo->FileId.Vnode,
1830 pObjectInfo->FileId.Unique);
1832 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
1838 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1843 if( !NT_SUCCESS( stIoStatus.Status))
1846 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1847 AFS_TRACE_LEVEL_ERROR,
1848 "AFSInvalidateCache CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1849 pObjectInfo->FileId.Cell,
1850 pObjectInfo->FileId.Volume,
1851 pObjectInfo->FileId.Vnode,
1852 pObjectInfo->FileId.Unique,
1854 stIoStatus.Information);
1856 ntStatus = stIoStatus.Status;
1859 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1864 __except( EXCEPTION_EXECUTE_HANDLER)
1867 ntStatus = GetExceptionCode();
1870 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
1873 // Clear out the extents
1874 // Get rid of them (note this involves waiting
1875 // for any writes or reads to the cache to complete)
1878 (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb);
1881 // Fall through to the default processing
1887 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1889 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1893 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1896 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1898 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1901 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1903 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1907 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1910 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1913 FILE_ACTION_MODIFIED);
1916 // Indicate this node requires re-evaluation for the remaining reasons
1919 pObjectInfo->Expiration.QuadPart = 0;
1921 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1922 AFS_TRACE_LEVEL_VERBOSE,
1923 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1924 pObjectInfo->FileId.Cell,
1925 pObjectInfo->FileId.Volume,
1926 pObjectInfo->FileId.Vnode,
1927 pObjectInfo->FileId.Unique);
1929 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1931 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
1932 InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1934 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1936 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
1939 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1940 AFS_TRACE_LEVEL_VERBOSE,
1941 "AFSInvalidateCache Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1942 pObjectInfo->FileId.Cell,
1943 pObjectInfo->FileId.Volume,
1944 pObjectInfo->FileId.Vnode,
1945 pObjectInfo->FileId.Unique);
1947 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1957 if( pObjectInfo != NULL)
1960 InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
1962 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1963 AFS_TRACE_LEVEL_VERBOSE,
1964 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
1966 pObjectInfo->ObjectReferenceCount);
1974 AFSIsChildOfParent( IN AFSFcb *Dcb,
1978 BOOLEAN bIsChild = FALSE;
1979 AFSFcb *pCurrentFcb = Fcb;
1981 while( pCurrentFcb != NULL)
1984 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
1992 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2000 AFSCreateHighIndex( IN AFSFileID *FileID)
2003 ULONGLONG ullIndex = 0;
2005 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2012 AFSCreateLowIndex( IN AFSFileID *FileID)
2015 ULONGLONG ullIndex = 0;
2017 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2023 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2024 IN ACCESS_MASK GrantedAccess,
2025 IN BOOLEAN DirectoryEntry)
2028 BOOLEAN bAccessGranted = TRUE;
2031 // Check if we are asking for read/write and granted only read only
2032 // NOTE: There will be more checks here
2035 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2037 AFSCheckForReadOnlyAccess( GrantedAccess,
2041 bAccessGranted = FALSE;
2044 return bAccessGranted;
2048 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2051 NTSTATUS ntStatus = STATUS_SUCCESS;
2052 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2058 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2060 if( AFSGlobalRoot == NULL)
2067 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2070 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2077 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2084 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2085 IN UNICODE_STRING *SubstituteName,
2086 IN ULONG StringIndex)
2089 NTSTATUS ntStatus = STATUS_SUCCESS;
2090 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2091 AFSSysNameCB *pSysName = NULL;
2092 ERESOURCE *pSysNameLock = NULL;
2095 UNICODE_STRING uniSysName;
2102 if( IoIs32bitProcess( NULL))
2105 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2107 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2112 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2114 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2118 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2120 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2124 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2125 AFS_TRACE_LEVEL_VERBOSE,
2126 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2128 PsGetCurrentThread());
2130 AFSAcquireShared( pSysNameLock,
2134 // Find where we are in the list
2137 while( pSysName != NULL &&
2138 ulIndex < StringIndex)
2141 pSysName = pSysName->fLink;
2146 if( pSysName == NULL)
2149 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2152 RtlInitUnicodeString( &uniSysName,
2155 // If it is a full component of @SYS then just substitue the
2159 if( RtlCompareUnicodeString( &uniSysName,
2164 SubstituteName->Length = pSysName->SysName.Length;
2165 SubstituteName->MaximumLength = SubstituteName->Length;
2167 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2168 SubstituteName->Length,
2169 AFS_SUBST_BUFFER_TAG);
2171 if( SubstituteName->Buffer == NULL)
2174 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2177 RtlCopyMemory( SubstituteName->Buffer,
2178 pSysName->SysName.Buffer,
2179 pSysName->SysName.Length);
2186 while( ComponentName->Buffer[ usIndex] != L'@')
2192 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2193 SubstituteName->MaximumLength = SubstituteName->Length;
2195 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2196 SubstituteName->Length,
2197 AFS_SUBST_BUFFER_TAG);
2199 if( SubstituteName->Buffer == NULL)
2202 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2205 RtlCopyMemory( SubstituteName->Buffer,
2206 ComponentName->Buffer,
2207 usIndex * sizeof( WCHAR));
2209 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2210 pSysName->SysName.Buffer,
2211 pSysName->SysName.Length);
2216 AFSReleaseResource( pSysNameLock);
2223 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2224 IN OUT UNICODE_STRING *ComponentName,
2225 IN UNICODE_STRING *SubstituteName,
2226 IN OUT UNICODE_STRING *RemainingPath,
2227 IN BOOLEAN FreePathName)
2230 NTSTATUS ntStatus = STATUS_SUCCESS;
2231 UNICODE_STRING uniPathName;
2232 USHORT usPrefixNameLen = 0;
2233 SHORT sNameLenDelta = 0;
2239 // If the passed in name can handle the additional length
2240 // then just moves things around
2243 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2245 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2247 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2250 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2253 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2254 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2255 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2258 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2259 SubstituteName->Buffer,
2260 SubstituteName->Length);
2262 FullPathName->Length += sNameLenDelta;
2264 ComponentName->Length += sNameLenDelta;
2266 ComponentName->MaximumLength = ComponentName->Length;
2268 if ( RemainingPath->Buffer)
2271 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2274 try_return( ntStatus);
2278 // Need to re-allocate the buffer
2281 uniPathName.Length = FullPathName->Length -
2282 ComponentName->Length +
2283 SubstituteName->Length;
2285 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2287 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2288 uniPathName.MaximumLength,
2289 AFS_NAME_BUFFER_FOUR_TAG);
2291 if( uniPathName.Buffer == NULL)
2294 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2297 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2299 usPrefixNameLen *= sizeof( WCHAR);
2301 RtlZeroMemory( uniPathName.Buffer,
2302 uniPathName.MaximumLength);
2304 RtlCopyMemory( uniPathName.Buffer,
2305 FullPathName->Buffer,
2308 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2309 SubstituteName->Buffer,
2310 SubstituteName->Length);
2312 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2315 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2316 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2317 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2320 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2322 ComponentName->Length += sNameLenDelta;
2324 ComponentName->MaximumLength = ComponentName->Length;
2326 if ( RemainingPath->Buffer)
2329 RemainingPath->Buffer = uniPathName.Buffer
2330 + (RemainingPath->Buffer - FullPathName->Buffer)
2331 + sNameLenDelta/sizeof( WCHAR);
2336 AFSExFreePool( FullPathName->Buffer);
2339 *FullPathName = uniPathName;
2350 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2354 NTSTATUS ntStatus = STATUS_SUCCESS;
2355 AFSFcb *pFcb = NULL;
2356 AFSObjectInfoCB *pCurrentObject = NULL;
2362 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2363 AFS_TRACE_LEVEL_VERBOSE,
2364 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2365 VolumeCB->ObjectInformation.FileId.Cell,
2366 VolumeCB->ObjectInformation.FileId.Volume,
2367 VolumeCB->ObjectInformation.FileId.Vnode,
2368 VolumeCB->ObjectInformation.FileId.Unique,
2372 // Depending on the reason for invalidation then perform work on the node
2378 case AFS_INVALIDATE_DELETED:
2382 // Mark this volume as invalid
2385 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2387 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2389 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2391 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2393 FILE_NOTIFY_CHANGE_DIR_NAME,
2394 FILE_ACTION_REMOVED);
2396 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2399 pCurrentObject = VolumeCB->ObjectInfoListHead;
2401 while( pCurrentObject != NULL)
2404 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2406 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2410 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2413 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2416 FILE_ACTION_REMOVED);
2418 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2420 pFcb = pCurrentObject->Fcb;
2423 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2428 // Clear out the extents
2429 // And get rid of them (note this involves waiting
2430 // for any writes or reads to the cache to complete)
2433 (VOID) AFSTearDownFcbExtents( pFcb);
2436 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2439 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2448 // Indicate this node requires re-evaluation for the remaining reasons
2451 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2453 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2454 AFS_TRACE_LEVEL_VERBOSE,
2455 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2456 VolumeCB->ObjectInformation.FileId.Cell,
2457 VolumeCB->ObjectInformation.FileId.Volume,
2458 VolumeCB->ObjectInformation.FileId.Vnode,
2459 VolumeCB->ObjectInformation.FileId.Unique);
2461 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY);
2463 if( Reason == AFS_INVALIDATE_FLUSHED ||
2464 Reason == AFS_INVALIDATE_DATA_VERSION)
2467 VolumeCB->ObjectInformation.DataVersion.QuadPart = (ULONGLONG)-1;
2471 // Notify anyone that cares
2474 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2476 if( Reason == AFS_INVALIDATE_CREDS)
2478 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2481 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2483 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2487 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2490 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2493 FILE_ACTION_MODIFIED);
2496 // Volume invalidations require all objects in the volume be re-verified
2499 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2502 pCurrentObject = VolumeCB->ObjectInfoListHead;
2504 while( pCurrentObject != NULL)
2507 pCurrentObject->Expiration.QuadPart = 0;
2509 pCurrentObject->TargetFileId.Vnode = 0;
2511 pCurrentObject->TargetFileId.Unique = 0;
2513 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2514 AFS_TRACE_LEVEL_VERBOSE,
2515 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2516 pCurrentObject->FileId.Cell,
2517 pCurrentObject->FileId.Volume,
2518 pCurrentObject->FileId.Vnode,
2519 pCurrentObject->FileId.Unique);
2521 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
2523 if( Reason == AFS_INVALIDATE_FLUSHED ||
2524 Reason == AFS_INVALIDATE_DATA_VERSION)
2527 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
2529 if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
2532 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2533 AFS_TRACE_LEVEL_VERBOSE,
2534 "AFSInvalidateVolume Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
2535 pCurrentObject->FileId.Cell,
2536 pCurrentObject->FileId.Volume,
2537 pCurrentObject->FileId.Vnode,
2538 pCurrentObject->FileId.Unique);
2540 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2544 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2546 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2550 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2553 if( Reason == AFS_INVALIDATE_CREDS)
2555 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2558 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2560 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2564 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2567 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2570 FILE_ACTION_MODIFIED);
2572 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2575 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2586 AFSVerifyEntry( IN GUID *AuthGroup,
2587 IN AFSDirectoryCB *DirEntry)
2590 NTSTATUS ntStatus = STATUS_SUCCESS;
2591 AFSDirEnumEntry *pDirEnumEntry = NULL;
2592 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2593 IO_STATUS_BLOCK stIoStatus;
2598 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2599 AFS_TRACE_LEVEL_VERBOSE_2,
2600 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2601 &DirEntry->NameInformation.FileName,
2602 pObjectInfo->FileId.Cell,
2603 pObjectInfo->FileId.Volume,
2604 pObjectInfo->FileId.Vnode,
2605 pObjectInfo->FileId.Unique);
2607 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2612 if( !NT_SUCCESS( ntStatus))
2615 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2616 AFS_TRACE_LEVEL_ERROR,
2617 "AFSValidateEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2618 &DirEntry->NameInformation.FileName,
2619 pObjectInfo->FileId.Cell,
2620 pObjectInfo->FileId.Volume,
2621 pObjectInfo->FileId.Vnode,
2622 pObjectInfo->FileId.Unique,
2625 try_return( ntStatus);
2629 // Check the data version of the file
2632 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2633 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2636 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2637 AFS_TRACE_LEVEL_VERBOSE,
2638 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2639 pObjectInfo->DataVersion.QuadPart,
2640 &DirEntry->NameInformation.FileName,
2641 pObjectInfo->FileId.Cell,
2642 pObjectInfo->FileId.Volume,
2643 pObjectInfo->FileId.Vnode,
2644 pObjectInfo->FileId.Unique);
2647 // We are ok, just get out
2650 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2652 try_return( ntStatus = STATUS_SUCCESS);
2656 // New data version so we will need to process the node based on the type
2659 switch( pDirEnumEntry->FileType)
2662 case AFS_FILE_TYPE_MOUNTPOINT:
2666 // For a mount point we need to ensure the target is the same
2669 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2670 &pDirEnumEntry->TargetFileId))
2676 // Update the metadata for the entry
2679 ntStatus = AFSUpdateMetaData( DirEntry,
2682 if( NT_SUCCESS( ntStatus))
2685 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2691 case AFS_FILE_TYPE_SYMLINK:
2694 ASSERT( pDirEnumEntry->TargetNameLength > 0);
2697 // Update the metadata for the entry
2700 ntStatus = AFSUpdateMetaData( DirEntry,
2703 if( NT_SUCCESS( ntStatus))
2706 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2712 case AFS_FILE_TYPE_FILE:
2714 FILE_OBJECT * pCCFileObject = NULL;
2715 BOOLEAN bPurgeExtents = FALSE;
2717 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2719 bPurgeExtents = TRUE;
2721 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2722 AFS_TRACE_LEVEL_VERBOSE,
2723 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2724 &DirEntry->NameInformation.FileName,
2725 pObjectInfo->FileId.Cell,
2726 pObjectInfo->FileId.Volume,
2727 pObjectInfo->FileId.Vnode,
2728 pObjectInfo->FileId.Unique);
2730 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2734 // Update the metadata for the entry
2737 ntStatus = AFSUpdateMetaData( DirEntry,
2740 if( !NT_SUCCESS( ntStatus))
2743 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2744 AFS_TRACE_LEVEL_ERROR,
2745 "AFSInvalidateCache Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2746 &DirEntry->NameInformation.FileName,
2747 pObjectInfo->FileId.Cell,
2748 pObjectInfo->FileId.Volume,
2749 pObjectInfo->FileId.Vnode,
2750 pObjectInfo->FileId.Unique,
2756 if( pObjectInfo->Fcb != NULL)
2759 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2760 AFS_TRACE_LEVEL_VERBOSE,
2761 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2762 &DirEntry->NameInformation.FileName,
2763 pObjectInfo->FileId.Cell,
2764 pObjectInfo->FileId.Volume,
2765 pObjectInfo->FileId.Vnode,
2766 pObjectInfo->FileId.Unique);
2768 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2774 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2779 if( !NT_SUCCESS( stIoStatus.Status))
2782 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2783 AFS_TRACE_LEVEL_ERROR,
2784 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2785 &DirEntry->NameInformation.FileName,
2786 pObjectInfo->FileId.Cell,
2787 pObjectInfo->FileId.Volume,
2788 pObjectInfo->FileId.Vnode,
2789 pObjectInfo->FileId.Unique,
2791 stIoStatus.Information);
2793 ntStatus = stIoStatus.Status;
2799 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2805 __except( EXCEPTION_EXECUTE_HANDLER)
2807 ntStatus = GetExceptionCode();
2809 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2810 AFS_TRACE_LEVEL_ERROR,
2811 "AFSVerifyEntry CcFlushCache or CcPurgeCacheSection Exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2812 &DirEntry->NameInformation.FileName,
2813 pObjectInfo->FileId.Cell,
2814 pObjectInfo->FileId.Volume,
2815 pObjectInfo->FileId.Vnode,
2816 pObjectInfo->FileId.Unique,
2820 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2824 AFSFlushExtents( pObjectInfo->Fcb);
2828 // Reacquire the Fcb to purge the cache
2831 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2832 AFS_TRACE_LEVEL_VERBOSE,
2833 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2834 &pObjectInfo->Fcb->NPFcb->Resource,
2835 PsGetCurrentThread());
2837 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2841 // Update file sizes
2844 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2845 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2846 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2848 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2850 if ( pCCFileObject != NULL)
2852 CcSetFileSizes( pCCFileObject,
2853 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
2856 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2860 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2861 AFS_TRACE_LEVEL_WARNING,
2862 "AFSValidateEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2863 &DirEntry->NameInformation.FileName,
2864 pObjectInfo->FileId.Cell,
2865 pObjectInfo->FileId.Volume,
2866 pObjectInfo->FileId.Vnode,
2867 pObjectInfo->FileId.Unique);
2870 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2875 case AFS_FILE_TYPE_DIRECTORY:
2878 AFSFcb *pCurrentFcb = NULL;
2879 AFSDirectoryCB *pCurrentDirEntry = NULL;
2882 // For a directory or root entry flush the content of
2883 // the directory enumeration.
2886 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2889 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2890 AFS_TRACE_LEVEL_VERBOSE_2,
2891 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2892 &DirEntry->NameInformation.FileName,
2893 pObjectInfo->FileId.Cell,
2894 pObjectInfo->FileId.Volume,
2895 pObjectInfo->FileId.Vnode,
2896 pObjectInfo->FileId.Unique);
2898 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2901 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
2904 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2906 if ( !NT_SUCCESS( ntStatus))
2909 try_return( ntStatus);
2914 // Update the metadata for the entry
2917 ntStatus = AFSUpdateMetaData( DirEntry,
2920 if( NT_SUCCESS( ntStatus))
2923 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2929 case AFS_FILE_TYPE_DFSLINK:
2932 UNICODE_STRING uniTargetName;
2935 // For a DFS link need to check the target name has not changed
2938 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
2940 uniTargetName.MaximumLength = uniTargetName.Length;
2942 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
2944 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
2947 if( DirEntry->NameInformation.TargetName.Length == 0 ||
2948 RtlCompareUnicodeString( &uniTargetName,
2949 &DirEntry->NameInformation.TargetName,
2954 // Update the target name
2957 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
2959 uniTargetName.Buffer,
2960 uniTargetName.Length);
2962 if( !NT_SUCCESS( ntStatus))
2965 AFSReleaseResource( &DirEntry->NonPaged->Lock);
2971 AFSReleaseResource( &DirEntry->NonPaged->Lock);
2974 // Update the metadata for the entry
2977 ntStatus = AFSUpdateMetaData( DirEntry,
2980 if( NT_SUCCESS( ntStatus))
2983 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2991 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2992 AFS_TRACE_LEVEL_WARNING,
2993 "AFSVerifyEntry Attempt to verify node of type %d\n",
2994 pObjectInfo->FileType);
3001 if( pDirEnumEntry != NULL)
3004 AFSExFreePool( pDirEnumEntry);
3012 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3015 NTSTATUS ntStatus = STATUS_SUCCESS;
3016 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3017 ULONGLONG ullIndex = 0;
3018 AFSVolumeCB *pVolumeCB = NULL;
3019 AFSFcb *pFcb = NULL;
3020 AFSObjectInfoCB *pCurrentObject = NULL;
3025 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3026 AFS_TRACE_LEVEL_VERBOSE,
3027 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3028 VolumeStatus->Online,
3029 VolumeStatus->FileID.Cell,
3030 VolumeStatus->FileID.Volume);
3033 // Need to locate the Fcb for the directory to purge
3036 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3037 AFS_TRACE_LEVEL_VERBOSE,
3038 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3039 &pDevExt->Specific.RDR.VolumeTreeLock,
3040 PsGetCurrentThread());
3042 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3045 // Locate the volume node
3048 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3050 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3052 (AFSBTreeEntry **)&pVolumeCB);
3054 if( pVolumeCB != NULL)
3057 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3059 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3062 // Set the volume state accordingly
3065 if( VolumeStatus->Online)
3068 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3073 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3076 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3079 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3081 while( pCurrentObject != NULL)
3084 if( VolumeStatus->Online)
3087 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3089 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3091 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3096 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3099 pFcb = pCurrentObject->Fcb;
3102 !(VolumeStatus->Online) &&
3103 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3106 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3107 AFS_TRACE_LEVEL_ERROR,
3108 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3109 VolumeStatus->FileID.Cell,
3110 VolumeStatus->FileID.Volume);
3113 // Clear out the extents
3116 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3117 AFS_TRACE_LEVEL_VERBOSE,
3118 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3119 &pFcb->NPFcb->Specific.File.ExtentsResource,
3120 PsGetCurrentThread());
3122 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3125 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3127 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3131 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3132 AFS_TRACE_LEVEL_VERBOSE,
3133 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3134 &pFcb->NPFcb->Specific.File.ExtentsResource,
3135 PsGetCurrentThread());
3137 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3140 // And get rid of them (note this involves waiting
3141 // for any writes or reads to the cache to complete)
3144 (VOID) AFSTearDownFcbExtents( pFcb);
3147 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3150 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3152 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3157 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3165 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3168 NTSTATUS ntStatus = STATUS_SUCCESS;
3173 if( AFSGlobalRoot == NULL)
3176 try_return( ntStatus);
3179 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3183 // Set the network state according to the information
3186 if( NetworkStatus->Online)
3189 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3194 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3197 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3208 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3212 NTSTATUS ntStatus = STATUS_SUCCESS;
3213 BOOLEAN bAcquiredLock = FALSE;
3214 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3215 AFSFcb *pFcb = NULL;
3220 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3221 AFS_TRACE_LEVEL_VERBOSE,
3222 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3223 ObjectInfo->FileId.Cell,
3224 ObjectInfo->FileId.Volume,
3225 ObjectInfo->FileId.Vnode,
3226 ObjectInfo->FileId.Unique);
3228 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3231 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3232 AFS_TRACE_LEVEL_VERBOSE,
3233 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3234 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3235 PsGetCurrentThread());
3237 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3240 bAcquiredLock = TRUE;
3244 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3247 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3248 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3251 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3252 AFS_TRACE_LEVEL_ERROR,
3253 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
3254 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3255 ObjectInfo->FileId.Cell,
3256 ObjectInfo->FileId.Volume,
3257 ObjectInfo->FileId.Vnode,
3258 ObjectInfo->FileId.Unique);
3262 // Reset the directory list information by clearing all valid entries
3265 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3267 while( pCurrentDirEntry != NULL)
3270 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3272 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3276 // If this entry has been deleted then process it here
3279 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3280 pCurrentDirEntry->OpenReferenceCount == 0)
3283 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3284 AFS_TRACE_LEVEL_VERBOSE,
3285 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3287 &pCurrentDirEntry->NameInformation.FileName);
3289 AFSDeleteDirEntry( ObjectInfo,
3295 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3297 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3298 AFS_TRACE_LEVEL_VERBOSE,
3299 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3301 pCurrentDirEntry->OpenReferenceCount);
3304 // We pull the short name from the parent tree since it could change below
3307 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3310 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3311 AFS_TRACE_LEVEL_VERBOSE,
3312 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3314 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3315 &pCurrentDirEntry->NameInformation.FileName);
3317 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3320 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3325 pCurrentDirEntry = pNextDirEntry;
3329 // Reget the directory contents
3332 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3335 if ( !NT_SUCCESS( ntStatus))
3337 try_return( ntStatus);
3341 // Now start again and tear down any entries not valid
3344 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3346 while( pCurrentDirEntry != NULL)
3349 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3351 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3354 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3355 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3358 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3361 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3363 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3364 AFS_TRACE_LEVEL_VERBOSE,
3365 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3367 &pCurrentDirEntry->NameInformation.FileName);
3369 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3374 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3377 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3378 AFS_TRACE_LEVEL_VERBOSE,
3379 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3381 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3382 &pCurrentDirEntry->NameInformation.FileName);
3386 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3388 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3389 AFS_TRACE_LEVEL_VERBOSE,
3390 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3392 &pCurrentDirEntry->NameInformation.FileName);
3397 pCurrentDirEntry = pNextDirEntry;
3402 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3403 AFS_TRACE_LEVEL_VERBOSE,
3404 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3406 pCurrentDirEntry->OpenReferenceCount);
3408 if( pCurrentDirEntry->OpenReferenceCount == 0)
3411 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3412 AFS_TRACE_LEVEL_VERBOSE,
3413 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3414 &pCurrentDirEntry->NameInformation.FileName,
3415 ObjectInfo->FileId.Cell,
3416 ObjectInfo->FileId.Volume,
3417 ObjectInfo->FileId.Vnode,
3418 ObjectInfo->FileId.Unique);
3420 AFSDeleteDirEntry( ObjectInfo,
3426 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3427 AFS_TRACE_LEVEL_VERBOSE,
3428 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3430 &pCurrentDirEntry->NameInformation.FileName,
3431 ObjectInfo->FileId.Cell,
3432 ObjectInfo->FileId.Volume,
3433 ObjectInfo->FileId.Vnode,
3434 ObjectInfo->FileId.Unique);
3436 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3438 AFSRemoveNameEntry( ObjectInfo,
3442 pCurrentDirEntry = pNextDirEntry;
3446 if( !AFSValidateDirList( ObjectInfo))
3449 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3458 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3466 AFSIsVolumeFID( IN AFSFileID *FileID)
3469 BOOLEAN bIsVolume = FALSE;
3471 if( FileID->Vnode == 1 &&
3472 FileID->Unique == 1)
3482 AFSIsFinalNode( IN AFSFcb *Fcb)
3485 BOOLEAN bIsFinalNode = FALSE;
3487 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3488 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3489 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3490 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3491 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3494 bIsFinalNode = TRUE;
3499 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3500 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3503 return bIsFinalNode;
3507 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3508 IN AFSDirEnumEntry *DirEnumEntry)
3511 NTSTATUS ntStatus = STATUS_SUCCESS;
3512 UNICODE_STRING uniTargetName;
3513 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3518 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3520 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3522 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3524 pObjectInfo->FileType = DirEnumEntry->FileType;
3526 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3528 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3530 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3532 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3534 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3536 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3538 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3540 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3543 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3546 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3547 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3550 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3553 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3555 pObjectInfo->Links = DirEnumEntry->Links;
3557 if( DirEnumEntry->TargetNameLength > 0)
3561 // Update the target name information if needed
3564 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3566 uniTargetName.MaximumLength = uniTargetName.Length;
3568 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3570 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3573 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3574 RtlCompareUnicodeString( &uniTargetName,
3575 &DirEntry->NameInformation.TargetName,
3580 // Update the target name
3583 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3585 uniTargetName.Buffer,
3586 uniTargetName.Length);
3588 if( !NT_SUCCESS( ntStatus))
3591 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3593 try_return( ntStatus);
3597 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3599 else if( DirEntry->NameInformation.TargetName.Length > 0)
3602 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3605 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3606 DirEntry->NameInformation.TargetName.Buffer != NULL)
3608 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
3611 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3613 DirEntry->NameInformation.TargetName.Length = 0;
3614 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3615 DirEntry->NameInformation.TargetName.Buffer = NULL;
3617 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3629 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3631 IN BOOLEAN PurgeContent,
3632 IN BOOLEAN FastCall)
3635 NTSTATUS ntStatus = STATUS_SUCCESS;
3636 LARGE_INTEGER liSystemTime;
3637 AFSDirEnumEntry *pDirEnumEntry = NULL;
3638 AFSFcb *pCurrentFcb = NULL;
3639 BOOLEAN bReleaseFcb = FALSE;
3640 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3646 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3650 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3651 AFS_TRACE_LEVEL_VERBOSE_2,
3652 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3653 &DirEntry->NameInformation.FileName,
3654 pObjectInfo->FileId.Cell,
3655 pObjectInfo->FileId.Volume,
3656 pObjectInfo->FileId.Vnode,
3657 pObjectInfo->FileId.Unique);
3660 // If this is a fake node then bail since the service knows nothing about it
3663 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3666 try_return( ntStatus);
3670 pObjectInfo->Fcb != NULL)
3673 pCurrentFcb = pObjectInfo->Fcb;
3675 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3678 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3679 AFS_TRACE_LEVEL_VERBOSE,
3680 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3681 &pCurrentFcb->NPFcb->Resource,
3682 PsGetCurrentThread());
3684 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3692 // This routine ensures that the current entry is valid by:
3694 // 1) Checking that the expiration time is non-zero and after where we
3698 KeQuerySystemTime( &liSystemTime);
3700 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3701 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3702 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3703 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3706 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3707 AFS_TRACE_LEVEL_VERBOSE_2,
3708 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3709 &DirEntry->NameInformation.FileName,
3710 pObjectInfo->FileId.Cell,
3711 pObjectInfo->FileId.Volume,
3712 pObjectInfo->FileId.Vnode,
3713 pObjectInfo->FileId.Unique);
3715 try_return( ntStatus);
3719 // This node requires updating
3722 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3727 if( !NT_SUCCESS( ntStatus))
3730 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3731 AFS_TRACE_LEVEL_ERROR,
3732 "AFSValidateEntry Failed to evaluate entry %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3733 &DirEntry->NameInformation.FileName,
3734 pObjectInfo->FileId.Cell,
3735 pObjectInfo->FileId.Volume,
3736 pObjectInfo->FileId.Vnode,
3737 pObjectInfo->FileId.Unique,
3741 // Failed validation of node so return access-denied
3744 try_return( ntStatus);
3747 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3748 AFS_TRACE_LEVEL_VERBOSE,
3749 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3750 &DirEntry->NameInformation.FileName,
3751 pObjectInfo->FileId.Cell,
3752 pObjectInfo->FileId.Volume,
3753 pObjectInfo->FileId.Vnode,
3754 pObjectInfo->FileId.Unique,
3755 pObjectInfo->DataVersion.QuadPart,
3756 pDirEnumEntry->DataVersion.QuadPart,
3757 pDirEnumEntry->FileType);
3761 // Based on the file type, process the node
3764 switch( pDirEnumEntry->FileType)
3767 case AFS_FILE_TYPE_MOUNTPOINT:
3771 // Update the metadata for the entry
3774 ntStatus = AFSUpdateMetaData( DirEntry,
3777 if( NT_SUCCESS( ntStatus))
3780 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3786 case AFS_FILE_TYPE_SYMLINK:
3787 case AFS_FILE_TYPE_DFSLINK:
3791 // Update the metadata for the entry
3794 ntStatus = AFSUpdateMetaData( DirEntry,
3797 if( NT_SUCCESS( ntStatus))
3800 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3806 case AFS_FILE_TYPE_FILE:
3810 // For a file where the data version has become invalid we need to
3811 // fail any current extent requests and purge the cache for the file
3812 // Can't hold the Fcb resource while doing this
3815 if( pCurrentFcb != NULL &&
3816 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3817 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3820 IO_STATUS_BLOCK stIoStatus;
3821 BOOLEAN bPurgeExtents = FALSE;
3823 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3824 AFS_TRACE_LEVEL_VERBOSE_2,
3825 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3826 &DirEntry->NameInformation.FileName,
3827 pObjectInfo->FileId.Cell,
3828 pObjectInfo->FileId.Volume,
3829 pObjectInfo->FileId.Vnode,
3830 pObjectInfo->FileId.Unique);
3832 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3834 bPurgeExtents = TRUE;
3836 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3837 AFS_TRACE_LEVEL_VERBOSE,
3838 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3839 &DirEntry->NameInformation.FileName,
3840 pObjectInfo->FileId.Cell,
3841 pObjectInfo->FileId.Volume,
3842 pObjectInfo->FileId.Vnode,
3843 pObjectInfo->FileId.Unique);
3845 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3851 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
3856 if( !NT_SUCCESS( stIoStatus.Status))
3859 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3860 AFS_TRACE_LEVEL_ERROR,
3861 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3862 &DirEntry->NameInformation.FileName,
3863 pObjectInfo->FileId.Cell,
3864 pObjectInfo->FileId.Volume,
3865 pObjectInfo->FileId.Vnode,
3866 pObjectInfo->FileId.Unique,
3868 stIoStatus.Information);
3870 ntStatus = stIoStatus.Status;
3876 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3882 __except( EXCEPTION_EXECUTE_HANDLER)
3884 ntStatus = GetExceptionCode();
3886 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3887 AFS_TRACE_LEVEL_ERROR,
3888 "AFSValidateEntry CcFlushCache or CcPurgeCacheSection exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3889 &DirEntry->NameInformation.FileName,
3890 pObjectInfo->FileId.Cell,
3891 pObjectInfo->FileId.Volume,
3892 pObjectInfo->FileId.Vnode,
3893 pObjectInfo->FileId.Unique,
3898 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3902 AFSFlushExtents( pCurrentFcb);
3906 // Reacquire the Fcb to purge the cache
3909 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3910 AFS_TRACE_LEVEL_VERBOSE,
3911 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3912 &pCurrentFcb->NPFcb->Resource,
3913 PsGetCurrentThread());
3915 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3920 // Update the metadata for the entry
3923 ntStatus = AFSUpdateMetaData( DirEntry,
3926 if( !NT_SUCCESS( ntStatus))
3929 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3930 AFS_TRACE_LEVEL_ERROR,
3931 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3932 &DirEntry->NameInformation.FileName,
3933 pObjectInfo->FileId.Cell,
3934 pObjectInfo->FileId.Volume,
3935 pObjectInfo->FileId.Vnode,
3936 pObjectInfo->FileId.Unique,
3942 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3945 // Update file sizes
3948 if( pObjectInfo->Fcb != NULL)
3950 FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3952 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3953 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3954 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3956 if ( pCCFileObject != NULL)
3958 CcSetFileSizes( pCCFileObject,
3959 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3966 case AFS_FILE_TYPE_DIRECTORY:
3969 AFSDirectoryCB *pCurrentDirEntry = NULL;
3971 if( pCurrentFcb != NULL &&
3972 pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3976 // For a directory or root entry flush the content of
3977 // the directory enumeration.
3980 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3981 AFS_TRACE_LEVEL_VERBOSE,
3982 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3983 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3984 PsGetCurrentThread());
3986 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3989 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3990 AFS_TRACE_LEVEL_VERBOSE_2,
3991 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3992 &DirEntry->NameInformation.FileName,
3993 pObjectInfo->FileId.Cell,
3994 pObjectInfo->FileId.Volume,
3995 pObjectInfo->FileId.Vnode,
3996 pObjectInfo->FileId.Unique);
3998 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4001 AFSValidateDirectoryCache( pCurrentFcb->ObjectInformation,
4004 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4007 if( !NT_SUCCESS( ntStatus))
4010 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4011 AFS_TRACE_LEVEL_ERROR,
4012 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4013 &DirEntry->NameInformation.FileName,
4014 pObjectInfo->FileId.Cell,
4015 pObjectInfo->FileId.Volume,
4016 pObjectInfo->FileId.Vnode,
4017 pObjectInfo->FileId.Unique,
4025 // Update the metadata for the entry
4028 ntStatus = AFSUpdateMetaData( DirEntry,
4031 if( NT_SUCCESS( ntStatus))
4034 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4042 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4043 AFS_TRACE_LEVEL_WARNING,
4044 "AFSValidateEntry Attempt to verify node of type %d\n",
4045 pObjectInfo->FileType);
4055 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4058 if( pDirEnumEntry != NULL)
4061 AFSExFreePool( pDirEnumEntry);
4069 AFSInitializeSpecialShareNameList()
4072 NTSTATUS ntStatus = STATUS_SUCCESS;
4073 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4074 AFSObjectInfoCB *pObjectInfoCB = NULL;
4075 UNICODE_STRING uniShareName;
4076 ULONG ulEntryLength = 0;
4077 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4082 RtlInitUnicodeString( &uniShareName,
4085 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4088 if( pObjectInfoCB == NULL)
4091 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4094 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4095 AFS_TRACE_LEVEL_VERBOSE,
4096 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
4099 pObjectInfoCB->ObjectReferenceCount = 1;
4101 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4103 ulEntryLength = sizeof( AFSDirectoryCB) +
4104 uniShareName.Length;
4106 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4110 if( pDirNode == NULL)
4113 AFSDeleteObjectInfo( pObjectInfoCB);
4115 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4118 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4119 sizeof( AFSNonPagedDirectoryCB),
4120 AFS_DIR_ENTRY_NP_TAG);
4122 if( pNonPagedDirEntry == NULL)
4125 ExFreePool( pDirNode);
4127 AFSDeleteObjectInfo( pObjectInfoCB);
4129 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4132 RtlZeroMemory( pDirNode,
4135 RtlZeroMemory( pNonPagedDirEntry,
4136 sizeof( AFSNonPagedDirectoryCB));
4138 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4140 pDirNode->NonPaged = pNonPagedDirEntry;
4142 pDirNode->ObjectInformation = pObjectInfoCB;
4148 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
4150 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4152 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4154 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4156 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4157 uniShareName.Buffer,
4158 pDirNode->NameInformation.FileName.Length);
4160 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4163 AFSSpecialShareNames = pDirNode;
4165 pLastDirNode = pDirNode;
4167 RtlInitUnicodeString( &uniShareName,
4170 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4173 if( pObjectInfoCB == NULL)
4176 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4179 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4180 AFS_TRACE_LEVEL_VERBOSE,
4181 "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
4184 pObjectInfoCB->ObjectReferenceCount = 1;
4186 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4188 ulEntryLength = sizeof( AFSDirectoryCB) +
4189 uniShareName.Length;
4191 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4195 if( pDirNode == NULL)
4198 AFSDeleteObjectInfo( pObjectInfoCB);
4200 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4203 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4204 sizeof( AFSNonPagedDirectoryCB),
4205 AFS_DIR_ENTRY_NP_TAG);
4207 if( pNonPagedDirEntry == NULL)
4210 ExFreePool( pDirNode);
4212 AFSDeleteObjectInfo( pObjectInfoCB);
4214 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4217 RtlZeroMemory( pDirNode,
4220 RtlZeroMemory( pNonPagedDirEntry,
4221 sizeof( AFSNonPagedDirectoryCB));
4223 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4225 pDirNode->NonPaged = pNonPagedDirEntry;
4227 pDirNode->ObjectInformation = pObjectInfoCB;
4233 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
4235 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4237 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4239 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4241 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4242 uniShareName.Buffer,
4243 pDirNode->NameInformation.FileName.Length);
4245 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4248 pLastDirNode->ListEntry.fLink = pDirNode;
4250 pDirNode->ListEntry.bLink = pLastDirNode;
4252 pLastDirNode = pDirNode;
4254 RtlInitUnicodeString( &uniShareName,
4257 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4260 if( pObjectInfoCB == NULL)
4263 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4266 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4267 AFS_TRACE_LEVEL_VERBOSE,
4268 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4271 pObjectInfoCB->ObjectReferenceCount = 1;
4273 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4275 ulEntryLength = sizeof( AFSDirectoryCB) +
4276 uniShareName.Length;
4278 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4282 if( pDirNode == NULL)
4285 AFSDeleteObjectInfo( pObjectInfoCB);
4287 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4290 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4291 sizeof( AFSNonPagedDirectoryCB),
4292 AFS_DIR_ENTRY_NP_TAG);
4294 if( pNonPagedDirEntry == NULL)
4297 ExFreePool( pDirNode);
4299 AFSDeleteObjectInfo( pObjectInfoCB);
4301 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4304 RtlZeroMemory( pDirNode,
4307 RtlZeroMemory( pNonPagedDirEntry,
4308 sizeof( AFSNonPagedDirectoryCB));
4310 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4312 pDirNode->NonPaged = pNonPagedDirEntry;
4314 pDirNode->ObjectInformation = pObjectInfoCB;
4320 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4322 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4324 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4326 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4328 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4329 uniShareName.Buffer,
4330 pDirNode->NameInformation.FileName.Length);
4332 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4335 pLastDirNode->ListEntry.fLink = pDirNode;
4337 pDirNode->ListEntry.bLink = pLastDirNode;
4341 if( !NT_SUCCESS( ntStatus))
4344 if( AFSSpecialShareNames != NULL)
4347 pDirNode = AFSSpecialShareNames;
4349 while( pDirNode != NULL)
4352 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4354 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4356 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4358 ExFreePool( pDirNode->NonPaged);
4360 ExFreePool( pDirNode);
4362 pDirNode = pLastDirNode;
4365 AFSSpecialShareNames = NULL;
4374 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4375 IN UNICODE_STRING *SecondaryName)
4378 AFSDirectoryCB *pDirectoryCB = NULL;
4379 ULONGLONG ullHash = 0;
4380 UNICODE_STRING uniFullShareName;
4386 // Build up the entire name here. We are guaranteed that if there is a
4387 // secondary name, it is pointing to a portion of the share name buffer
4390 if( SecondaryName->Length > 0 &&
4391 SecondaryName->Buffer != NULL)
4394 uniFullShareName = *SecondaryName;
4397 // The calling routine strips off the leading slash so add it back in
4400 uniFullShareName.Buffer--;
4401 uniFullShareName.Length += sizeof( WCHAR);
4402 uniFullShareName.MaximumLength += sizeof( WCHAR);
4405 // And the share name
4408 uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
4409 uniFullShareName.Length += ShareName->Length;
4410 uniFullShareName.MaximumLength += ShareName->Length;
4415 uniFullShareName = *ShareName;
4419 // Generate our hash value
4422 ullHash = AFSGenerateCRC( &uniFullShareName,
4426 // Loop through our special share names to see if this is one of them
4429 pDirectoryCB = AFSSpecialShareNames;
4431 while( pDirectoryCB != NULL)
4434 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4440 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4444 return pDirectoryCB;
4448 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4452 // Block on the queue flush event
4455 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4465 AFSWaitOnQueuedReleases()
4468 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4471 // Block on the queue flush event
4474 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4484 AFSIsEqualFID( IN AFSFileID *FileId1,
4485 IN AFSFileID *FileId2)
4488 BOOLEAN bIsEqual = FALSE;
4490 if( FileId1->Unique == FileId2->Unique &&
4491 FileId1->Vnode == FileId2->Vnode &&
4492 FileId1->Volume == FileId2->Volume &&
4493 FileId1->Cell == FileId2->Cell)
4503 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4506 NTSTATUS ntStatus = STATUS_SUCCESS;
4507 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4512 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4515 // Reset the directory list information
4518 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4520 while( pCurrentDirEntry != NULL)
4523 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4525 if( pCurrentDirEntry->OpenReferenceCount == 0)
4528 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4529 AFS_TRACE_LEVEL_VERBOSE,
4530 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4532 &pCurrentDirEntry->NameInformation.FileName);
4534 AFSDeleteDirEntry( ObjectInfoCB,
4540 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4541 AFS_TRACE_LEVEL_VERBOSE,
4542 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4544 &pCurrentDirEntry->NameInformation.FileName);
4546 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4548 AFSRemoveNameEntry( ObjectInfoCB,
4552 pCurrentDirEntry = pNextDirEntry;
4555 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4557 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4559 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4561 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4563 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4565 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4567 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4568 AFS_TRACE_LEVEL_VERBOSE,
4569 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4570 ObjectInfoCB->FileId.Cell,
4571 ObjectInfoCB->FileId.Volume,
4572 ObjectInfoCB->FileId.Vnode,
4573 ObjectInfoCB->FileId.Unique);
4580 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4583 NTSTATUS ntStatus = STATUS_SUCCESS;
4584 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4585 UNICODE_STRING uniFullName;
4590 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4591 AFS_TRACE_LEVEL_VERBOSE,
4592 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4593 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4594 PsGetCurrentThread());
4596 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4599 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4602 try_return( ntStatus);
4606 // Initialize the root information
4609 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4612 // Enumerate the shares in the volume
4615 ntStatus = AFSEnumerateDirectory( AuthGroup,
4616 &AFSGlobalRoot->ObjectInformation,
4619 if( !NT_SUCCESS( ntStatus))
4622 try_return( ntStatus);
4625 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4628 // Indicate the node is initialized
4631 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4633 uniFullName.MaximumLength = PAGE_SIZE;
4634 uniFullName.Length = 0;
4636 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4637 uniFullName.MaximumLength,
4638 AFS_GENERIC_MEMORY_12_TAG);
4640 if( uniFullName.Buffer == NULL)
4644 // Reset the directory content
4647 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4649 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4651 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4655 // Populate our list of entries in the NP enumeration list
4658 while( pDirGlobalDirNode != NULL)
4661 uniFullName.Buffer[ 0] = L'\\';
4662 uniFullName.Buffer[ 1] = L'\\';
4664 uniFullName.Length = 2 * sizeof( WCHAR);
4666 RtlCopyMemory( &uniFullName.Buffer[ 2],
4667 AFSServerName.Buffer,
4668 AFSServerName.Length);
4670 uniFullName.Length += AFSServerName.Length;
4672 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4674 uniFullName.Length += sizeof( WCHAR);
4676 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4677 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4678 pDirGlobalDirNode->NameInformation.FileName.Length);
4680 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4682 AFSAddConnectionEx( &uniFullName,
4683 RESOURCEDISPLAYTYPE_SHARE,
4686 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4689 AFSExFreePool( uniFullName.Buffer);
4693 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4700 AFSIsRelativeName( IN UNICODE_STRING *Name)
4703 BOOLEAN bIsRelative = FALSE;
4705 if( Name->Buffer[ 0] != L'\\')
4715 AFSUpdateName( IN UNICODE_STRING *Name)
4720 while( usIndex < Name->Length/sizeof( WCHAR))
4723 if( Name->Buffer[ usIndex] == L'/')
4726 Name->Buffer[ usIndex] = L'\\';
4736 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4737 IN OUT ULONG *Flags,
4738 IN WCHAR *NameBuffer,
4739 IN USHORT NameLength)
4742 NTSTATUS ntStatus = STATUS_SUCCESS;
4743 WCHAR *pTmpBuffer = NULL;
4749 // If we have enough space then just move in the name otherwise
4750 // allocate a new buffer
4753 if( TargetName->Length < NameLength)
4756 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4758 AFS_NAME_BUFFER_FIVE_TAG);
4760 if( pTmpBuffer == NULL)
4763 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4766 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4769 AFSExFreePool( TargetName->Buffer);
4772 TargetName->MaximumLength = NameLength;
4774 TargetName->Buffer = pTmpBuffer;
4776 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4779 TargetName->Length = NameLength;
4781 RtlCopyMemory( TargetName->Buffer,
4783 TargetName->Length);
4786 // Update the name in the buffer
4789 AFSUpdateName( TargetName);
4800 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4801 IN ULONG InitialElementCount)
4804 AFSNameArrayHdr *pNameArray = NULL;
4805 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4810 if( InitialElementCount == 0)
4813 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
4816 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
4817 sizeof( AFSNameArrayHdr) +
4818 (InitialElementCount * sizeof( AFSNameArrayCB)),
4819 AFS_NAME_ARRAY_TAG);
4821 if( pNameArray == NULL)
4824 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4825 AFS_TRACE_LEVEL_ERROR,
4826 "AFSInitNameArray Failed to allocate name array\n");
4828 try_return( pNameArray);
4831 RtlZeroMemory( pNameArray,
4832 sizeof( AFSNameArrayHdr) +
4833 (InitialElementCount * sizeof( AFSNameArrayCB)));
4835 pNameArray->MaxElementCount = InitialElementCount;
4837 if( DirectoryCB != NULL)
4840 pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
4842 InterlockedIncrement( &pNameArray->Count);
4844 InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
4846 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4847 AFS_TRACE_LEVEL_VERBOSE,
4848 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
4849 &DirectoryCB->NameInformation.FileName,
4851 DirectoryCB->OpenReferenceCount);
4853 pNameArray->CurrentEntry->DirectoryCB = DirectoryCB;
4855 pNameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
4857 pNameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
4869 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
4870 IN UNICODE_STRING *Path,
4871 IN AFSDirectoryCB *DirectoryCB)
4874 NTSTATUS ntStatus = STATUS_SUCCESS;
4875 AFSNameArrayCB *pCurrentElement = NULL;
4876 UNICODE_STRING uniComponentName, uniRemainingPath;
4877 AFSObjectInfoCB *pCurrentObject = NULL;
4878 ULONG ulTotalCount = 0;
4880 USHORT usLength = 0;
4886 // Init some info in the header
4889 pCurrentElement = &NameArray->ElementArray[ 0];
4891 NameArray->CurrentEntry = pCurrentElement;
4894 // The first entry points at the root
4897 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
4899 InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4901 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4902 AFS_TRACE_LEVEL_VERBOSE,
4903 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
4904 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4905 pCurrentElement->DirectoryCB,
4906 pCurrentElement->DirectoryCB->OpenReferenceCount);
4908 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
4910 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
4912 NameArray->Count = 1;
4914 NameArray->LinkCount = 0;
4917 // If the root is the parent then we are done ...
4920 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
4922 try_return( ntStatus);
4934 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
4935 IN AFSNameArrayHdr *RelatedNameArray,
4936 IN AFSDirectoryCB *DirectoryCB)
4939 NTSTATUS ntStatus = STATUS_SUCCESS;
4940 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
4941 UNICODE_STRING uniComponentName, uniRemainingPath;
4942 AFSObjectInfoCB *pObjectInfo = NULL;
4943 ULONG ulTotalCount = 0;
4945 USHORT usLength = 0;
4951 // Init some info in the header
4954 pCurrentElement = &NameArray->ElementArray[ 0];
4956 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
4958 NameArray->Count = 0;
4960 NameArray->LinkCount = RelatedNameArray->LinkCount;
4963 // Populate the name array with the data from the related array
4969 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
4971 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
4973 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
4975 InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4977 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4978 AFS_TRACE_LEVEL_VERBOSE,
4979 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
4980 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4981 pCurrentElement->DirectoryCB,
4982 pCurrentElement->DirectoryCB->OpenReferenceCount);
4984 InterlockedIncrement( &NameArray->Count);
4986 if( pCurrentElement->DirectoryCB == DirectoryCB ||
4987 NameArray->Count == RelatedNameArray->Count)
4999 pCurrentRelatedElement++;
5002 if( NameArray->Count > 0)
5004 NameArray->CurrentEntry = pCurrentElement;
5012 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5015 NTSTATUS ntStatus = STATUS_SUCCESS;
5016 AFSNameArrayCB *pCurrentElement = NULL;
5021 pCurrentElement = &NameArray->ElementArray[ 0];
5026 if( pCurrentElement->DirectoryCB == NULL)
5032 InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5034 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5035 AFS_TRACE_LEVEL_VERBOSE,
5036 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
5037 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5038 pCurrentElement->DirectoryCB,
5039 pCurrentElement->DirectoryCB->OpenReferenceCount);
5044 AFSExFreePool( NameArray);
5051 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5052 IN AFSDirectoryCB *DirEntry)
5055 NTSTATUS ntStatus = STATUS_SUCCESS;
5056 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5061 if( NameArray->Count == NameArray->MaxElementCount)
5064 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5067 if( NameArray->CurrentEntry != NULL &&
5068 NameArray->CurrentEntry->DirectoryCB == DirEntry)
5071 try_return( ntStatus);
5074 if( NameArray->Count > 0)
5077 NameArray->CurrentEntry++;
5081 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5084 InterlockedIncrement( &NameArray->Count);
5086 InterlockedIncrement( &DirEntry->OpenReferenceCount);
5088 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5089 AFS_TRACE_LEVEL_VERBOSE,
5090 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
5091 &DirEntry->NameInformation.FileName,
5093 DirEntry->OpenReferenceCount);
5095 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5097 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5099 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5110 AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
5111 IN AFSDirectoryCB *DirectoryCB)
5114 ASSERT( NameArray->CurrentEntry != NULL);
5116 InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5118 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5119 AFS_TRACE_LEVEL_VERBOSE,
5120 "AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
5121 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5122 NameArray->CurrentEntry->DirectoryCB,
5123 NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5125 InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5127 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5128 AFS_TRACE_LEVEL_VERBOSE,
5129 "AFSReplaceCurrentElement Increment count on %wZ DE %p Cnt %d\n",
5130 &DirectoryCB->NameInformation.FileName,
5132 DirectoryCB->OpenReferenceCount);
5134 NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
5136 NameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
5138 NameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
5140 if( DirectoryCB->ObjectInformation->ParentObjectInformation == NULL)
5143 SetFlag( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5150 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5153 AFSDirectoryCB *pCurrentDirEntry = NULL;
5158 if( NameArray->Count == 0)
5160 try_return( pCurrentDirEntry);
5163 InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5165 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5166 AFS_TRACE_LEVEL_VERBOSE,
5167 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5168 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5169 NameArray->CurrentEntry->DirectoryCB,
5170 NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5172 NameArray->CurrentEntry->DirectoryCB = NULL;
5174 if( InterlockedDecrement( &NameArray->Count) == 0)
5176 NameArray->CurrentEntry = NULL;
5180 NameArray->CurrentEntry--;
5181 pCurrentDirEntry = NameArray->CurrentEntry->DirectoryCB;
5189 return pCurrentDirEntry;
5193 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5196 AFSDirectoryCB *pDirEntry = NULL;
5197 AFSNameArrayCB *pElement = NULL;
5202 if( NameArray->Count == 0 ||
5203 NameArray->Count == 1)
5206 try_return( pDirEntry = NULL);
5209 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5211 pDirEntry = pElement->DirectoryCB;
5222 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5223 IN AFSDirectoryCB *DirEntry)
5226 AFSNameArrayCB *pCurrentElement = NULL;
5227 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5232 pCurrentElement = &NameArray->ElementArray[ 0];
5237 if( pCurrentElement->DirectoryCB == NULL)
5243 InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5245 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5246 AFS_TRACE_LEVEL_VERBOSE,
5247 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5248 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5249 pCurrentElement->DirectoryCB,
5250 pCurrentElement->DirectoryCB->OpenReferenceCount);
5255 RtlZeroMemory( NameArray,
5256 sizeof( AFSNameArrayHdr) +
5257 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5259 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5261 if( DirEntry != NULL)
5264 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5266 InterlockedIncrement( &NameArray->Count);
5268 InterlockedIncrement( &DirEntry->OpenReferenceCount);
5270 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5271 AFS_TRACE_LEVEL_VERBOSE,
5272 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5273 &DirEntry->NameInformation.FileName,
5275 DirEntry->OpenReferenceCount);
5277 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5279 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5281 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5289 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5292 AFSNameArrayCB *pCurrentElement = NULL;
5294 pCurrentElement = &NameArray->ElementArray[ 0];
5296 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5298 while( pCurrentElement->DirectoryCB != NULL)
5301 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5302 pCurrentElement->FileId.Cell,
5303 pCurrentElement->FileId.Volume,
5304 pCurrentElement->FileId.Vnode,
5305 pCurrentElement->FileId.Unique,
5306 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5311 AFSPrint("AFSDumpNameArray End\n\n");
5317 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5321 // Depending on the type of node, set the event
5324 switch( Fcb->Header.NodeTypeCode)
5327 case AFS_DIRECTORY_FCB:
5330 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5334 InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5343 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5347 InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5357 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5361 // Depending on the type of node, set the event
5364 switch( Fcb->Header.NodeTypeCode)
5367 case AFS_DIRECTORY_FCB:
5370 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5372 if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
5375 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5385 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5387 if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
5390 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5401 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5404 BOOLEAN bIsInProcess = FALSE;
5409 if( ObjectInfo->Fcb == NULL)
5412 try_return( bIsInProcess);
5416 // Depending on the type of node, set the event
5419 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5422 case AFS_DIRECTORY_FCB:
5425 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5428 bIsInProcess = TRUE;
5438 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5441 bIsInProcess = TRUE;
5453 return bIsInProcess;
5457 AFSVerifyVolume( IN ULONGLONG ProcessId,
5458 IN AFSVolumeCB *VolumeCB)
5461 NTSTATUS ntStatus = STATUS_SUCCESS;
5468 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5471 NTSTATUS ntStatus = STATUS_SUCCESS;
5472 AFSObjectInfoCB *pObjectInfoCB = NULL;
5473 AFSDirectoryCB *pDirNode = NULL;
5474 ULONG ulEntryLength = 0;
5475 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5480 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5483 if( pObjectInfoCB == NULL)
5486 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5489 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5490 AFS_TRACE_LEVEL_VERBOSE,
5491 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5494 pObjectInfoCB->ObjectReferenceCount = 1;
5496 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5498 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5500 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5502 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5506 if( pDirNode == NULL)
5509 AFSDeleteObjectInfo( pObjectInfoCB);
5511 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5514 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5515 sizeof( AFSNonPagedDirectoryCB),
5516 AFS_DIR_ENTRY_NP_TAG);
5518 if( pNonPagedDirEntry == NULL)
5521 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5524 RtlZeroMemory( pDirNode,
5527 RtlZeroMemory( pNonPagedDirEntry,
5528 sizeof( AFSNonPagedDirectoryCB));
5530 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5532 pDirNode->NonPaged = pNonPagedDirEntry;
5534 pDirNode->ObjectInformation = pObjectInfoCB;
5536 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5542 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5544 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5546 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5548 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5550 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5551 AFSPIOCtlName.Buffer,
5552 pDirNode->NameInformation.FileName.Length);
5554 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5557 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB = pDirNode;
5561 if ( !NT_SUCCESS( ntStatus))
5564 if ( pDirNode != NULL)
5567 AFSExFreePool( pDirNode);
5570 if ( pObjectInfoCB != NULL)
5573 AFSDeleteObjectInfo( pObjectInfoCB);
5582 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5583 IN AFSDirectoryCB *DirectoryCB,
5584 IN UNICODE_STRING *ParentPathName,
5585 IN AFSNameArrayHdr *RelatedNameArray,
5586 OUT AFSFileInfoCB *FileInfo)
5589 NTSTATUS ntStatus = STATUS_SUCCESS;
5590 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
5591 UNICODE_STRING uniFullPathName;
5592 AFSNameArrayHdr *pNameArray = NULL;
5593 AFSVolumeCB *pVolumeCB = NULL;
5594 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5595 WCHAR *pwchBuffer = NULL;
5596 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5597 ULONG ulNameDifference = 0;
5598 GUID *pAuthGroup = NULL;
5604 // Retrieve a target name for the entry
5607 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5610 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5613 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5615 if( ParentDirectoryCB->ObjectInformation->Fcb != NULL)
5617 pAuthGroup = &ParentDirectoryCB->ObjectInformation->Fcb->AuthGroup;
5619 else if( DirectoryCB->ObjectInformation->Fcb != NULL)
5621 pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
5624 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5629 if( !NT_SUCCESS( ntStatus) ||
5630 pDirEntry->TargetNameLength == 0)
5633 if( pDirEntry != NULL)
5636 ntStatus = STATUS_ACCESS_DENIED;
5639 try_return( ntStatus);
5642 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5645 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5649 // Update the target name
5652 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5653 &DirectoryCB->Flags,
5654 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5655 (USHORT)pDirEntry->TargetNameLength);
5657 if( !NT_SUCCESS( ntStatus))
5660 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5662 try_return( ntStatus);
5666 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5670 // Need to pass the full path in for parsing.
5673 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5676 uniFullPathName.Length = 0;
5677 uniFullPathName.MaximumLength = ParentPathName->Length +
5679 DirectoryCB->NameInformation.TargetName.Length;
5681 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5682 uniFullPathName.MaximumLength,
5683 AFS_NAME_BUFFER_SIX_TAG);
5685 if( uniFullPathName.Buffer == NULL)
5688 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5690 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5693 pwchBuffer = uniFullPathName.Buffer;
5695 RtlZeroMemory( uniFullPathName.Buffer,
5696 uniFullPathName.MaximumLength);
5698 RtlCopyMemory( uniFullPathName.Buffer,
5699 ParentPathName->Buffer,
5700 ParentPathName->Length);
5702 uniFullPathName.Length = ParentPathName->Length;
5704 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5705 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5708 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5710 uniFullPathName.Length += sizeof( WCHAR);
5713 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5714 DirectoryCB->NameInformation.TargetName.Buffer,
5715 DirectoryCB->NameInformation.TargetName.Length);
5717 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5719 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5720 uniParsedName.MaximumLength = uniParsedName.Length;
5722 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5724 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5727 // We populate up to the current parent
5730 if( RelatedNameArray != NULL)
5733 pNameArray = AFSInitNameArray( NULL,
5734 RelatedNameArray->MaxElementCount);
5736 if( pNameArray == NULL)
5739 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5742 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5749 pNameArray = AFSInitNameArray( NULL,
5752 if( pNameArray == NULL)
5755 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5758 ntStatus = AFSPopulateNameArray( pNameArray,
5763 if( !NT_SUCCESS( ntStatus))
5766 try_return( ntStatus);
5769 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5771 AFSAcquireShared( pVolumeCB->VolumeLock,
5774 pParentDirEntry = ParentDirectoryCB;
5779 uniFullPathName.Length = 0;
5780 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5782 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5783 uniFullPathName.MaximumLength,
5784 AFS_NAME_BUFFER_SEVEN_TAG);
5786 if( uniFullPathName.Buffer == NULL)
5789 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5791 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5794 pwchBuffer = uniFullPathName.Buffer;
5796 RtlZeroMemory( uniFullPathName.Buffer,
5797 uniFullPathName.MaximumLength);
5799 RtlCopyMemory( uniFullPathName.Buffer,
5800 DirectoryCB->NameInformation.TargetName.Buffer,
5801 DirectoryCB->NameInformation.TargetName.Length);
5803 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5806 // This name should begin with the \afs server so parse it off and check it
5809 FsRtlDissectName( uniFullPathName,
5813 if( RtlCompareUnicodeString( &uniComponentName,
5818 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5820 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5821 AFS_TRACE_LEVEL_ERROR,
5822 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5825 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5828 uniFullPathName = uniRemainingPath;
5830 uniParsedName = uniFullPathName;
5832 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5834 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5840 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5843 if( pNameArray == NULL)
5846 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5849 pVolumeCB = AFSGlobalRoot;
5851 AFSAcquireShared( pVolumeCB->VolumeLock,
5854 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5858 // Increment the ref count on the volume and dir entry for correct processing below
5861 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
5863 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5864 AFS_TRACE_LEVEL_VERBOSE,
5865 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
5867 pVolumeCB->VolumeReferenceCount);
5869 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
5871 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5872 AFS_TRACE_LEVEL_VERBOSE,
5873 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5874 &pParentDirEntry->NameInformation.FileName,
5877 pParentDirEntry->OpenReferenceCount);
5879 ntStatus = AFSLocateNameEntry( NULL,
5884 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5890 if( !NT_SUCCESS( ntStatus))
5894 // The volume lock was released on failure above
5895 // Except for STATUS_OBJECT_NAME_NOT_FOUND
5898 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
5901 if( pVolumeCB != NULL)
5904 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5906 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5907 AFS_TRACE_LEVEL_VERBOSE,
5908 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
5910 pVolumeCB->VolumeReferenceCount);
5912 AFSReleaseResource( pVolumeCB->VolumeLock);
5915 if( pDirectoryEntry != NULL)
5918 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5920 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5921 AFS_TRACE_LEVEL_VERBOSE,
5922 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5923 &pDirectoryEntry->NameInformation.FileName,
5926 pDirectoryEntry->OpenReferenceCount);
5931 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
5933 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5934 AFS_TRACE_LEVEL_VERBOSE,
5935 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5936 &pParentDirEntry->NameInformation.FileName,
5939 pParentDirEntry->OpenReferenceCount);
5945 try_return( ntStatus);
5949 // Store off the information
5952 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5955 // Check for the mount point being returned
5958 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
5961 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5963 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
5964 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5967 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
5970 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
5975 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5979 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5981 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5983 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5985 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5987 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5989 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5992 // Remove the reference made above
5995 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5997 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5998 AFS_TRACE_LEVEL_VERBOSE,
5999 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
6000 &pDirectoryEntry->NameInformation.FileName,
6003 pDirectoryEntry->OpenReferenceCount);
6007 if( pDirEntry != NULL)
6010 AFSExFreePool( pDirEntry);
6013 if( pVolumeCB != NULL)
6016 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6018 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6019 AFS_TRACE_LEVEL_VERBOSE,
6020 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
6022 pVolumeCB->VolumeReferenceCount);
6024 AFSReleaseResource( pVolumeCB->VolumeLock);
6027 if( pNameArray != NULL)
6030 AFSFreeNameArray( pNameArray);
6033 if( pwchBuffer != NULL)
6037 // Always free the buffer that we allocated as AFSLocateNameEntry
6038 // will not free it. If uniFullPathName.Buffer was allocated by
6039 // AFSLocateNameEntry, then we must free that as well.
6040 // Check that the uniFullPathName.Buffer in the string is not the same
6041 // offset by the length of the server name
6044 if( uniFullPathName.Length > 0 &&
6045 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6048 AFSExFreePool( uniFullPathName.Buffer);
6051 AFSExFreePool( pwchBuffer);
6059 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6060 IN ULONGLONG HashIndex)
6063 NTSTATUS ntStatus = STATUS_SUCCESS;
6064 AFSObjectInfoCB *pObjectInfo = NULL;
6069 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6070 sizeof( AFSObjectInfoCB),
6071 AFS_OBJECT_INFO_TAG);
6073 if( pObjectInfo == NULL)
6076 try_return( pObjectInfo);
6079 RtlZeroMemory( pObjectInfo,
6080 sizeof( AFSObjectInfoCB));
6082 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6083 sizeof( AFSNonPagedObjectInfoCB),
6084 AFS_NP_OBJECT_INFO_TAG);
6086 if( pObjectInfo->NonPagedInfo == NULL)
6089 AFSExFreePool( pObjectInfo);
6091 try_return( pObjectInfo = NULL);
6094 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6096 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6098 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6100 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6102 if( ParentObjectInfo != NULL)
6104 InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
6108 // Initialize the access time
6111 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6117 // Insert the entry into the object tree and list
6120 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6122 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6125 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6130 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6131 &pObjectInfo->TreeEntry);
6133 ASSERT( NT_SUCCESS( ntStatus));
6137 // And the object list in the volume
6140 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6143 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6148 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6150 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6153 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6156 // Indicate the object is in the hash tree and linked list in the volume
6159 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6171 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6174 BOOLEAN bAcquiredTreeLock = FALSE;
6176 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6179 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6181 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6184 bAcquiredTreeLock = TRUE;
6188 // Remove it from the tree and list if it was inserted
6191 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6194 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6195 &ObjectInfo->TreeEntry);
6198 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6201 if( ObjectInfo->ListEntry.fLink == NULL)
6204 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6206 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6209 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6215 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6218 if( ObjectInfo->ListEntry.bLink == NULL)
6221 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6223 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6226 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6232 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6236 if( ObjectInfo->ParentObjectInformation != NULL)
6238 InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
6241 if( bAcquiredTreeLock)
6244 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6248 // Release the fid in the service
6251 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6254 AFSReleaseFid( &ObjectInfo->FileId);
6257 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6259 AFSExFreePool( ObjectInfo->NonPagedInfo);
6261 AFSExFreePool( ObjectInfo);
6267 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6268 OUT AFSDirectoryCB **TargetDirEntry)
6271 NTSTATUS ntStatus = STATUS_SUCCESS;
6272 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6273 UNICODE_STRING uniFullPathName;
6274 AFSNameArrayHdr *pNameArray = NULL;
6275 AFSVolumeCB *pVolumeCB = NULL;
6276 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6277 WCHAR *pwchBuffer = NULL;
6278 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6279 ULONG ulNameDifference = 0;
6280 GUID *pAuthGroup = NULL;
6286 // Retrieve a target name for the entry
6289 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6292 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6295 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6297 if( DirectoryCB->ObjectInformation->Fcb != NULL)
6299 pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
6302 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6307 if( !NT_SUCCESS( ntStatus) ||
6308 pDirEntry->TargetNameLength == 0)
6311 if( pDirEntry != NULL)
6314 ntStatus = STATUS_ACCESS_DENIED;
6317 try_return( ntStatus);
6320 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6323 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6327 // Update the target name
6330 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6331 &DirectoryCB->Flags,
6332 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6333 (USHORT)pDirEntry->TargetNameLength);
6335 if( !NT_SUCCESS( ntStatus))
6338 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6340 try_return( ntStatus);
6344 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6348 // Need to pass the full path in for parsing.
6351 uniFullPathName.Length = 0;
6352 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6354 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6355 uniFullPathName.MaximumLength,
6356 AFS_NAME_BUFFER_EIGHT_TAG);
6358 if( uniFullPathName.Buffer == NULL)
6361 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6363 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6366 pwchBuffer = uniFullPathName.Buffer;
6368 RtlZeroMemory( uniFullPathName.Buffer,
6369 uniFullPathName.MaximumLength);
6371 RtlCopyMemory( uniFullPathName.Buffer,
6372 DirectoryCB->NameInformation.TargetName.Buffer,
6373 DirectoryCB->NameInformation.TargetName.Length);
6375 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6378 // This name should begin with the \afs server so parse it off and chech it
6381 FsRtlDissectName( uniFullPathName,
6385 if( RtlCompareUnicodeString( &uniComponentName,
6391 // Try evaluating the full path
6394 uniFullPathName.Buffer = pwchBuffer;
6396 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6398 uniFullPathName.MaximumLength = uniFullPathName.Length;
6403 uniFullPathName = uniRemainingPath;
6406 uniParsedName = uniFullPathName;
6408 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6410 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6416 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6419 if( pNameArray == NULL)
6422 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6425 pVolumeCB = AFSGlobalRoot;
6427 AFSAcquireShared( pVolumeCB->VolumeLock,
6430 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6432 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6434 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6435 AFS_TRACE_LEVEL_VERBOSE,
6436 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6438 pVolumeCB->VolumeReferenceCount);
6440 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6442 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6443 AFS_TRACE_LEVEL_VERBOSE,
6444 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6445 &pParentDirEntry->NameInformation.FileName,
6448 pParentDirEntry->OpenReferenceCount);
6450 ntStatus = AFSLocateNameEntry( NULL,
6461 if( !NT_SUCCESS( ntStatus))
6465 // The volume lock was released on failure above
6466 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6469 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6472 if( pVolumeCB != NULL)
6475 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6477 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6478 AFS_TRACE_LEVEL_VERBOSE,
6479 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
6481 pVolumeCB->VolumeReferenceCount);
6483 AFSReleaseResource( pVolumeCB->VolumeLock);
6486 if( pDirectoryEntry != NULL)
6489 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6491 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6492 AFS_TRACE_LEVEL_VERBOSE,
6493 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6494 &pDirectoryEntry->NameInformation.FileName,
6497 pDirectoryEntry->OpenReferenceCount);
6502 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6504 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6505 AFS_TRACE_LEVEL_VERBOSE,
6506 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6507 &pParentDirEntry->NameInformation.FileName,
6510 pParentDirEntry->OpenReferenceCount);
6516 try_return( ntStatus);
6520 // Pass back the target dir entry for this request
6523 *TargetDirEntry = pDirectoryEntry;
6527 if( pDirEntry != NULL)
6530 AFSExFreePool( pDirEntry);
6533 if( pVolumeCB != NULL)
6536 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6538 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6539 AFS_TRACE_LEVEL_VERBOSE,
6540 "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
6542 pVolumeCB->VolumeReferenceCount);
6544 AFSReleaseResource( pVolumeCB->VolumeLock);
6547 if( pNameArray != NULL)
6550 AFSFreeNameArray( pNameArray);
6553 if( pwchBuffer != NULL)
6557 // Always free the buffer that we allocated as AFSLocateNameEntry
6558 // will not free it. If uniFullPathName.Buffer was allocated by
6559 // AFSLocateNameEntry, then we must free that as well.
6560 // Check that the uniFullPathName.Buffer in the string is not the same
6561 // offset by the length of the server name
6564 if( uniFullPathName.Length > 0 &&
6565 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6568 AFSExFreePool( uniFullPathName.Buffer);
6571 AFSExFreePool( pwchBuffer);
6579 AFSCleanupFcb( IN AFSFcb *Fcb,
6580 IN BOOLEAN ForceFlush)
6583 NTSTATUS ntStatus = STATUS_SUCCESS;
6584 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6585 LARGE_INTEGER liTime;
6586 IO_STATUS_BLOCK stIoStatus;
6591 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6593 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6595 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6598 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6599 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6602 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6605 if( Fcb->OpenReferenceCount > 0)
6611 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6616 if( !NT_SUCCESS( stIoStatus.Status))
6619 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6620 AFS_TRACE_LEVEL_ERROR,
6621 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6622 Fcb->ObjectInformation->FileId.Cell,
6623 Fcb->ObjectInformation->FileId.Volume,
6624 Fcb->ObjectInformation->FileId.Vnode,
6625 Fcb->ObjectInformation->FileId.Unique,
6627 stIoStatus.Information);
6629 ntStatus = stIoStatus.Status;
6632 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6637 __except( EXCEPTION_EXECUTE_HANDLER)
6639 ntStatus = GetExceptionCode();
6643 AFSReleaseResource( &Fcb->NPFcb->Resource);
6646 // Wait for any currently running flush or release requests to complete
6649 AFSWaitOnQueuedFlushes( Fcb);
6652 // Now perform another flush on the file
6655 if( !NT_SUCCESS( AFSFlushExtents( Fcb)))
6658 AFSReleaseExtentsWithFlush( Fcb);
6662 if( Fcb->OpenReferenceCount == 0 ||
6663 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6664 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6667 AFSTearDownFcbExtents( Fcb);
6670 try_return( ntStatus);
6673 KeQueryTickCount( &liTime);
6676 // First up are there dirty extents in the cache to flush?
6680 ( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6681 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
6682 ( Fcb->Specific.File.ExtentsDirtyCount ||
6683 Fcb->Specific.File.ExtentCount) &&
6684 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6685 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6688 if( !NT_SUCCESS( AFSFlushExtents( Fcb)) &&
6689 Fcb->OpenReferenceCount == 0)
6692 AFSReleaseExtentsWithFlush( Fcb);
6695 else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6696 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6700 // The file has been marked as invalid. Dump it
6703 AFSTearDownFcbExtents( Fcb);
6707 // If there are extents and they haven't been used recently *and*
6708 // are not being used
6712 ( 0 != Fcb->Specific.File.ExtentCount &&
6713 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6714 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6715 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
6716 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6723 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6728 if( !NT_SUCCESS( stIoStatus.Status))
6731 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6732 AFS_TRACE_LEVEL_ERROR,
6733 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6734 Fcb->ObjectInformation->FileId.Cell,
6735 Fcb->ObjectInformation->FileId.Volume,
6736 Fcb->ObjectInformation->FileId.Vnode,
6737 Fcb->ObjectInformation->FileId.Unique,
6739 stIoStatus.Information);
6741 ntStatus = stIoStatus.Status;
6747 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6753 __except( EXCEPTION_EXECUTE_HANDLER)
6755 ntStatus = GetExceptionCode();
6758 AFSReleaseResource( &Fcb->NPFcb->Resource);
6760 if( Fcb->OpenReferenceCount == 0)
6764 // Tear em down we'll not be needing them again
6767 AFSTearDownFcbExtents( Fcb);
6780 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
6781 IN UNICODE_STRING *NewFileName)
6784 NTSTATUS ntStatus = STATUS_SUCCESS;
6785 WCHAR *pTmpBuffer = NULL;
6790 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
6793 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
6796 AFSExFreePool( DirectoryCB->NameInformation.FileName.Buffer);
6798 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6800 DirectoryCB->NameInformation.FileName.Buffer = NULL;
6804 // OK, we need to allocate a new name buffer
6807 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6808 NewFileName->Length,
6809 AFS_NAME_BUFFER_NINE_TAG);
6811 if( pTmpBuffer == NULL)
6814 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6817 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
6819 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
6821 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6824 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
6826 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
6827 NewFileName->Buffer,
6828 NewFileName->Length);
6839 AFSReadCacheFile( IN void *ReadBuffer,
6840 IN LARGE_INTEGER *ReadOffset,
6841 IN ULONG RequestedDataLength,
6842 IN OUT PULONG BytesRead)
6845 NTSTATUS ntStatus = STATUS_SUCCESS;
6848 PIO_STACK_LOCATION pIoStackLocation = NULL;
6849 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6850 DEVICE_OBJECT *pTargetDeviceObject = NULL;
6851 FILE_OBJECT *pCacheFileObject = NULL;
6856 pCacheFileObject = AFSReferenceCacheFileObject();
6858 if( pCacheFileObject == NULL)
6860 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
6863 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
6866 // Initialize the event
6869 KeInitializeEvent( &kEvent,
6870 SynchronizationEvent,
6874 // Allocate an irp for this request. This could also come from a
6875 // private pool, for instance.
6878 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
6884 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6888 // Build the IRP's main body
6891 pIrp->UserBuffer = ReadBuffer;
6893 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
6894 pIrp->RequestorMode = KernelMode;
6895 pIrp->Flags |= IRP_READ_OPERATION;
6898 // Set up the I/O stack location.
6901 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
6902 pIoStackLocation->MajorFunction = IRP_MJ_READ;
6903 pIoStackLocation->DeviceObject = pTargetDeviceObject;
6904 pIoStackLocation->FileObject = pCacheFileObject;
6905 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
6907 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
6910 // Set the completion routine.
6913 IoSetCompletionRoutine( pIrp,
6921 // Send it to the FSD
6924 ntStatus = IoCallDriver( pTargetDeviceObject,
6927 if( NT_SUCCESS( ntStatus))
6934 ntStatus = KeWaitForSingleObject( &kEvent,
6940 if( NT_SUCCESS( ntStatus))
6943 ntStatus = pIrp->IoStatus.Status;
6945 *BytesRead = (ULONG)pIrp->IoStatus.Information;
6951 if( pCacheFileObject != NULL)
6953 AFSReleaseCacheFileObject( pCacheFileObject);
6959 if( pIrp->MdlAddress != NULL)
6962 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
6965 MmUnlockPages( pIrp->MdlAddress);
6968 IoFreeMdl( pIrp->MdlAddress);
6971 pIrp->MdlAddress = NULL;
6985 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
6990 KEVENT *pEvent = (KEVENT *)Context;
6996 return STATUS_MORE_PROCESSING_REQUIRED;
7000 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7003 BOOLEAN bIsEmpty = FALSE;
7004 AFSDirectoryCB *pDirEntry = NULL;
7009 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7014 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7017 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7019 while( pDirEntry != NULL)
7022 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7023 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7031 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7036 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7043 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7044 IN AFSDirectoryCB *DirEntry)
7047 NTSTATUS ntStatus = STATUS_SUCCESS;
7052 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7055 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7056 AFS_TRACE_LEVEL_VERBOSE,
7057 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7059 &DirEntry->NameInformation.FileName);
7061 try_return( ntStatus);
7064 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7067 // Remove the entry from the parent tree
7070 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7071 AFS_TRACE_LEVEL_VERBOSE,
7072 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7074 &DirEntry->NameInformation.FileName);
7076 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7079 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7080 AFS_TRACE_LEVEL_VERBOSE,
7081 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7083 &DirEntry->NameInformation.FileName);
7085 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7088 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7092 // From the short name tree
7095 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7096 AFS_TRACE_LEVEL_VERBOSE,
7097 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7099 &DirEntry->NameInformation.FileName);
7101 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7104 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7107 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7108 AFS_TRACE_LEVEL_VERBOSE,
7109 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7111 &DirEntry->NameInformation.FileName);
7113 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7115 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7126 AFSGetAuthenticationId()
7129 LARGE_INTEGER liAuthId = {0,0};
7130 NTSTATUS ntStatus = STATUS_SUCCESS;
7131 PACCESS_TOKEN hToken = NULL;
7132 PTOKEN_STATISTICS pTokenInfo = NULL;
7133 BOOLEAN bCopyOnOpen = FALSE;
7134 BOOLEAN bEffectiveOnly = FALSE;
7135 BOOLEAN bPrimaryToken = FALSE;
7136 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7141 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7144 &stImpersonationLevel);
7149 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7154 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7155 AFS_TRACE_LEVEL_ERROR,
7156 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7158 try_return( ntStatus);
7161 bPrimaryToken = TRUE;
7164 ntStatus = SeQueryInformationToken( hToken,
7166 (PVOID *)&pTokenInfo);
7168 if( !NT_SUCCESS( ntStatus))
7171 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7172 AFS_TRACE_LEVEL_ERROR,
7173 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7175 try_return( ntStatus);
7178 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7179 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7181 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7182 AFS_TRACE_LEVEL_VERBOSE,
7183 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7194 PsDereferenceImpersonationToken( hToken);
7199 PsDereferencePrimaryToken( hToken);
7203 if( pTokenInfo != NULL)
7206 AFSExFreePool( pTokenInfo);
7214 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7218 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7220 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7223 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7225 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7228 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7230 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7233 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7235 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7238 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7240 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7247 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7250 BOOLEAN bIsValid = TRUE;
7252 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7254 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7256 while( pCurrentDirEntry != NULL)
7259 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7263 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7268 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7269 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7272 if( pDirEntry == NULL)
7279 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7282 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7285 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7287 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7289 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7298 AFSReferenceCacheFileObject()
7301 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7302 FILE_OBJECT *pCacheFileObject = NULL;
7304 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7307 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7309 if( pCacheFileObject != NULL)
7311 ObReferenceObject( pCacheFileObject);
7314 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7316 return pCacheFileObject;
7320 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7323 ASSERT( CacheFileObject != NULL);
7325 ObDereferenceObject( CacheFileObject);
7331 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7334 NTSTATUS ntStatus = STATUS_SUCCESS;
7335 AFSDeviceExt *pControlDevExt = NULL;
7336 ULONG ulTimeIncrement = 0;
7341 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7343 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7345 AFSServerName = LibraryInit->AFSServerName;
7347 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7350 // Callbacks in the framework
7353 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7355 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7357 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7359 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7361 AFSExFreePool = LibraryInit->AFSExFreePool;
7363 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7365 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7367 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7369 if( LibraryInit->AFSCacheBaseAddress != NULL)
7372 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7374 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7376 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7380 // Initialize some flush parameters
7383 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7385 ulTimeIncrement = KeQueryTimeIncrement();
7387 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7388 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_ONE_SECOND;
7389 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart *= AFS_SERVER_PURGE_DELAY;
7390 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7391 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)(AFS_ONE_SECOND * AFS_SERVER_FLUSH_DELAY) / (ULONGLONG)ulTimeIncrement);
7392 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7395 // Initialize the global root entry
7398 ntStatus = AFSInitVolume( NULL,
7399 &LibraryInit->GlobalRootFid,
7402 if( !NT_SUCCESS( ntStatus))
7405 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7406 AFS_TRACE_LEVEL_ERROR,
7407 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7410 try_return( ntStatus);
7413 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7416 if( !NT_SUCCESS( ntStatus))
7419 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7420 AFS_TRACE_LEVEL_ERROR,
7421 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7424 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7426 try_return( ntStatus);
7430 // Update the node type code to AFS_ROOT_ALL
7433 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7435 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7438 // Drop the locks acquired above
7441 AFSInitVolumeWorker( AFSGlobalRoot);
7443 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7445 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7459 NTSTATUS ntStatus = STATUS_SUCCESS;
7460 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7465 if( AFSGlobalDotDirEntry != NULL)
7468 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
7470 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7472 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7474 ExFreePool( AFSGlobalDotDirEntry);
7476 AFSGlobalDotDirEntry = NULL;
7479 if( AFSGlobalDotDotDirEntry != NULL)
7482 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
7484 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7486 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7488 ExFreePool( AFSGlobalDotDotDirEntry);
7490 AFSGlobalDotDotDirEntry = NULL;
7493 if( AFSSpecialShareNames != NULL)
7496 pDirNode = AFSSpecialShareNames;
7498 while( pDirNode != NULL)
7501 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7503 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
7505 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7507 ExFreePool( pDirNode->NonPaged);
7509 ExFreePool( pDirNode);
7511 pDirNode = pLastDirNode;
7514 AFSSpecialShareNames = NULL;
7522 AFSDefaultLogMsg( IN ULONG Subsystem,
7528 NTSTATUS ntStatus = STATUS_SUCCESS;
7530 char chDebugBuffer[ 256];
7535 va_start( va_args, Format);
7537 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7542 if( NT_SUCCESS( ntStatus))
7544 DbgPrint( chDebugBuffer);
7554 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7555 IN ULONG InputBufferLength,
7556 IN AFSStatusInfoCB *StatusInfo,
7557 OUT ULONG *ReturnLength)
7560 NTSTATUS ntStatus = STATUS_SUCCESS;
7561 AFSFcb *pFcb = NULL;
7562 AFSVolumeCB *pVolumeCB = NULL;
7563 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7564 AFSObjectInfoCB *pObjectInfo = NULL;
7565 ULONGLONG ullIndex = 0;
7566 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7567 AFSNameArrayHdr *pNameArray = NULL;
7568 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7574 // If we are given a FID then look up the entry by that, otherwise
7578 if( GetStatusInfo->FileID.Cell != 0 &&
7579 GetStatusInfo->FileID.Volume != 0 &&
7580 GetStatusInfo->FileID.Vnode != 0 &&
7581 GetStatusInfo->FileID.Unique != 0)
7584 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7587 // Locate the volume node
7590 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7592 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7594 (AFSBTreeEntry **)&pVolumeCB);
7596 if( pVolumeCB != NULL)
7599 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7601 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7602 AFS_TRACE_LEVEL_VERBOSE,
7603 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7605 pVolumeCB->VolumeReferenceCount);
7608 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7610 if( !NT_SUCCESS( ntStatus) ||
7613 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7616 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
7619 pObjectInfo = &pVolumeCB->ObjectInformation;
7621 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7623 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7628 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
7631 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7633 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7634 AFS_TRACE_LEVEL_VERBOSE,
7635 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7637 pVolumeCB->VolumeReferenceCount);
7639 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
7641 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
7643 (AFSBTreeEntry **)&pObjectInfo);
7645 if( pObjectInfo != NULL)
7649 // Reference the node so it won't be torn down
7652 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7654 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7655 AFS_TRACE_LEVEL_VERBOSE,
7656 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
7658 pObjectInfo->ObjectReferenceCount);
7661 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
7663 if( !NT_SUCCESS( ntStatus) ||
7664 pObjectInfo == NULL)
7666 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7673 if( GetStatusInfo->FileNameLength == 0 ||
7674 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
7676 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7679 uniFullPathName.Length = GetStatusInfo->FileNameLength;
7680 uniFullPathName.MaximumLength = uniFullPathName.Length;
7682 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
7685 // This name should begin with the \afs server so parse it off and check it
7688 FsRtlDissectName( uniFullPathName,
7692 if( RtlCompareUnicodeString( &uniComponentName,
7696 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7697 AFS_TRACE_LEVEL_ERROR,
7698 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
7701 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
7704 uniFullPathName = uniRemainingPath;
7706 uniParsedName = uniFullPathName;
7712 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7715 if( pNameArray == NULL)
7717 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7720 pVolumeCB = AFSGlobalRoot;
7722 AFSAcquireShared( pVolumeCB->VolumeLock,
7725 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7728 // Increment the ref count on the volume and dir entry for correct processing below
7731 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7733 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7734 AFS_TRACE_LEVEL_VERBOSE,
7735 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7737 pVolumeCB->VolumeReferenceCount);
7739 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
7741 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7742 AFS_TRACE_LEVEL_VERBOSE,
7743 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7744 &pParentDirEntry->NameInformation.FileName,
7747 pParentDirEntry->OpenReferenceCount);
7749 ntStatus = AFSLocateNameEntry( NULL,
7754 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
7755 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
7761 if( !NT_SUCCESS( ntStatus))
7765 // The volume lock was released on failure above
7766 // Except for STATUS_OBJECT_NAME_NOT_FOUND
7769 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
7772 if( pVolumeCB != NULL)
7775 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7777 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7778 AFS_TRACE_LEVEL_VERBOSE,
7779 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7781 pVolumeCB->VolumeReferenceCount);
7783 AFSReleaseResource( pVolumeCB->VolumeLock);
7786 if( pDirectoryEntry != NULL)
7789 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7791 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7792 AFS_TRACE_LEVEL_VERBOSE,
7793 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7794 &pDirectoryEntry->NameInformation.FileName,
7797 pDirectoryEntry->OpenReferenceCount);
7802 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
7804 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7805 AFS_TRACE_LEVEL_VERBOSE,
7806 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7807 &pParentDirEntry->NameInformation.FileName,
7810 pParentDirEntry->OpenReferenceCount);
7816 try_return( ntStatus);
7820 // Remove the reference made above
7823 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7825 pObjectInfo = pDirectoryEntry->ObjectInformation;
7827 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7829 if( pVolumeCB != NULL)
7832 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7834 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7835 AFS_TRACE_LEVEL_VERBOSE,
7836 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
7838 pVolumeCB->VolumeReferenceCount);
7840 AFSReleaseResource( pVolumeCB->VolumeLock);
7845 // At this point we have an object info block, return the information
7848 StatusInfo->FileId = pObjectInfo->FileId;
7850 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
7852 StatusInfo->Expiration = pObjectInfo->Expiration;
7854 StatusInfo->DataVersion = pObjectInfo->DataVersion;
7856 StatusInfo->FileType = pObjectInfo->FileType;
7858 StatusInfo->ObjectFlags = pObjectInfo->Flags;
7860 StatusInfo->CreationTime = pObjectInfo->CreationTime;
7862 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
7864 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
7866 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
7868 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
7870 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
7872 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
7874 StatusInfo->EaSize = pObjectInfo->EaSize;
7876 StatusInfo->Links = pObjectInfo->Links;
7879 // Return the information length
7882 *ReturnLength = sizeof( AFSStatusInfoCB);
7886 if( pObjectInfo != NULL)
7889 InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
7892 if( pNameArray != NULL)
7895 AFSFreeNameArray( pNameArray);
7903 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
7904 IN UNICODE_STRING *ComponentName)
7907 NTSTATUS ntStatus = STATUS_SUCCESS;
7908 AFSDirectoryCB *pDirEntry = NULL;
7915 // Search for the entry in the parent
7918 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7919 AFS_TRACE_LEVEL_VERBOSE_2,
7920 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
7923 ulCRC = AFSGenerateCRC( ComponentName,
7926 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7929 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7933 if( pDirEntry == NULL)
7937 // Missed so perform a case insensitive lookup
7940 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7941 AFS_TRACE_LEVEL_VERBOSE_2,
7942 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
7945 ulCRC = AFSGenerateCRC( ComponentName,
7948 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7952 if( pDirEntry == NULL)
7956 // OK, if this component is a valid short name then try
7957 // a lookup in the short name tree
7960 if( RtlIsNameLegalDOS8Dot3( ComponentName,
7965 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7966 AFS_TRACE_LEVEL_VERBOSE_2,
7967 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
7970 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
7977 if( pDirEntry != NULL)
7979 InterlockedIncrement( &pDirEntry->OpenReferenceCount);
7982 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7984 if( pDirEntry == NULL)
7987 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7988 AFS_TRACE_LEVEL_VERBOSE_2,
7989 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
7992 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
7996 // We have the symlink object but previously failed to process it so return access
8000 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8001 AFS_TRACE_LEVEL_VERBOSE_2,
8002 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ ACCESS_DENIED\n",
8005 ntStatus = STATUS_ACCESS_DENIED;
8007 InterlockedDecrement( &pDirEntry->OpenReferenceCount);
8018 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8019 OUT UNICODE_STRING *ComponentName)
8022 NTSTATUS ntStatus = STATUS_SUCCESS;
8023 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8025 uniFullPathName = *FullPathName;
8030 FsRtlDissectName( uniFullPathName,
8034 if( uniRemainingPath.Length == 0)
8039 uniFullPathName = uniRemainingPath;
8042 if( uniComponentName.Length > 0)
8044 *ComponentName = uniComponentName;
8051 AFSDumpTraceFiles_Default()
8057 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8060 BOOLEAN bIsValidName = TRUE;
8066 while( usIndex < FileName->Length/sizeof( WCHAR))
8069 if( FileName->Buffer[ usIndex] == L':' ||
8070 FileName->Buffer[ usIndex] == L'*' ||
8071 FileName->Buffer[ usIndex] == L'?' ||
8072 FileName->Buffer[ usIndex] == L'"' ||
8073 FileName->Buffer[ usIndex] == L'<' ||
8074 FileName->Buffer[ usIndex] == L'>')
8076 bIsValidName = FALSE;
8084 return bIsValidName;
8088 AFSCreateDefaultSecurityDescriptor()
8091 NTSTATUS ntStatus = STATUS_SUCCESS;
8093 ULONG ulSACLSize = 0;
8094 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8095 ULONG ulACESize = 0;
8096 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8097 ULONG ulSDLength = 0;
8098 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8099 PSID pWorldSID = NULL;
8100 ULONG *pulSubAuthority = NULL;
8101 ULONG ulWorldSIDLEngth = 0;
8106 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8108 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8110 AFS_GENERIC_MEMORY_29_TAG);
8112 if( pWorldSID == NULL)
8114 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8115 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8118 RtlZeroMemory( pWorldSID,
8121 RtlInitializeSid( pWorldSID,
8122 &SeWorldSidAuthority,
8125 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8126 *pulSubAuthority = SECURITY_WORLD_RID;
8128 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8131 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8136 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8138 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8140 AFS_GENERIC_MEMORY_29_TAG);
8145 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8147 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8150 RtlZeroMemory( pACE,
8153 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8154 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8155 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8156 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8158 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8160 SeExports->SeLowMandatorySid);
8162 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8163 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8165 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8167 AFS_GENERIC_MEMORY_29_TAG);
8172 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8174 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8177 ntStatus = RtlCreateAcl( pSACL,
8181 if( !NT_SUCCESS( ntStatus))
8184 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8187 try_return( ntStatus);
8190 ntStatus = RtlAddAce( pSACL,
8194 pACE->Header.AceSize);
8196 if( !NT_SUCCESS( ntStatus))
8199 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8202 try_return( ntStatus);
8206 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8207 sizeof( SECURITY_DESCRIPTOR),
8208 AFS_GENERIC_MEMORY_27_TAG);
8210 if( pSecurityDescr == NULL)
8213 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8215 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8218 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8219 SECURITY_DESCRIPTOR_REVISION);
8221 if( !NT_SUCCESS( ntStatus))
8224 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8227 try_return( ntStatus);
8230 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8232 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8237 if( !NT_SUCCESS( ntStatus))
8240 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8243 try_return( ntStatus);
8248 // Add in the group and owner to the SD
8251 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8253 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8257 if( !NT_SUCCESS( ntStatus))
8260 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8263 try_return( ntStatus);
8267 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8271 if( !NT_SUCCESS( ntStatus))
8274 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8277 try_return( ntStatus);
8280 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8283 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8285 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8288 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8290 AFS_GENERIC_MEMORY_27_TAG);
8292 if( pRelativeSecurityDescr == NULL)
8295 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8297 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8300 ulSDLength = PAGE_SIZE;
8302 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8303 pRelativeSecurityDescr,
8306 if( !NT_SUCCESS( ntStatus))
8309 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8312 try_return( ntStatus);
8315 AFSDefaultSD = pRelativeSecurityDescr;
8319 if( !NT_SUCCESS( ntStatus))
8322 if( pRelativeSecurityDescr != NULL)
8324 ExFreePool( pRelativeSecurityDescr);
8328 if( pSecurityDescr != NULL)
8330 ExFreePool( pSecurityDescr);
8343 if( pWorldSID != NULL)
8345 ExFreePool( pWorldSID);
8353 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8354 OUT UNICODE_STRING *ParentPath)
8359 *ParentPath = *FullFileName;
8362 // If the final character is a \, jump over it
8365 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8367 ParentPath->Length -= sizeof( WCHAR);
8370 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8372 ParentPath->Length -= sizeof( WCHAR);
8376 // And the separator
8379 ParentPath->Length -= sizeof( WCHAR);