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;
1028 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
1030 pDirNode->FileIndex = FileIndex;
1033 // Setup the names in the entry
1036 if( FileName->Length > 0)
1039 pDirNode->NameInformation.FileName.Length = FileName->Length;
1041 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1043 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1045 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1047 pDirNode->NameInformation.FileName.Length);
1050 // Create a CRC for the file
1053 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1056 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1060 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1061 AFS_TRACE_LEVEL_VERBOSE,
1062 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1065 ParentObjectInfo->FileId.Cell,
1066 ParentObjectInfo->FileId.Volume,
1067 ParentObjectInfo->FileId.Vnode,
1068 ParentObjectInfo->FileId.Unique);
1070 if( TargetName != NULL &&
1071 TargetName->Length > 0)
1074 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1076 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1078 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1079 sizeof( AFSDirectoryCB) +
1080 pDirNode->NameInformation.FileName.Length);
1082 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1084 pDirNode->NameInformation.TargetName.Length);
1088 // If we allocated the object information cb then update the information
1091 if( bAllocatedObjectCB)
1095 // Populate the rest of the data
1098 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1100 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1102 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1104 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1106 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1108 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1110 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1112 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1114 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1116 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1118 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1119 pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1120 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1123 pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1126 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1129 // Object specific information
1132 pObjectInfoCB->Links = DirEnumEntry->Links;
1134 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1136 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1139 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1140 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1144 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1145 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1146 pObjectInfoCB->TargetFileId.Unique == 0 &&
1147 pDirNode->NameInformation.TargetName.Length == 0)
1151 // This will ensure we perform a validation on the node
1154 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1157 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1160 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1166 if( !NT_SUCCESS( ntStatus))
1169 if( pNonPagedDirEntry != NULL)
1172 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1174 AFSExFreePool( pNonPagedDirEntry);
1177 if( pDirNode != NULL)
1180 AFSExFreePool( pDirNode);
1186 // Dereference our object info block if we have one
1189 if( pObjectInfoCB != NULL)
1192 InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
1194 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1195 AFS_TRACE_LEVEL_VERBOSE,
1196 "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
1198 pObjectInfoCB->ObjectReferenceCount);
1200 if( bAllocatedObjectCB)
1203 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1205 AFSDeleteObjectInfo( pObjectInfoCB);
1215 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1216 IN BOOLEAN DirectoryEntry)
1219 BOOLEAN bReturn = TRUE;
1220 ACCESS_MASK stAccessMask = 0;
1223 // Get rid of anything we don't know about
1226 DesiredAccess = (DesiredAccess &
1232 ACCESS_SYSTEM_SECURITY |
1236 FILE_READ_ATTRIBUTES |
1237 FILE_WRITE_ATTRIBUTES |
1238 FILE_LIST_DIRECTORY |
1244 // Our 'read only' access mask. These are the accesses we will
1245 // allow for a read only file
1248 stAccessMask = DELETE |
1253 ACCESS_SYSTEM_SECURITY |
1257 FILE_READ_ATTRIBUTES |
1258 FILE_WRITE_ATTRIBUTES |
1260 FILE_LIST_DIRECTORY |
1264 // For a directory, add in the directory specific accesses
1270 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1275 if( FlagOn( DesiredAccess, ~stAccessMask))
1279 // A write access is set ...
1289 AFSEvaluateNode( IN GUID *AuthGroup,
1290 IN AFSDirectoryCB *DirEntry)
1293 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1294 NTSTATUS ntStatus = STATUS_SUCCESS;
1295 AFSDirEnumEntry *pDirEntry = NULL;
1296 UNICODE_STRING uniTargetName;
1301 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1306 if( !NT_SUCCESS( ntStatus))
1309 try_return( ntStatus);
1312 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1314 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1316 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1318 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1320 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1322 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1324 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1326 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1328 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1330 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1332 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1334 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1335 pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1336 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1339 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1342 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1344 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1347 // If we have a target name then see if it needs updating ...
1350 if( pDirEntry->TargetNameLength > 0)
1354 // Update the target name information if needed
1357 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1359 uniTargetName.MaximumLength = uniTargetName.Length;
1361 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1363 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1366 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1367 RtlCompareUnicodeString( &uniTargetName,
1368 &DirEntry->NameInformation.TargetName,
1373 // Update the target name
1376 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1378 uniTargetName.Buffer,
1379 uniTargetName.Length);
1381 if( !NT_SUCCESS( ntStatus))
1384 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1386 try_return( ntStatus);
1390 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1395 if( pDirEntry != NULL)
1398 AFSExFreePool( pDirEntry);
1406 AFSValidateSymLink( IN GUID *AuthGroup,
1407 IN AFSDirectoryCB *DirEntry)
1410 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1411 NTSTATUS ntStatus = STATUS_SUCCESS;
1412 AFSDirEnumEntry *pDirEntry = NULL;
1413 UNICODE_STRING uniTargetName;
1418 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1423 if( !NT_SUCCESS( ntStatus))
1426 try_return( ntStatus);
1429 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1430 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1433 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1436 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1438 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1440 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1443 // Update the target name information if needed
1446 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1448 uniTargetName.MaximumLength = uniTargetName.Length;
1450 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1452 if( uniTargetName.Length > 0)
1455 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1458 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1459 RtlCompareUnicodeString( &uniTargetName,
1460 &DirEntry->NameInformation.TargetName,
1465 // Update the target name
1468 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1470 uniTargetName.Buffer,
1471 uniTargetName.Length);
1473 if( !NT_SUCCESS( ntStatus))
1476 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1478 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1482 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1486 // If the FileType is the same then nothing to do since it IS
1490 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1493 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1495 try_return( ntStatus = STATUS_SUCCESS);
1498 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1500 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1502 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1504 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1506 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1508 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1510 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1512 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1514 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
1515 pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1516 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1519 DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
1522 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1524 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1528 if( pDirEntry != NULL)
1531 AFSExFreePool( pDirEntry);
1539 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1542 NTSTATUS ntStatus = STATUS_SUCCESS;
1543 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1544 AFSVolumeCB *pVolumeCB = NULL;
1545 AFSFcb *pTargetDcb = NULL;
1546 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1547 AFSDirectoryCB *pCurrentDirEntry = NULL;
1548 BOOLEAN bIsChild = FALSE;
1549 ULONGLONG ullIndex = 0;
1550 AFSObjectInfoCB *pObjectInfo = NULL;
1551 IO_STATUS_BLOCK stIoStatus;
1558 // Need to locate the Fcb for the directory to purge
1561 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1562 AFS_TRACE_LEVEL_VERBOSE,
1563 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1564 &pDevExt->Specific.RDR.VolumeTreeLock,
1565 PsGetCurrentThread());
1568 // Starve any exclusive waiters on this paticular call
1571 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1574 // Locate the volume node
1577 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1579 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1581 (AFSBTreeEntry **)&pVolumeCB);
1583 if( pVolumeCB != NULL)
1586 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1588 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1589 AFS_TRACE_LEVEL_VERBOSE,
1590 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1592 pVolumeCB->VolumeReferenceCount);
1595 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1597 if( !NT_SUCCESS( ntStatus) ||
1600 try_return( ntStatus = STATUS_SUCCESS);
1604 // If this is a whole volume invalidation then go do it now
1607 if( InvalidateCB->WholeVolume ||
1608 AFSIsVolumeFID( &InvalidateCB->FileID))
1611 ntStatus = AFSInvalidateVolume( pVolumeCB,
1612 InvalidateCB->Reason);
1614 AFSFsRtlNotifyFullReportChange( &pVolumeCB->ObjectInformation,
1616 FILE_NOTIFY_CHANGE_FILE_NAME |
1617 FILE_NOTIFY_CHANGE_DIR_NAME |
1618 FILE_NOTIFY_CHANGE_NAME |
1619 FILE_NOTIFY_CHANGE_ATTRIBUTES |
1620 FILE_NOTIFY_CHANGE_SIZE,
1621 FILE_ACTION_MODIFIED);
1623 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1625 try_return( ntStatus);
1628 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1631 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1633 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1634 AFS_TRACE_LEVEL_VERBOSE,
1635 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
1637 pVolumeCB->VolumeReferenceCount);
1639 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
1641 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
1643 (AFSBTreeEntry **)&pObjectInfo);
1645 if( pObjectInfo != NULL)
1649 // Reference the node so it won't be torn down
1652 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
1654 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1655 AFS_TRACE_LEVEL_VERBOSE,
1656 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
1658 pObjectInfo->ObjectReferenceCount);
1661 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1663 if( !NT_SUCCESS( ntStatus) ||
1664 pObjectInfo == NULL)
1666 try_return( ntStatus = STATUS_SUCCESS);
1669 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
1670 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK ||
1671 pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1674 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1675 AFS_TRACE_LEVEL_VERBOSE,
1676 "AFSInvalidateCache Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1677 pObjectInfo->FileType,
1678 pObjectInfo->FileId.Cell,
1679 pObjectInfo->FileId.Volume,
1680 pObjectInfo->FileId.Vnode,
1681 pObjectInfo->FileId.Unique,
1682 InvalidateCB->Reason);
1685 // We only act on the mount point itself, not the target. If the
1686 // node has been deleted then mark it as such otherwise indicate
1687 // it requires verification
1690 if( InvalidateCB->Reason == AFS_INVALIDATE_DELETED)
1692 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1697 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
1698 InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1700 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1703 pObjectInfo->Expiration.QuadPart = 0;
1705 pObjectInfo->TargetFileId.Vnode = 0;
1707 pObjectInfo->TargetFileId.Unique = 0;
1709 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1710 AFS_TRACE_LEVEL_VERBOSE,
1711 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1712 pObjectInfo->FileId.Cell,
1713 pObjectInfo->FileId.Volume,
1714 pObjectInfo->FileId.Vnode,
1715 pObjectInfo->FileId.Unique);
1717 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1720 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1722 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1724 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1727 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1729 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1733 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1736 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1738 FILE_NOTIFY_CHANGE_FILE_NAME |
1739 FILE_NOTIFY_CHANGE_ATTRIBUTES,
1740 FILE_ACTION_MODIFIED);
1742 try_return( ntStatus);
1746 // Depending on the reason for invalidation then perform work on the node
1749 switch( InvalidateCB->Reason)
1752 case AFS_INVALIDATE_DELETED:
1756 // Mark this node as invalid
1759 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
1761 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1762 AFS_TRACE_LEVEL_VERBOSE,
1763 "AFSInvalidateCache Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1764 pObjectInfo->FileId.Cell,
1765 pObjectInfo->FileId.Volume,
1766 pObjectInfo->FileId.Vnode,
1767 pObjectInfo->FileId.Unique);
1769 if( pObjectInfo->ParentObjectInformation != NULL)
1772 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1773 AFS_TRACE_LEVEL_VERBOSE,
1774 "AFSInvalidateCache Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1775 pObjectInfo->ParentObjectInformation->FileId.Cell,
1776 pObjectInfo->ParentObjectInformation->FileId.Volume,
1777 pObjectInfo->ParentObjectInformation->FileId.Vnode,
1778 pObjectInfo->ParentObjectInformation->FileId.Unique);
1780 SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1781 pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1782 pObjectInfo->ParentObjectInformation->Expiration.QuadPart = 0;
1785 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1787 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1791 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1794 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1797 FILE_ACTION_REMOVED);
1802 case AFS_INVALIDATE_FLUSHED:
1805 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
1806 pObjectInfo->Fcb != NULL)
1809 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1810 AFS_TRACE_LEVEL_VERBOSE,
1811 "AFSInvalidateCache Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1812 pObjectInfo->FileId.Cell,
1813 pObjectInfo->FileId.Volume,
1814 pObjectInfo->FileId.Vnode,
1815 pObjectInfo->FileId.Unique);
1817 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
1823 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1828 if( !NT_SUCCESS( stIoStatus.Status))
1831 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1832 AFS_TRACE_LEVEL_ERROR,
1833 "AFSInvalidateCache CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1834 pObjectInfo->FileId.Cell,
1835 pObjectInfo->FileId.Volume,
1836 pObjectInfo->FileId.Vnode,
1837 pObjectInfo->FileId.Unique,
1839 stIoStatus.Information);
1841 ntStatus = stIoStatus.Status;
1844 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1849 __except( EXCEPTION_EXECUTE_HANDLER)
1852 ntStatus = GetExceptionCode();
1855 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
1858 // Clear out the extents
1859 // Get rid of them (note this involves waiting
1860 // for any writes or reads to the cache to complete)
1863 (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb);
1866 // Fall through to the default processing
1872 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1874 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1878 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1881 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1883 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1886 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1888 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1892 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1895 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1898 FILE_ACTION_MODIFIED);
1901 // Indicate this node requires re-evaluation for the remaining reasons
1904 pObjectInfo->Expiration.QuadPart = 0;
1906 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1907 AFS_TRACE_LEVEL_VERBOSE,
1908 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1909 pObjectInfo->FileId.Cell,
1910 pObjectInfo->FileId.Volume,
1911 pObjectInfo->FileId.Vnode,
1912 pObjectInfo->FileId.Unique);
1914 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1916 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
1917 InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1919 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1921 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
1924 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1925 AFS_TRACE_LEVEL_VERBOSE,
1926 "AFSInvalidateCache Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1927 pObjectInfo->FileId.Cell,
1928 pObjectInfo->FileId.Volume,
1929 pObjectInfo->FileId.Vnode,
1930 pObjectInfo->FileId.Unique);
1932 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1942 if( pObjectInfo != NULL)
1945 InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
1947 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1948 AFS_TRACE_LEVEL_VERBOSE,
1949 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
1951 pObjectInfo->ObjectReferenceCount);
1959 AFSIsChildOfParent( IN AFSFcb *Dcb,
1963 BOOLEAN bIsChild = FALSE;
1964 AFSFcb *pCurrentFcb = Fcb;
1966 while( pCurrentFcb != NULL)
1969 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
1977 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
1985 AFSCreateHighIndex( IN AFSFileID *FileID)
1988 ULONGLONG ullIndex = 0;
1990 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
1997 AFSCreateLowIndex( IN AFSFileID *FileID)
2000 ULONGLONG ullIndex = 0;
2002 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2008 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2009 IN ACCESS_MASK GrantedAccess,
2010 IN BOOLEAN DirectoryEntry)
2013 BOOLEAN bAccessGranted = TRUE;
2016 // Check if we are asking for read/write and granted only read only
2017 // NOTE: There will be more checks here
2020 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2022 AFSCheckForReadOnlyAccess( GrantedAccess,
2026 bAccessGranted = FALSE;
2029 return bAccessGranted;
2033 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2036 NTSTATUS ntStatus = STATUS_SUCCESS;
2037 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2043 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2045 if( AFSGlobalRoot == NULL)
2052 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2055 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2062 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2069 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2070 IN UNICODE_STRING *SubstituteName,
2071 IN ULONG StringIndex)
2074 NTSTATUS ntStatus = STATUS_SUCCESS;
2075 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2076 AFSSysNameCB *pSysName = NULL;
2077 ERESOURCE *pSysNameLock = NULL;
2080 UNICODE_STRING uniSysName;
2087 if( IoIs32bitProcess( NULL))
2090 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2092 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2097 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2099 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2103 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2105 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2109 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2110 AFS_TRACE_LEVEL_VERBOSE,
2111 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2113 PsGetCurrentThread());
2115 AFSAcquireShared( pSysNameLock,
2119 // Find where we are in the list
2122 while( pSysName != NULL &&
2123 ulIndex < StringIndex)
2126 pSysName = pSysName->fLink;
2131 if( pSysName == NULL)
2134 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2137 RtlInitUnicodeString( &uniSysName,
2140 // If it is a full component of @SYS then just substitue the
2144 if( RtlCompareUnicodeString( &uniSysName,
2149 SubstituteName->Length = pSysName->SysName.Length;
2150 SubstituteName->MaximumLength = SubstituteName->Length;
2152 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2153 SubstituteName->Length,
2154 AFS_SUBST_BUFFER_TAG);
2156 if( SubstituteName->Buffer == NULL)
2159 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2162 RtlCopyMemory( SubstituteName->Buffer,
2163 pSysName->SysName.Buffer,
2164 pSysName->SysName.Length);
2171 while( ComponentName->Buffer[ usIndex] != L'@')
2177 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2178 SubstituteName->MaximumLength = SubstituteName->Length;
2180 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2181 SubstituteName->Length,
2182 AFS_SUBST_BUFFER_TAG);
2184 if( SubstituteName->Buffer == NULL)
2187 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2190 RtlCopyMemory( SubstituteName->Buffer,
2191 ComponentName->Buffer,
2192 usIndex * sizeof( WCHAR));
2194 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2195 pSysName->SysName.Buffer,
2196 pSysName->SysName.Length);
2201 AFSReleaseResource( pSysNameLock);
2208 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2209 IN OUT UNICODE_STRING *ComponentName,
2210 IN UNICODE_STRING *SubstituteName,
2211 IN OUT UNICODE_STRING *RemainingPath,
2212 IN BOOLEAN FreePathName)
2215 NTSTATUS ntStatus = STATUS_SUCCESS;
2216 UNICODE_STRING uniPathName;
2217 USHORT usPrefixNameLen = 0;
2218 SHORT sNameLenDelta = 0;
2224 // If the passed in name can handle the additional length
2225 // then just moves things around
2228 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2230 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2232 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2235 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2238 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2239 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2240 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2243 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2244 SubstituteName->Buffer,
2245 SubstituteName->Length);
2247 FullPathName->Length += sNameLenDelta;
2249 ComponentName->Length += sNameLenDelta;
2251 ComponentName->MaximumLength = ComponentName->Length;
2253 if ( RemainingPath->Buffer)
2256 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2259 try_return( ntStatus);
2263 // Need to re-allocate the buffer
2266 uniPathName.Length = FullPathName->Length -
2267 ComponentName->Length +
2268 SubstituteName->Length;
2270 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2272 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2273 uniPathName.MaximumLength,
2274 AFS_NAME_BUFFER_FOUR_TAG);
2276 if( uniPathName.Buffer == NULL)
2279 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2282 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2284 usPrefixNameLen *= sizeof( WCHAR);
2286 RtlZeroMemory( uniPathName.Buffer,
2287 uniPathName.MaximumLength);
2289 RtlCopyMemory( uniPathName.Buffer,
2290 FullPathName->Buffer,
2293 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2294 SubstituteName->Buffer,
2295 SubstituteName->Length);
2297 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2300 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2301 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2302 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2305 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2307 ComponentName->Length += sNameLenDelta;
2309 ComponentName->MaximumLength = ComponentName->Length;
2311 if ( RemainingPath->Buffer)
2314 RemainingPath->Buffer = uniPathName.Buffer
2315 + (RemainingPath->Buffer - FullPathName->Buffer)
2316 + sNameLenDelta/sizeof( WCHAR);
2321 AFSExFreePool( FullPathName->Buffer);
2324 *FullPathName = uniPathName;
2335 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2339 NTSTATUS ntStatus = STATUS_SUCCESS;
2340 AFSFcb *pFcb = NULL;
2341 AFSObjectInfoCB *pCurrentObject = NULL;
2347 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2348 AFS_TRACE_LEVEL_VERBOSE,
2349 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2350 VolumeCB->ObjectInformation.FileId.Cell,
2351 VolumeCB->ObjectInformation.FileId.Volume,
2352 VolumeCB->ObjectInformation.FileId.Vnode,
2353 VolumeCB->ObjectInformation.FileId.Unique,
2357 // Depending on the reason for invalidation then perform work on the node
2363 case AFS_INVALIDATE_DELETED:
2367 // Mark this volume as invalid
2370 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2372 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2374 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2376 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2378 FILE_NOTIFY_CHANGE_DIR_NAME,
2379 FILE_ACTION_REMOVED);
2381 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2384 pCurrentObject = VolumeCB->ObjectInfoListHead;
2386 while( pCurrentObject != NULL)
2389 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2391 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2395 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2398 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2401 FILE_ACTION_REMOVED);
2403 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2405 pFcb = pCurrentObject->Fcb;
2408 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2413 // Clear out the extents
2414 // And get rid of them (note this involves waiting
2415 // for any writes or reads to the cache to complete)
2418 (VOID) AFSTearDownFcbExtents( pFcb);
2421 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2424 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2433 // Indicate this node requires re-evaluation for the remaining reasons
2436 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2438 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2439 AFS_TRACE_LEVEL_VERBOSE,
2440 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2441 VolumeCB->ObjectInformation.FileId.Cell,
2442 VolumeCB->ObjectInformation.FileId.Volume,
2443 VolumeCB->ObjectInformation.FileId.Vnode,
2444 VolumeCB->ObjectInformation.FileId.Unique);
2446 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY);
2448 if( Reason == AFS_INVALIDATE_FLUSHED ||
2449 Reason == AFS_INVALIDATE_DATA_VERSION)
2452 VolumeCB->ObjectInformation.DataVersion.QuadPart = (ULONGLONG)-1;
2456 // Notify anyone that cares
2459 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2461 if( Reason == AFS_INVALIDATE_CREDS)
2463 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2466 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2468 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2472 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2475 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2478 FILE_ACTION_MODIFIED);
2481 // Volume invalidations require all objects in the volume be re-verified
2484 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2487 pCurrentObject = VolumeCB->ObjectInfoListHead;
2489 while( pCurrentObject != NULL)
2492 pCurrentObject->Expiration.QuadPart = 0;
2494 pCurrentObject->TargetFileId.Vnode = 0;
2496 pCurrentObject->TargetFileId.Unique = 0;
2498 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2499 AFS_TRACE_LEVEL_VERBOSE,
2500 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2501 pCurrentObject->FileId.Cell,
2502 pCurrentObject->FileId.Volume,
2503 pCurrentObject->FileId.Vnode,
2504 pCurrentObject->FileId.Unique);
2506 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
2508 if( Reason == AFS_INVALIDATE_FLUSHED ||
2509 Reason == AFS_INVALIDATE_DATA_VERSION)
2512 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
2514 if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
2517 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2518 AFS_TRACE_LEVEL_VERBOSE,
2519 "AFSInvalidateVolume Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
2520 pCurrentObject->FileId.Cell,
2521 pCurrentObject->FileId.Volume,
2522 pCurrentObject->FileId.Vnode,
2523 pCurrentObject->FileId.Unique);
2525 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2529 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2531 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2535 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2538 if( Reason == AFS_INVALIDATE_CREDS)
2540 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2543 if( Reason == AFS_INVALIDATE_DATA_VERSION)
2545 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2549 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2552 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2555 FILE_ACTION_MODIFIED);
2557 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2560 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2571 AFSVerifyEntry( IN GUID *AuthGroup,
2572 IN AFSDirectoryCB *DirEntry)
2575 NTSTATUS ntStatus = STATUS_SUCCESS;
2576 AFSDirEnumEntry *pDirEnumEntry = NULL;
2577 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2578 IO_STATUS_BLOCK stIoStatus;
2583 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2584 AFS_TRACE_LEVEL_VERBOSE_2,
2585 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2586 &DirEntry->NameInformation.FileName,
2587 pObjectInfo->FileId.Cell,
2588 pObjectInfo->FileId.Volume,
2589 pObjectInfo->FileId.Vnode,
2590 pObjectInfo->FileId.Unique);
2592 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2597 if( !NT_SUCCESS( ntStatus))
2600 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2601 AFS_TRACE_LEVEL_ERROR,
2602 "AFSValidateEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2603 &DirEntry->NameInformation.FileName,
2604 pObjectInfo->FileId.Cell,
2605 pObjectInfo->FileId.Volume,
2606 pObjectInfo->FileId.Vnode,
2607 pObjectInfo->FileId.Unique,
2610 try_return( ntStatus);
2614 // Check the data version of the file
2617 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2618 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2621 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2622 AFS_TRACE_LEVEL_VERBOSE,
2623 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2624 pObjectInfo->DataVersion.QuadPart,
2625 &DirEntry->NameInformation.FileName,
2626 pObjectInfo->FileId.Cell,
2627 pObjectInfo->FileId.Volume,
2628 pObjectInfo->FileId.Vnode,
2629 pObjectInfo->FileId.Unique);
2632 // We are ok, just get out
2635 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2637 try_return( ntStatus = STATUS_SUCCESS);
2641 // New data version so we will need to process the node based on the type
2644 switch( pDirEnumEntry->FileType)
2647 case AFS_FILE_TYPE_MOUNTPOINT:
2651 // For a mount point we need to ensure the target is the same
2654 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2655 &pDirEnumEntry->TargetFileId))
2661 // Update the metadata for the entry
2664 ntStatus = AFSUpdateMetaData( DirEntry,
2667 if( NT_SUCCESS( ntStatus))
2670 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2676 case AFS_FILE_TYPE_SYMLINK:
2679 ASSERT( pDirEnumEntry->TargetNameLength > 0);
2682 // Update the metadata for the entry
2685 ntStatus = AFSUpdateMetaData( DirEntry,
2688 if( NT_SUCCESS( ntStatus))
2691 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2697 case AFS_FILE_TYPE_FILE:
2699 FILE_OBJECT * pCCFileObject = NULL;
2700 BOOLEAN bPurgeExtents = FALSE;
2702 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2704 bPurgeExtents = TRUE;
2706 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2707 AFS_TRACE_LEVEL_VERBOSE,
2708 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2709 &DirEntry->NameInformation.FileName,
2710 pObjectInfo->FileId.Cell,
2711 pObjectInfo->FileId.Volume,
2712 pObjectInfo->FileId.Vnode,
2713 pObjectInfo->FileId.Unique);
2715 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2719 // Update the metadata for the entry
2722 ntStatus = AFSUpdateMetaData( DirEntry,
2725 if( !NT_SUCCESS( ntStatus))
2728 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2729 AFS_TRACE_LEVEL_ERROR,
2730 "AFSInvalidateCache Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2731 &DirEntry->NameInformation.FileName,
2732 pObjectInfo->FileId.Cell,
2733 pObjectInfo->FileId.Volume,
2734 pObjectInfo->FileId.Vnode,
2735 pObjectInfo->FileId.Unique,
2741 if( pObjectInfo->Fcb != NULL)
2744 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2745 AFS_TRACE_LEVEL_VERBOSE,
2746 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2747 &DirEntry->NameInformation.FileName,
2748 pObjectInfo->FileId.Cell,
2749 pObjectInfo->FileId.Volume,
2750 pObjectInfo->FileId.Vnode,
2751 pObjectInfo->FileId.Unique);
2753 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2759 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2764 if( !NT_SUCCESS( stIoStatus.Status))
2767 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2768 AFS_TRACE_LEVEL_ERROR,
2769 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2770 &DirEntry->NameInformation.FileName,
2771 pObjectInfo->FileId.Cell,
2772 pObjectInfo->FileId.Volume,
2773 pObjectInfo->FileId.Vnode,
2774 pObjectInfo->FileId.Unique,
2776 stIoStatus.Information);
2778 ntStatus = stIoStatus.Status;
2784 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2790 __except( EXCEPTION_EXECUTE_HANDLER)
2792 ntStatus = GetExceptionCode();
2794 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2795 AFS_TRACE_LEVEL_ERROR,
2796 "AFSVerifyEntry CcFlushCache or CcPurgeCacheSection Exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2797 &DirEntry->NameInformation.FileName,
2798 pObjectInfo->FileId.Cell,
2799 pObjectInfo->FileId.Volume,
2800 pObjectInfo->FileId.Vnode,
2801 pObjectInfo->FileId.Unique,
2805 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2809 AFSFlushExtents( pObjectInfo->Fcb);
2813 // Reacquire the Fcb to purge the cache
2816 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2817 AFS_TRACE_LEVEL_VERBOSE,
2818 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2819 &pObjectInfo->Fcb->NPFcb->Resource,
2820 PsGetCurrentThread());
2822 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2826 // Update file sizes
2829 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2830 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2831 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2833 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2835 if ( pCCFileObject != NULL)
2837 CcSetFileSizes( pCCFileObject,
2838 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
2841 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2845 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2846 AFS_TRACE_LEVEL_WARNING,
2847 "AFSValidateEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2848 &DirEntry->NameInformation.FileName,
2849 pObjectInfo->FileId.Cell,
2850 pObjectInfo->FileId.Volume,
2851 pObjectInfo->FileId.Vnode,
2852 pObjectInfo->FileId.Unique);
2855 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2860 case AFS_FILE_TYPE_DIRECTORY:
2863 AFSFcb *pCurrentFcb = NULL;
2864 AFSDirectoryCB *pCurrentDirEntry = NULL;
2867 // For a directory or root entry flush the content of
2868 // the directory enumeration.
2871 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2874 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2875 AFS_TRACE_LEVEL_VERBOSE_2,
2876 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2877 &DirEntry->NameInformation.FileName,
2878 pObjectInfo->FileId.Cell,
2879 pObjectInfo->FileId.Volume,
2880 pObjectInfo->FileId.Vnode,
2881 pObjectInfo->FileId.Unique);
2883 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2886 AFSValidateDirectoryCache( pObjectInfo,
2889 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2893 // Update the metadata for the entry
2896 ntStatus = AFSUpdateMetaData( DirEntry,
2899 if( NT_SUCCESS( ntStatus))
2902 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2908 case AFS_FILE_TYPE_DFSLINK:
2911 UNICODE_STRING uniTargetName;
2914 // For a DFS link need to check the target name has not changed
2917 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
2919 uniTargetName.MaximumLength = uniTargetName.Length;
2921 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
2923 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
2926 if( DirEntry->NameInformation.TargetName.Length == 0 ||
2927 RtlCompareUnicodeString( &uniTargetName,
2928 &DirEntry->NameInformation.TargetName,
2933 // Update the target name
2936 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
2938 uniTargetName.Buffer,
2939 uniTargetName.Length);
2941 if( !NT_SUCCESS( ntStatus))
2944 AFSReleaseResource( &DirEntry->NonPaged->Lock);
2950 AFSReleaseResource( &DirEntry->NonPaged->Lock);
2953 // Update the metadata for the entry
2956 ntStatus = AFSUpdateMetaData( DirEntry,
2959 if( NT_SUCCESS( ntStatus))
2962 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2970 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2971 AFS_TRACE_LEVEL_WARNING,
2972 "AFSVerifyEntry Attempt to verify node of type %d\n",
2973 pObjectInfo->FileType);
2980 if( pDirEnumEntry != NULL)
2983 AFSExFreePool( pDirEnumEntry);
2991 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
2994 NTSTATUS ntStatus = STATUS_SUCCESS;
2995 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
2996 ULONGLONG ullIndex = 0;
2997 AFSVolumeCB *pVolumeCB = NULL;
2998 AFSFcb *pFcb = NULL;
2999 AFSObjectInfoCB *pCurrentObject = NULL;
3004 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3005 AFS_TRACE_LEVEL_VERBOSE,
3006 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3007 VolumeStatus->Online,
3008 VolumeStatus->FileID.Cell,
3009 VolumeStatus->FileID.Volume);
3012 // Need to locate the Fcb for the directory to purge
3015 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3016 AFS_TRACE_LEVEL_VERBOSE,
3017 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3018 &pDevExt->Specific.RDR.VolumeTreeLock,
3019 PsGetCurrentThread());
3021 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3024 // Locate the volume node
3027 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3029 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3031 (AFSBTreeEntry **)&pVolumeCB);
3033 if( pVolumeCB != NULL)
3036 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3038 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3041 // Set the volume state accordingly
3044 if( VolumeStatus->Online)
3047 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3052 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3055 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3058 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3060 while( pCurrentObject != NULL)
3063 if( VolumeStatus->Online)
3066 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3068 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3070 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3075 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3078 pFcb = pCurrentObject->Fcb;
3081 !(VolumeStatus->Online) &&
3082 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3085 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3086 AFS_TRACE_LEVEL_ERROR,
3087 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3088 VolumeStatus->FileID.Cell,
3089 VolumeStatus->FileID.Volume);
3092 // Clear out the extents
3095 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3096 AFS_TRACE_LEVEL_VERBOSE,
3097 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3098 &pFcb->NPFcb->Specific.File.ExtentsResource,
3099 PsGetCurrentThread());
3101 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3104 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3106 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3110 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3111 AFS_TRACE_LEVEL_VERBOSE,
3112 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3113 &pFcb->NPFcb->Specific.File.ExtentsResource,
3114 PsGetCurrentThread());
3116 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3119 // And get rid of them (note this involves waiting
3120 // for any writes or reads to the cache to complete)
3123 (VOID) AFSTearDownFcbExtents( pFcb);
3126 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3129 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3131 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3136 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3144 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3147 NTSTATUS ntStatus = STATUS_SUCCESS;
3152 if( AFSGlobalRoot == NULL)
3155 try_return( ntStatus);
3158 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3162 // Set the network state according to the information
3165 if( NetworkStatus->Online)
3168 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3173 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3176 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3187 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3191 NTSTATUS ntStatus = STATUS_SUCCESS;
3192 BOOLEAN bAcquiredLock = FALSE;
3193 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3194 AFSFcb *pFcb = NULL;
3199 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3200 AFS_TRACE_LEVEL_VERBOSE,
3201 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3202 ObjectInfo->FileId.Cell,
3203 ObjectInfo->FileId.Volume,
3204 ObjectInfo->FileId.Vnode,
3205 ObjectInfo->FileId.Unique);
3207 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3210 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3211 AFS_TRACE_LEVEL_VERBOSE,
3212 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3213 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3214 PsGetCurrentThread());
3216 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3219 bAcquiredLock = TRUE;
3223 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3226 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3227 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3230 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3231 AFS_TRACE_LEVEL_ERROR,
3232 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
3233 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3234 ObjectInfo->FileId.Cell,
3235 ObjectInfo->FileId.Volume,
3236 ObjectInfo->FileId.Vnode,
3237 ObjectInfo->FileId.Unique);
3241 // Reset the directory list information by clearing all valid entries
3244 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3246 while( pCurrentDirEntry != NULL)
3249 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3252 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3254 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3255 AFS_TRACE_LEVEL_VERBOSE,
3256 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3258 pCurrentDirEntry->OpenReferenceCount);
3262 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3266 // Reget the directory contents
3269 AFSVerifyDirectoryContent( ObjectInfo,
3273 // Now start again and tear down any entries not valid
3276 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3278 while( pCurrentDirEntry != NULL)
3281 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3283 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3286 pCurrentDirEntry = pNextDirEntry;
3291 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3292 AFS_TRACE_LEVEL_VERBOSE,
3293 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3295 pCurrentDirEntry->OpenReferenceCount);
3297 if( pCurrentDirEntry->OpenReferenceCount == 0)
3300 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3301 AFS_TRACE_LEVEL_VERBOSE,
3302 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3303 &pCurrentDirEntry->NameInformation.FileName,
3304 ObjectInfo->FileId.Cell,
3305 ObjectInfo->FileId.Volume,
3306 ObjectInfo->FileId.Vnode,
3307 ObjectInfo->FileId.Unique);
3309 AFSDeleteDirEntry( ObjectInfo,
3315 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3316 AFS_TRACE_LEVEL_VERBOSE,
3317 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3319 &pCurrentDirEntry->NameInformation.FileName,
3320 ObjectInfo->FileId.Cell,
3321 ObjectInfo->FileId.Volume,
3322 ObjectInfo->FileId.Vnode,
3323 ObjectInfo->FileId.Unique);
3325 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3327 AFSRemoveNameEntry( ObjectInfo,
3331 pCurrentDirEntry = pNextDirEntry;
3335 if( !AFSValidateDirList( ObjectInfo))
3338 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3345 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3353 AFSIsVolumeFID( IN AFSFileID *FileID)
3356 BOOLEAN bIsVolume = FALSE;
3358 if( FileID->Vnode == 1 &&
3359 FileID->Unique == 1)
3369 AFSIsFinalNode( IN AFSFcb *Fcb)
3372 BOOLEAN bIsFinalNode = FALSE;
3374 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3375 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3376 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3377 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3378 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3381 bIsFinalNode = TRUE;
3386 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3387 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3390 return bIsFinalNode;
3394 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3395 IN AFSDirEnumEntry *DirEnumEntry)
3398 NTSTATUS ntStatus = STATUS_SUCCESS;
3399 UNICODE_STRING uniTargetName;
3400 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3405 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3407 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3409 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3411 pObjectInfo->FileType = DirEnumEntry->FileType;
3413 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3415 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3417 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3419 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3421 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3423 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3425 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3427 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
3428 pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3429 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3432 pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
3435 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3437 pObjectInfo->Links = DirEnumEntry->Links;
3439 if( DirEnumEntry->TargetNameLength > 0)
3443 // Update the target name information if needed
3446 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3448 uniTargetName.MaximumLength = uniTargetName.Length;
3450 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3452 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3455 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3456 RtlCompareUnicodeString( &uniTargetName,
3457 &DirEntry->NameInformation.TargetName,
3462 // Update the target name
3465 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3467 uniTargetName.Buffer,
3468 uniTargetName.Length);
3470 if( !NT_SUCCESS( ntStatus))
3473 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3475 try_return( ntStatus);
3479 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3481 else if( DirEntry->NameInformation.TargetName.Length > 0)
3484 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3487 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3488 DirEntry->NameInformation.TargetName.Buffer != NULL)
3490 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
3493 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3495 DirEntry->NameInformation.TargetName.Length = 0;
3496 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3497 DirEntry->NameInformation.TargetName.Buffer = NULL;
3499 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3511 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3513 IN BOOLEAN PurgeContent,
3514 IN BOOLEAN FastCall)
3517 NTSTATUS ntStatus = STATUS_SUCCESS;
3518 LARGE_INTEGER liSystemTime;
3519 AFSDirEnumEntry *pDirEnumEntry = NULL;
3520 AFSFcb *pCurrentFcb = NULL;
3521 BOOLEAN bReleaseFcb = FALSE;
3522 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3528 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3532 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3533 AFS_TRACE_LEVEL_VERBOSE_2,
3534 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3535 &DirEntry->NameInformation.FileName,
3536 pObjectInfo->FileId.Cell,
3537 pObjectInfo->FileId.Volume,
3538 pObjectInfo->FileId.Vnode,
3539 pObjectInfo->FileId.Unique);
3542 // If this is a fake node then bail since the service knows nothing about it
3545 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3548 try_return( ntStatus);
3552 pObjectInfo->Fcb != NULL)
3555 pCurrentFcb = pObjectInfo->Fcb;
3557 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3560 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3561 AFS_TRACE_LEVEL_VERBOSE,
3562 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3563 &pCurrentFcb->NPFcb->Resource,
3564 PsGetCurrentThread());
3566 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3574 // This routine ensures that the current entry is valid by:
3576 // 1) Checking that the expiration time is non-zero and after where we
3580 KeQuerySystemTime( &liSystemTime);
3582 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3583 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3584 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3585 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3588 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3589 AFS_TRACE_LEVEL_VERBOSE_2,
3590 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3591 &DirEntry->NameInformation.FileName,
3592 pObjectInfo->FileId.Cell,
3593 pObjectInfo->FileId.Volume,
3594 pObjectInfo->FileId.Vnode,
3595 pObjectInfo->FileId.Unique);
3597 try_return( ntStatus);
3601 // This node requires updating
3604 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3609 if( !NT_SUCCESS( ntStatus))
3612 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3613 AFS_TRACE_LEVEL_ERROR,
3614 "AFSValidateEntry Failed to evaluate entry %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3615 &DirEntry->NameInformation.FileName,
3616 pObjectInfo->FileId.Cell,
3617 pObjectInfo->FileId.Volume,
3618 pObjectInfo->FileId.Vnode,
3619 pObjectInfo->FileId.Unique,
3623 // Failed validation of node so return access-denied
3626 try_return( ntStatus);
3629 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3630 AFS_TRACE_LEVEL_VERBOSE,
3631 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3632 &DirEntry->NameInformation.FileName,
3633 pObjectInfo->FileId.Cell,
3634 pObjectInfo->FileId.Volume,
3635 pObjectInfo->FileId.Vnode,
3636 pObjectInfo->FileId.Unique,
3637 pObjectInfo->DataVersion.QuadPart,
3638 pDirEnumEntry->DataVersion.QuadPart,
3639 pDirEnumEntry->FileType);
3643 // Based on the file type, process the node
3646 switch( pDirEnumEntry->FileType)
3649 case AFS_FILE_TYPE_MOUNTPOINT:
3653 // Update the metadata for the entry
3656 ntStatus = AFSUpdateMetaData( DirEntry,
3659 if( NT_SUCCESS( ntStatus))
3662 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3668 case AFS_FILE_TYPE_SYMLINK:
3669 case AFS_FILE_TYPE_DFSLINK:
3673 // Update the metadata for the entry
3676 ntStatus = AFSUpdateMetaData( DirEntry,
3679 if( NT_SUCCESS( ntStatus))
3682 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3688 case AFS_FILE_TYPE_FILE:
3692 // For a file where the data version has become invalid we need to
3693 // fail any current extent requests and purge the cache for the file
3694 // Can't hold the Fcb resource while doing this
3697 if( pCurrentFcb != NULL &&
3698 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3699 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3702 IO_STATUS_BLOCK stIoStatus;
3703 BOOLEAN bPurgeExtents = FALSE;
3705 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3706 AFS_TRACE_LEVEL_VERBOSE_2,
3707 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3708 &DirEntry->NameInformation.FileName,
3709 pObjectInfo->FileId.Cell,
3710 pObjectInfo->FileId.Volume,
3711 pObjectInfo->FileId.Vnode,
3712 pObjectInfo->FileId.Unique);
3714 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3716 bPurgeExtents = TRUE;
3718 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3719 AFS_TRACE_LEVEL_VERBOSE,
3720 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3721 &DirEntry->NameInformation.FileName,
3722 pObjectInfo->FileId.Cell,
3723 pObjectInfo->FileId.Volume,
3724 pObjectInfo->FileId.Vnode,
3725 pObjectInfo->FileId.Unique);
3727 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3733 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
3738 if( !NT_SUCCESS( stIoStatus.Status))
3741 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3742 AFS_TRACE_LEVEL_ERROR,
3743 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3744 &DirEntry->NameInformation.FileName,
3745 pObjectInfo->FileId.Cell,
3746 pObjectInfo->FileId.Volume,
3747 pObjectInfo->FileId.Vnode,
3748 pObjectInfo->FileId.Unique,
3750 stIoStatus.Information);
3752 ntStatus = stIoStatus.Status;
3758 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3764 __except( EXCEPTION_EXECUTE_HANDLER)
3766 ntStatus = GetExceptionCode();
3768 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3769 AFS_TRACE_LEVEL_ERROR,
3770 "AFSValidateEntry CcFlushCache or CcPurgeCacheSection exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3771 &DirEntry->NameInformation.FileName,
3772 pObjectInfo->FileId.Cell,
3773 pObjectInfo->FileId.Volume,
3774 pObjectInfo->FileId.Vnode,
3775 pObjectInfo->FileId.Unique,
3780 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3784 AFSFlushExtents( pCurrentFcb);
3788 // Reacquire the Fcb to purge the cache
3791 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3792 AFS_TRACE_LEVEL_VERBOSE,
3793 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3794 &pCurrentFcb->NPFcb->Resource,
3795 PsGetCurrentThread());
3797 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3802 // Update the metadata for the entry
3805 ntStatus = AFSUpdateMetaData( DirEntry,
3808 if( !NT_SUCCESS( ntStatus))
3811 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3812 AFS_TRACE_LEVEL_ERROR,
3813 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3814 &DirEntry->NameInformation.FileName,
3815 pObjectInfo->FileId.Cell,
3816 pObjectInfo->FileId.Volume,
3817 pObjectInfo->FileId.Vnode,
3818 pObjectInfo->FileId.Unique,
3824 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3827 // Update file sizes
3830 if( pObjectInfo->Fcb != NULL)
3832 FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3834 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3835 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3836 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3838 if ( pCCFileObject != NULL)
3840 CcSetFileSizes( pCCFileObject,
3841 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3848 case AFS_FILE_TYPE_DIRECTORY:
3851 AFSDirectoryCB *pCurrentDirEntry = NULL;
3853 if( pCurrentFcb != NULL &&
3854 pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
3858 // For a directory or root entry flush the content of
3859 // the directory enumeration.
3862 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3863 AFS_TRACE_LEVEL_VERBOSE,
3864 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3865 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3866 PsGetCurrentThread());
3868 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
3871 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3872 AFS_TRACE_LEVEL_VERBOSE_2,
3873 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3874 &DirEntry->NameInformation.FileName,
3875 pObjectInfo->FileId.Cell,
3876 pObjectInfo->FileId.Volume,
3877 pObjectInfo->FileId.Vnode,
3878 pObjectInfo->FileId.Unique);
3880 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3883 AFSValidateDirectoryCache( pCurrentFcb->ObjectInformation,
3886 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3889 if( !NT_SUCCESS( ntStatus))
3892 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3893 AFS_TRACE_LEVEL_ERROR,
3894 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3895 &DirEntry->NameInformation.FileName,
3896 pObjectInfo->FileId.Cell,
3897 pObjectInfo->FileId.Volume,
3898 pObjectInfo->FileId.Vnode,
3899 pObjectInfo->FileId.Unique,
3907 // Update the metadata for the entry
3910 ntStatus = AFSUpdateMetaData( DirEntry,
3913 if( NT_SUCCESS( ntStatus))
3916 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3924 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3925 AFS_TRACE_LEVEL_WARNING,
3926 "AFSValidateEntry Attempt to verify node of type %d\n",
3927 pObjectInfo->FileType);
3937 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3940 if( pDirEnumEntry != NULL)
3943 AFSExFreePool( pDirEnumEntry);
3951 AFSInitializeSpecialShareNameList()
3954 NTSTATUS ntStatus = STATUS_SUCCESS;
3955 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
3956 AFSObjectInfoCB *pObjectInfoCB = NULL;
3957 UNICODE_STRING uniShareName;
3958 ULONG ulEntryLength = 0;
3959 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
3964 RtlInitUnicodeString( &uniShareName,
3967 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
3970 if( pObjectInfoCB == NULL)
3973 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
3976 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3977 AFS_TRACE_LEVEL_VERBOSE,
3978 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
3981 pObjectInfoCB->ObjectReferenceCount = 1;
3983 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
3985 ulEntryLength = sizeof( AFSDirectoryCB) +
3986 uniShareName.Length;
3988 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
3992 if( pDirNode == NULL)
3995 AFSDeleteObjectInfo( pObjectInfoCB);
3997 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4000 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4001 sizeof( AFSNonPagedDirectoryCB),
4002 AFS_DIR_ENTRY_NP_TAG);
4004 if( pNonPagedDirEntry == NULL)
4007 ExFreePool( pDirNode);
4009 AFSDeleteObjectInfo( pObjectInfoCB);
4011 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4014 RtlZeroMemory( pDirNode,
4017 RtlZeroMemory( pNonPagedDirEntry,
4018 sizeof( AFSNonPagedDirectoryCB));
4020 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4022 pDirNode->NonPaged = pNonPagedDirEntry;
4024 pDirNode->ObjectInformation = pObjectInfoCB;
4030 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
4032 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4034 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4036 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4038 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4039 uniShareName.Buffer,
4040 pDirNode->NameInformation.FileName.Length);
4042 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4045 AFSSpecialShareNames = pDirNode;
4047 pLastDirNode = pDirNode;
4049 RtlInitUnicodeString( &uniShareName,
4052 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4055 if( pObjectInfoCB == NULL)
4058 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4061 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4062 AFS_TRACE_LEVEL_VERBOSE,
4063 "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
4066 pObjectInfoCB->ObjectReferenceCount = 1;
4068 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4070 ulEntryLength = sizeof( AFSDirectoryCB) +
4071 uniShareName.Length;
4073 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4077 if( pDirNode == NULL)
4080 AFSDeleteObjectInfo( pObjectInfoCB);
4082 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4085 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4086 sizeof( AFSNonPagedDirectoryCB),
4087 AFS_DIR_ENTRY_NP_TAG);
4089 if( pNonPagedDirEntry == NULL)
4092 ExFreePool( pDirNode);
4094 AFSDeleteObjectInfo( pObjectInfoCB);
4096 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4099 RtlZeroMemory( pDirNode,
4102 RtlZeroMemory( pNonPagedDirEntry,
4103 sizeof( AFSNonPagedDirectoryCB));
4105 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4107 pDirNode->NonPaged = pNonPagedDirEntry;
4109 pDirNode->ObjectInformation = pObjectInfoCB;
4115 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
4117 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4119 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4121 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4123 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4124 uniShareName.Buffer,
4125 pDirNode->NameInformation.FileName.Length);
4127 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4130 pLastDirNode->ListEntry.fLink = pDirNode;
4132 pDirNode->ListEntry.bLink = pLastDirNode;
4134 pLastDirNode = pDirNode;
4136 RtlInitUnicodeString( &uniShareName,
4139 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4142 if( pObjectInfoCB == NULL)
4145 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4148 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4149 AFS_TRACE_LEVEL_VERBOSE,
4150 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4153 pObjectInfoCB->ObjectReferenceCount = 1;
4155 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4157 ulEntryLength = sizeof( AFSDirectoryCB) +
4158 uniShareName.Length;
4160 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4164 if( pDirNode == NULL)
4167 AFSDeleteObjectInfo( pObjectInfoCB);
4169 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4172 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4173 sizeof( AFSNonPagedDirectoryCB),
4174 AFS_DIR_ENTRY_NP_TAG);
4176 if( pNonPagedDirEntry == NULL)
4179 ExFreePool( pDirNode);
4181 AFSDeleteObjectInfo( pObjectInfoCB);
4183 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4186 RtlZeroMemory( pDirNode,
4189 RtlZeroMemory( pNonPagedDirEntry,
4190 sizeof( AFSNonPagedDirectoryCB));
4192 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4194 pDirNode->NonPaged = pNonPagedDirEntry;
4196 pDirNode->ObjectInformation = pObjectInfoCB;
4202 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4204 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4206 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4208 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4210 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4211 uniShareName.Buffer,
4212 pDirNode->NameInformation.FileName.Length);
4214 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4217 pLastDirNode->ListEntry.fLink = pDirNode;
4219 pDirNode->ListEntry.bLink = pLastDirNode;
4223 if( !NT_SUCCESS( ntStatus))
4226 if( AFSSpecialShareNames != NULL)
4229 pDirNode = AFSSpecialShareNames;
4231 while( pDirNode != NULL)
4234 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4236 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4238 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4240 ExFreePool( pDirNode->NonPaged);
4242 ExFreePool( pDirNode);
4244 pDirNode = pLastDirNode;
4247 AFSSpecialShareNames = NULL;
4256 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4257 IN UNICODE_STRING *SecondaryName)
4260 AFSDirectoryCB *pDirectoryCB = NULL;
4261 ULONGLONG ullHash = 0;
4262 UNICODE_STRING uniFullShareName;
4268 // Build up the entire name here. We are guaranteed that if there is a
4269 // secondary name, it is pointing to a portion of the share name buffer
4272 if( SecondaryName->Length > 0 &&
4273 SecondaryName->Buffer != NULL)
4276 uniFullShareName = *SecondaryName;
4279 // The calling routine strips off the leading slash so add it back in
4282 uniFullShareName.Buffer--;
4283 uniFullShareName.Length += sizeof( WCHAR);
4284 uniFullShareName.MaximumLength += sizeof( WCHAR);
4287 // And the share name
4290 uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
4291 uniFullShareName.Length += ShareName->Length;
4292 uniFullShareName.MaximumLength += ShareName->Length;
4297 uniFullShareName = *ShareName;
4301 // Generate our hash value
4304 ullHash = AFSGenerateCRC( &uniFullShareName,
4308 // Loop through our special share names to see if this is one of them
4311 pDirectoryCB = AFSSpecialShareNames;
4313 while( pDirectoryCB != NULL)
4316 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4322 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4326 return pDirectoryCB;
4330 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4334 // Block on the queue flush event
4337 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4347 AFSWaitOnQueuedReleases()
4350 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4353 // Block on the queue flush event
4356 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4366 AFSIsEqualFID( IN AFSFileID *FileId1,
4367 IN AFSFileID *FileId2)
4370 BOOLEAN bIsEqual = FALSE;
4372 if( FileId1->Unique == FileId2->Unique &&
4373 FileId1->Vnode == FileId2->Vnode &&
4374 FileId1->Volume == FileId2->Volume &&
4375 FileId1->Cell == FileId2->Cell)
4385 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4388 NTSTATUS ntStatus = STATUS_SUCCESS;
4389 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4394 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4397 // Reset the directory list information
4400 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4402 while( pCurrentDirEntry != NULL)
4405 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4407 if( pCurrentDirEntry->OpenReferenceCount == 0)
4410 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4411 AFS_TRACE_LEVEL_VERBOSE,
4412 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4414 &pCurrentDirEntry->NameInformation.FileName);
4416 AFSDeleteDirEntry( ObjectInfoCB,
4422 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4423 AFS_TRACE_LEVEL_VERBOSE,
4424 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4426 &pCurrentDirEntry->NameInformation.FileName);
4428 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4430 AFSRemoveNameEntry( ObjectInfoCB,
4434 pCurrentDirEntry = pNextDirEntry;
4437 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4439 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4441 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4443 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4445 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4447 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4449 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4450 AFS_TRACE_LEVEL_VERBOSE,
4451 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4452 ObjectInfoCB->FileId.Cell,
4453 ObjectInfoCB->FileId.Volume,
4454 ObjectInfoCB->FileId.Vnode,
4455 ObjectInfoCB->FileId.Unique);
4462 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4465 NTSTATUS ntStatus = STATUS_SUCCESS;
4466 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4467 UNICODE_STRING uniFullName;
4472 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4473 AFS_TRACE_LEVEL_VERBOSE,
4474 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4475 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4476 PsGetCurrentThread());
4478 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4481 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4484 try_return( ntStatus);
4488 // Initialize the root information
4491 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4494 // Enumerate the shares in the volume
4497 ntStatus = AFSEnumerateDirectory( AuthGroup,
4498 &AFSGlobalRoot->ObjectInformation,
4501 if( !NT_SUCCESS( ntStatus))
4504 try_return( ntStatus);
4507 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4510 // Indicate the node is initialized
4513 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4515 uniFullName.MaximumLength = PAGE_SIZE;
4516 uniFullName.Length = 0;
4518 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4519 uniFullName.MaximumLength,
4520 AFS_GENERIC_MEMORY_12_TAG);
4522 if( uniFullName.Buffer == NULL)
4526 // Reset the directory content
4529 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4531 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4533 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4537 // Populate our list of entries in the NP enumeration list
4540 while( pDirGlobalDirNode != NULL)
4543 uniFullName.Buffer[ 0] = L'\\';
4544 uniFullName.Buffer[ 1] = L'\\';
4546 uniFullName.Length = 2 * sizeof( WCHAR);
4548 RtlCopyMemory( &uniFullName.Buffer[ 2],
4549 AFSServerName.Buffer,
4550 AFSServerName.Length);
4552 uniFullName.Length += AFSServerName.Length;
4554 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4556 uniFullName.Length += sizeof( WCHAR);
4558 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4559 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4560 pDirGlobalDirNode->NameInformation.FileName.Length);
4562 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4564 AFSAddConnectionEx( &uniFullName,
4565 RESOURCEDISPLAYTYPE_SHARE,
4568 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4571 AFSExFreePool( uniFullName.Buffer);
4575 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4582 AFSIsRelativeName( IN UNICODE_STRING *Name)
4585 BOOLEAN bIsRelative = FALSE;
4587 if( Name->Buffer[ 0] != L'\\')
4597 AFSUpdateName( IN UNICODE_STRING *Name)
4602 while( usIndex < Name->Length/sizeof( WCHAR))
4605 if( Name->Buffer[ usIndex] == L'/')
4608 Name->Buffer[ usIndex] = L'\\';
4618 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4619 IN OUT ULONG *Flags,
4620 IN WCHAR *NameBuffer,
4621 IN USHORT NameLength)
4624 NTSTATUS ntStatus = STATUS_SUCCESS;
4625 WCHAR *pTmpBuffer = NULL;
4631 // If we have enough space then just move in the name otherwise
4632 // allocate a new buffer
4635 if( TargetName->Length < NameLength)
4638 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4640 AFS_NAME_BUFFER_FIVE_TAG);
4642 if( pTmpBuffer == NULL)
4645 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4648 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4651 AFSExFreePool( TargetName->Buffer);
4654 TargetName->MaximumLength = NameLength;
4656 TargetName->Buffer = pTmpBuffer;
4658 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4661 TargetName->Length = NameLength;
4663 RtlCopyMemory( TargetName->Buffer,
4665 TargetName->Length);
4668 // Update the name in the buffer
4671 AFSUpdateName( TargetName);
4682 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4683 IN ULONG InitialElementCount)
4686 AFSNameArrayHdr *pNameArray = NULL;
4687 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4692 if( InitialElementCount == 0)
4695 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
4698 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
4699 sizeof( AFSNameArrayHdr) +
4700 (InitialElementCount * sizeof( AFSNameArrayCB)),
4701 AFS_NAME_ARRAY_TAG);
4703 if( pNameArray == NULL)
4706 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4707 AFS_TRACE_LEVEL_ERROR,
4708 "AFSInitNameArray Failed to allocate name array\n");
4710 try_return( pNameArray);
4713 RtlZeroMemory( pNameArray,
4714 sizeof( AFSNameArrayHdr) +
4715 (InitialElementCount * sizeof( AFSNameArrayCB)));
4717 pNameArray->MaxElementCount = InitialElementCount;
4719 if( DirectoryCB != NULL)
4722 pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
4724 InterlockedIncrement( &pNameArray->Count);
4726 InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
4728 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4729 AFS_TRACE_LEVEL_VERBOSE,
4730 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
4731 &DirectoryCB->NameInformation.FileName,
4733 DirectoryCB->OpenReferenceCount);
4735 pNameArray->CurrentEntry->DirectoryCB = DirectoryCB;
4737 pNameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
4739 pNameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
4751 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
4752 IN UNICODE_STRING *Path,
4753 IN AFSDirectoryCB *DirectoryCB)
4756 NTSTATUS ntStatus = STATUS_SUCCESS;
4757 AFSNameArrayCB *pCurrentElement = NULL;
4758 UNICODE_STRING uniComponentName, uniRemainingPath;
4759 AFSObjectInfoCB *pCurrentObject = NULL;
4760 ULONG ulTotalCount = 0;
4762 USHORT usLength = 0;
4768 // Init some info in the header
4771 pCurrentElement = &NameArray->ElementArray[ 0];
4773 NameArray->CurrentEntry = pCurrentElement;
4776 // The first entry points at the root
4779 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
4781 InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4783 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4784 AFS_TRACE_LEVEL_VERBOSE,
4785 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
4786 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4787 pCurrentElement->DirectoryCB,
4788 pCurrentElement->DirectoryCB->OpenReferenceCount);
4790 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
4792 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
4794 NameArray->Count = 1;
4796 NameArray->LinkCount = 0;
4799 // If the root is the parent then we are done ...
4802 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
4804 try_return( ntStatus);
4816 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
4817 IN AFSNameArrayHdr *RelatedNameArray,
4818 IN AFSDirectoryCB *DirectoryCB)
4821 NTSTATUS ntStatus = STATUS_SUCCESS;
4822 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
4823 UNICODE_STRING uniComponentName, uniRemainingPath;
4824 AFSObjectInfoCB *pObjectInfo = NULL;
4825 ULONG ulTotalCount = 0;
4827 USHORT usLength = 0;
4833 // Init some info in the header
4836 pCurrentElement = &NameArray->ElementArray[ 0];
4838 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
4840 NameArray->Count = 0;
4842 NameArray->LinkCount = RelatedNameArray->LinkCount;
4845 // Populate the name array with the data from the related array
4851 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
4853 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
4855 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
4857 InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4859 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4860 AFS_TRACE_LEVEL_VERBOSE,
4861 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
4862 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4863 pCurrentElement->DirectoryCB,
4864 pCurrentElement->DirectoryCB->OpenReferenceCount);
4866 InterlockedIncrement( &NameArray->Count);
4868 if( pCurrentElement->DirectoryCB == DirectoryCB ||
4869 NameArray->Count == RelatedNameArray->Count)
4881 pCurrentRelatedElement++;
4884 if( NameArray->Count > 0)
4886 NameArray->CurrentEntry = pCurrentElement;
4894 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
4897 NTSTATUS ntStatus = STATUS_SUCCESS;
4898 AFSNameArrayCB *pCurrentElement = NULL;
4903 pCurrentElement = &NameArray->ElementArray[ 0];
4908 if( pCurrentElement->DirectoryCB == NULL)
4914 InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4916 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4917 AFS_TRACE_LEVEL_VERBOSE,
4918 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
4919 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4920 pCurrentElement->DirectoryCB,
4921 pCurrentElement->DirectoryCB->OpenReferenceCount);
4926 AFSExFreePool( NameArray);
4933 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
4934 IN AFSDirectoryCB *DirEntry)
4937 NTSTATUS ntStatus = STATUS_SUCCESS;
4938 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4943 if( NameArray->Count == NameArray->MaxElementCount)
4946 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4949 if( NameArray->CurrentEntry != NULL &&
4950 NameArray->CurrentEntry->DirectoryCB == DirEntry)
4953 try_return( ntStatus);
4956 if( NameArray->Count > 0)
4959 NameArray->CurrentEntry++;
4963 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
4966 InterlockedIncrement( &NameArray->Count);
4968 InterlockedIncrement( &DirEntry->OpenReferenceCount);
4970 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4971 AFS_TRACE_LEVEL_VERBOSE,
4972 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
4973 &DirEntry->NameInformation.FileName,
4975 DirEntry->OpenReferenceCount);
4977 NameArray->CurrentEntry->DirectoryCB = DirEntry;
4979 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
4981 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
4992 AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
4993 IN AFSDirectoryCB *DirectoryCB)
4996 ASSERT( NameArray->CurrentEntry != NULL);
4998 InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5000 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5001 AFS_TRACE_LEVEL_VERBOSE,
5002 "AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
5003 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5004 NameArray->CurrentEntry->DirectoryCB,
5005 NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5007 InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5009 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5010 AFS_TRACE_LEVEL_VERBOSE,
5011 "AFSReplaceCurrentElement Increment count on %wZ DE %p Cnt %d\n",
5012 &DirectoryCB->NameInformation.FileName,
5014 DirectoryCB->OpenReferenceCount);
5016 NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
5018 NameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
5020 NameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
5022 if( DirectoryCB->ObjectInformation->ParentObjectInformation == NULL)
5025 SetFlag( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5032 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5035 AFSDirectoryCB *pCurrentDirEntry = NULL;
5040 if( NameArray->Count == 0)
5042 try_return( pCurrentDirEntry);
5045 InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5047 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5048 AFS_TRACE_LEVEL_VERBOSE,
5049 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5050 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5051 NameArray->CurrentEntry->DirectoryCB,
5052 NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5054 NameArray->CurrentEntry->DirectoryCB = NULL;
5056 if( InterlockedDecrement( &NameArray->Count) == 0)
5058 NameArray->CurrentEntry = NULL;
5062 NameArray->CurrentEntry--;
5063 pCurrentDirEntry = NameArray->CurrentEntry->DirectoryCB;
5071 return pCurrentDirEntry;
5075 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5078 AFSDirectoryCB *pDirEntry = NULL;
5079 AFSNameArrayCB *pElement = NULL;
5084 if( NameArray->Count == 0 ||
5085 NameArray->Count == 1)
5088 try_return( pDirEntry = NULL);
5091 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5093 pDirEntry = pElement->DirectoryCB;
5104 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5105 IN AFSDirectoryCB *DirEntry)
5108 AFSNameArrayCB *pCurrentElement = NULL;
5109 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5114 pCurrentElement = &NameArray->ElementArray[ 0];
5119 if( pCurrentElement->DirectoryCB == NULL)
5125 InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5127 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5128 AFS_TRACE_LEVEL_VERBOSE,
5129 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5130 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5131 pCurrentElement->DirectoryCB,
5132 pCurrentElement->DirectoryCB->OpenReferenceCount);
5137 RtlZeroMemory( NameArray,
5138 sizeof( AFSNameArrayHdr) +
5139 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5141 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5143 if( DirEntry != NULL)
5146 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5148 InterlockedIncrement( &NameArray->Count);
5150 InterlockedIncrement( &DirEntry->OpenReferenceCount);
5152 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5153 AFS_TRACE_LEVEL_VERBOSE,
5154 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5155 &DirEntry->NameInformation.FileName,
5157 DirEntry->OpenReferenceCount);
5159 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5161 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5163 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5171 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5174 AFSNameArrayCB *pCurrentElement = NULL;
5176 pCurrentElement = &NameArray->ElementArray[ 0];
5178 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5180 while( pCurrentElement->DirectoryCB != NULL)
5183 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5184 pCurrentElement->FileId.Cell,
5185 pCurrentElement->FileId.Volume,
5186 pCurrentElement->FileId.Vnode,
5187 pCurrentElement->FileId.Unique,
5188 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5193 AFSPrint("AFSDumpNameArray End\n\n");
5199 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5203 // Depending on the type of node, set the event
5206 switch( Fcb->Header.NodeTypeCode)
5209 case AFS_DIRECTORY_FCB:
5212 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5216 InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5225 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5229 InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5239 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5243 // Depending on the type of node, set the event
5246 switch( Fcb->Header.NodeTypeCode)
5249 case AFS_DIRECTORY_FCB:
5252 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5254 if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
5257 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5267 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5269 if( InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount) == 0)
5272 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5283 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5286 BOOLEAN bIsInProcess = FALSE;
5291 if( ObjectInfo->Fcb == NULL)
5294 try_return( bIsInProcess);
5298 // Depending on the type of node, set the event
5301 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5304 case AFS_DIRECTORY_FCB:
5307 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5310 bIsInProcess = TRUE;
5320 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5323 bIsInProcess = TRUE;
5335 return bIsInProcess;
5339 AFSVerifyVolume( IN ULONGLONG ProcessId,
5340 IN AFSVolumeCB *VolumeCB)
5343 NTSTATUS ntStatus = STATUS_SUCCESS;
5350 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5353 NTSTATUS ntStatus = STATUS_SUCCESS;
5354 AFSObjectInfoCB *pObjectInfoCB = NULL;
5355 AFSDirectoryCB *pDirNode = NULL;
5356 ULONG ulEntryLength = 0;
5357 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5362 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5365 if( pObjectInfoCB == NULL)
5368 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5371 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5372 AFS_TRACE_LEVEL_VERBOSE,
5373 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5376 pObjectInfoCB->ObjectReferenceCount = 1;
5378 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5380 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5382 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5384 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5388 if( pDirNode == NULL)
5391 AFSDeleteObjectInfo( pObjectInfoCB);
5393 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5396 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5397 sizeof( AFSNonPagedDirectoryCB),
5398 AFS_DIR_ENTRY_NP_TAG);
5400 if( pNonPagedDirEntry == NULL)
5403 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5406 RtlZeroMemory( pDirNode,
5409 RtlZeroMemory( pNonPagedDirEntry,
5410 sizeof( AFSNonPagedDirectoryCB));
5412 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5414 pDirNode->NonPaged = pNonPagedDirEntry;
5416 pDirNode->ObjectInformation = pObjectInfoCB;
5418 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5424 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5426 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5428 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5430 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5432 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5433 AFSPIOCtlName.Buffer,
5434 pDirNode->NameInformation.FileName.Length);
5436 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5439 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB = pDirNode;
5443 if ( !NT_SUCCESS( ntStatus))
5446 if ( pDirNode != NULL)
5449 AFSExFreePool( pDirNode);
5452 if ( pObjectInfoCB != NULL)
5455 AFSDeleteObjectInfo( pObjectInfoCB);
5464 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5465 IN AFSDirectoryCB *DirectoryCB,
5466 IN UNICODE_STRING *ParentPathName,
5467 IN AFSNameArrayHdr *RelatedNameArray,
5468 OUT AFSFileInfoCB *FileInfo)
5471 NTSTATUS ntStatus = STATUS_SUCCESS;
5472 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
5473 UNICODE_STRING uniFullPathName;
5474 AFSNameArrayHdr *pNameArray = NULL;
5475 AFSVolumeCB *pVolumeCB = NULL;
5476 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5477 WCHAR *pwchBuffer = NULL;
5478 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5479 ULONG ulNameDifference = 0;
5480 GUID *pAuthGroup = NULL;
5486 // Retrieve a target name for the entry
5489 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5492 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5495 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5497 if( ParentDirectoryCB->ObjectInformation->Fcb != NULL)
5499 pAuthGroup = &ParentDirectoryCB->ObjectInformation->Fcb->AuthGroup;
5501 else if( DirectoryCB->ObjectInformation->Fcb != NULL)
5503 pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
5506 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5511 if( !NT_SUCCESS( ntStatus) ||
5512 pDirEntry->TargetNameLength == 0)
5515 if( pDirEntry != NULL)
5518 ntStatus = STATUS_ACCESS_DENIED;
5521 try_return( ntStatus);
5524 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5527 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5531 // Update the target name
5534 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5535 &DirectoryCB->Flags,
5536 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5537 (USHORT)pDirEntry->TargetNameLength);
5539 if( !NT_SUCCESS( ntStatus))
5542 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5544 try_return( ntStatus);
5548 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5552 // Need to pass the full path in for parsing.
5555 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5558 uniFullPathName.Length = 0;
5559 uniFullPathName.MaximumLength = ParentPathName->Length +
5561 DirectoryCB->NameInformation.TargetName.Length;
5563 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5564 uniFullPathName.MaximumLength,
5565 AFS_NAME_BUFFER_SIX_TAG);
5567 if( uniFullPathName.Buffer == NULL)
5570 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5572 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5575 pwchBuffer = uniFullPathName.Buffer;
5577 RtlZeroMemory( uniFullPathName.Buffer,
5578 uniFullPathName.MaximumLength);
5580 RtlCopyMemory( uniFullPathName.Buffer,
5581 ParentPathName->Buffer,
5582 ParentPathName->Length);
5584 uniFullPathName.Length = ParentPathName->Length;
5586 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5587 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5590 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5592 uniFullPathName.Length += sizeof( WCHAR);
5595 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5596 DirectoryCB->NameInformation.TargetName.Buffer,
5597 DirectoryCB->NameInformation.TargetName.Length);
5599 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5601 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5602 uniParsedName.MaximumLength = uniParsedName.Length;
5604 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5606 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5609 // We populate up to the current parent
5612 if( RelatedNameArray != NULL)
5615 pNameArray = AFSInitNameArray( NULL,
5616 RelatedNameArray->MaxElementCount);
5618 if( pNameArray == NULL)
5621 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5624 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5631 pNameArray = AFSInitNameArray( NULL,
5634 if( pNameArray == NULL)
5637 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5640 ntStatus = AFSPopulateNameArray( pNameArray,
5645 if( !NT_SUCCESS( ntStatus))
5648 try_return( ntStatus);
5651 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5653 AFSAcquireShared( pVolumeCB->VolumeLock,
5656 pParentDirEntry = ParentDirectoryCB;
5661 uniFullPathName.Length = 0;
5662 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5664 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5665 uniFullPathName.MaximumLength,
5666 AFS_NAME_BUFFER_SEVEN_TAG);
5668 if( uniFullPathName.Buffer == NULL)
5671 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5673 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5676 pwchBuffer = uniFullPathName.Buffer;
5678 RtlZeroMemory( uniFullPathName.Buffer,
5679 uniFullPathName.MaximumLength);
5681 RtlCopyMemory( uniFullPathName.Buffer,
5682 DirectoryCB->NameInformation.TargetName.Buffer,
5683 DirectoryCB->NameInformation.TargetName.Length);
5685 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5688 // This name should begin with the \afs server so parse it off and check it
5691 FsRtlDissectName( uniFullPathName,
5695 if( RtlCompareUnicodeString( &uniComponentName,
5700 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5702 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5703 AFS_TRACE_LEVEL_ERROR,
5704 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5707 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5710 uniFullPathName = uniRemainingPath;
5712 uniParsedName = uniFullPathName;
5714 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5716 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5722 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5725 if( pNameArray == NULL)
5728 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5731 pVolumeCB = AFSGlobalRoot;
5733 AFSAcquireShared( pVolumeCB->VolumeLock,
5736 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5740 // Increment the ref count on the volume and dir entry for correct processing below
5743 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
5745 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5746 AFS_TRACE_LEVEL_VERBOSE,
5747 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
5749 pVolumeCB->VolumeReferenceCount);
5751 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
5753 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5754 AFS_TRACE_LEVEL_VERBOSE,
5755 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5756 &pParentDirEntry->NameInformation.FileName,
5759 pParentDirEntry->OpenReferenceCount);
5761 ntStatus = AFSLocateNameEntry( NULL,
5766 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5772 if( !NT_SUCCESS( ntStatus))
5776 // The volume lock was released on failure above
5777 // Except for STATUS_OBJECT_NAME_NOT_FOUND
5780 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
5783 if( pVolumeCB != NULL)
5786 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5788 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5789 AFS_TRACE_LEVEL_VERBOSE,
5790 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
5792 pVolumeCB->VolumeReferenceCount);
5794 AFSReleaseResource( pVolumeCB->VolumeLock);
5797 if( pDirectoryEntry != NULL)
5800 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5802 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5803 AFS_TRACE_LEVEL_VERBOSE,
5804 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5805 &pDirectoryEntry->NameInformation.FileName,
5808 pDirectoryEntry->OpenReferenceCount);
5813 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
5815 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5816 AFS_TRACE_LEVEL_VERBOSE,
5817 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5818 &pParentDirEntry->NameInformation.FileName,
5821 pParentDirEntry->OpenReferenceCount);
5827 try_return( ntStatus);
5831 // Store off the information
5834 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5837 // Check for the mount point being returned
5840 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
5843 FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
5845 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
5846 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
5849 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
5852 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
5854 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
5856 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
5858 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
5860 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
5862 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
5865 // Remove the reference made above
5868 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5870 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5871 AFS_TRACE_LEVEL_VERBOSE,
5872 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
5873 &pDirectoryEntry->NameInformation.FileName,
5876 pDirectoryEntry->OpenReferenceCount);
5880 if( pDirEntry != NULL)
5883 AFSExFreePool( pDirEntry);
5886 if( pVolumeCB != NULL)
5889 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5891 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5892 AFS_TRACE_LEVEL_VERBOSE,
5893 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
5895 pVolumeCB->VolumeReferenceCount);
5897 AFSReleaseResource( pVolumeCB->VolumeLock);
5900 if( pNameArray != NULL)
5903 AFSFreeNameArray( pNameArray);
5906 if( pwchBuffer != NULL)
5910 // Always free the buffer that we allocated as AFSLocateNameEntry
5911 // will not free it. If uniFullPathName.Buffer was allocated by
5912 // AFSLocateNameEntry, then we must free that as well.
5913 // Check that the uniFullPathName.Buffer in the string is not the same
5914 // offset by the length of the server name
5917 if( uniFullPathName.Length > 0 &&
5918 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
5921 AFSExFreePool( uniFullPathName.Buffer);
5924 AFSExFreePool( pwchBuffer);
5932 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
5933 IN ULONGLONG HashIndex)
5936 NTSTATUS ntStatus = STATUS_SUCCESS;
5937 AFSObjectInfoCB *pObjectInfo = NULL;
5942 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
5943 sizeof( AFSObjectInfoCB),
5944 AFS_OBJECT_INFO_TAG);
5946 if( pObjectInfo == NULL)
5949 try_return( pObjectInfo);
5952 RtlZeroMemory( pObjectInfo,
5953 sizeof( AFSObjectInfoCB));
5955 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5956 sizeof( AFSNonPagedObjectInfoCB),
5957 AFS_NP_OBJECT_INFO_TAG);
5959 if( pObjectInfo->NonPagedInfo == NULL)
5962 AFSExFreePool( pObjectInfo);
5964 try_return( pObjectInfo = NULL);
5967 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
5969 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
5971 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
5973 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
5975 if( ParentObjectInfo != NULL)
5977 InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
5981 // Initialize the access time
5984 KeQueryTickCount( &pObjectInfo->LastAccessCount);
5990 // Insert the entry into the object tree and list
5993 pObjectInfo->TreeEntry.HashIndex = HashIndex;
5995 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
5998 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6003 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6004 &pObjectInfo->TreeEntry);
6006 ASSERT( NT_SUCCESS( ntStatus));
6010 // And the object list in the volume
6013 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6016 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6021 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6023 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6026 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6029 // Indicate the object is in the hash tree and linked list in the volume
6032 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6044 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6047 BOOLEAN bAcquiredTreeLock = FALSE;
6049 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6052 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6054 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6057 bAcquiredTreeLock = TRUE;
6061 // Remove it from the tree and list if it was inserted
6064 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6067 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6068 &ObjectInfo->TreeEntry);
6071 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6074 if( ObjectInfo->ListEntry.fLink == NULL)
6077 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6079 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6082 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6088 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6091 if( ObjectInfo->ListEntry.bLink == NULL)
6094 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6096 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6099 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6105 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6109 if( ObjectInfo->ParentObjectInformation != NULL)
6111 InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
6114 if( bAcquiredTreeLock)
6117 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6121 // Release the fid in the service
6124 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6127 AFSReleaseFid( &ObjectInfo->FileId);
6130 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6132 AFSExFreePool( ObjectInfo->NonPagedInfo);
6134 AFSExFreePool( ObjectInfo);
6140 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6141 OUT AFSDirectoryCB **TargetDirEntry)
6144 NTSTATUS ntStatus = STATUS_SUCCESS;
6145 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6146 UNICODE_STRING uniFullPathName;
6147 AFSNameArrayHdr *pNameArray = NULL;
6148 AFSVolumeCB *pVolumeCB = NULL;
6149 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6150 WCHAR *pwchBuffer = NULL;
6151 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6152 ULONG ulNameDifference = 0;
6153 GUID *pAuthGroup = NULL;
6159 // Retrieve a target name for the entry
6162 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6165 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6168 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6170 if( DirectoryCB->ObjectInformation->Fcb != NULL)
6172 pAuthGroup = &DirectoryCB->ObjectInformation->Fcb->AuthGroup;
6175 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6180 if( !NT_SUCCESS( ntStatus) ||
6181 pDirEntry->TargetNameLength == 0)
6184 if( pDirEntry != NULL)
6187 ntStatus = STATUS_ACCESS_DENIED;
6190 try_return( ntStatus);
6193 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6196 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6200 // Update the target name
6203 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6204 &DirectoryCB->Flags,
6205 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6206 (USHORT)pDirEntry->TargetNameLength);
6208 if( !NT_SUCCESS( ntStatus))
6211 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6213 try_return( ntStatus);
6217 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6221 // Need to pass the full path in for parsing.
6224 uniFullPathName.Length = 0;
6225 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6227 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6228 uniFullPathName.MaximumLength,
6229 AFS_NAME_BUFFER_EIGHT_TAG);
6231 if( uniFullPathName.Buffer == NULL)
6234 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6236 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6239 pwchBuffer = uniFullPathName.Buffer;
6241 RtlZeroMemory( uniFullPathName.Buffer,
6242 uniFullPathName.MaximumLength);
6244 RtlCopyMemory( uniFullPathName.Buffer,
6245 DirectoryCB->NameInformation.TargetName.Buffer,
6246 DirectoryCB->NameInformation.TargetName.Length);
6248 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6251 // This name should begin with the \afs server so parse it off and chech it
6254 FsRtlDissectName( uniFullPathName,
6258 if( RtlCompareUnicodeString( &uniComponentName,
6264 // Try evaluating the full path
6267 uniFullPathName.Buffer = pwchBuffer;
6269 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6271 uniFullPathName.MaximumLength = uniFullPathName.Length;
6276 uniFullPathName = uniRemainingPath;
6279 uniParsedName = uniFullPathName;
6281 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6283 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6289 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6292 if( pNameArray == NULL)
6295 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6298 pVolumeCB = AFSGlobalRoot;
6300 AFSAcquireShared( pVolumeCB->VolumeLock,
6303 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6305 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6307 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6308 AFS_TRACE_LEVEL_VERBOSE,
6309 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6311 pVolumeCB->VolumeReferenceCount);
6313 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6315 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6316 AFS_TRACE_LEVEL_VERBOSE,
6317 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6318 &pParentDirEntry->NameInformation.FileName,
6321 pParentDirEntry->OpenReferenceCount);
6323 ntStatus = AFSLocateNameEntry( NULL,
6334 if( !NT_SUCCESS( ntStatus))
6338 // The volume lock was released on failure above
6339 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6342 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6345 if( pVolumeCB != NULL)
6348 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6350 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6351 AFS_TRACE_LEVEL_VERBOSE,
6352 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
6354 pVolumeCB->VolumeReferenceCount);
6356 AFSReleaseResource( pVolumeCB->VolumeLock);
6359 if( pDirectoryEntry != NULL)
6362 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6364 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6365 AFS_TRACE_LEVEL_VERBOSE,
6366 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6367 &pDirectoryEntry->NameInformation.FileName,
6370 pDirectoryEntry->OpenReferenceCount);
6375 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6377 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6378 AFS_TRACE_LEVEL_VERBOSE,
6379 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6380 &pParentDirEntry->NameInformation.FileName,
6383 pParentDirEntry->OpenReferenceCount);
6389 try_return( ntStatus);
6393 // Pass back the target dir entry for this request
6396 *TargetDirEntry = pDirectoryEntry;
6400 if( pDirEntry != NULL)
6403 AFSExFreePool( pDirEntry);
6406 if( pVolumeCB != NULL)
6409 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6411 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6412 AFS_TRACE_LEVEL_VERBOSE,
6413 "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
6415 pVolumeCB->VolumeReferenceCount);
6417 AFSReleaseResource( pVolumeCB->VolumeLock);
6420 if( pNameArray != NULL)
6423 AFSFreeNameArray( pNameArray);
6426 if( pwchBuffer != NULL)
6430 // Always free the buffer that we allocated as AFSLocateNameEntry
6431 // will not free it. If uniFullPathName.Buffer was allocated by
6432 // AFSLocateNameEntry, then we must free that as well.
6433 // Check that the uniFullPathName.Buffer in the string is not the same
6434 // offset by the length of the server name
6437 if( uniFullPathName.Length > 0 &&
6438 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6441 AFSExFreePool( uniFullPathName.Buffer);
6444 AFSExFreePool( pwchBuffer);
6452 AFSCleanupFcb( IN AFSFcb *Fcb,
6453 IN BOOLEAN ForceFlush)
6456 NTSTATUS ntStatus = STATUS_SUCCESS;
6457 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6458 LARGE_INTEGER liTime;
6459 IO_STATUS_BLOCK stIoStatus;
6464 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6466 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6468 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6471 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6472 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6475 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6478 if( Fcb->OpenReferenceCount > 0)
6484 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6489 if( !NT_SUCCESS( stIoStatus.Status))
6492 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6493 AFS_TRACE_LEVEL_ERROR,
6494 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6495 Fcb->ObjectInformation->FileId.Cell,
6496 Fcb->ObjectInformation->FileId.Volume,
6497 Fcb->ObjectInformation->FileId.Vnode,
6498 Fcb->ObjectInformation->FileId.Unique,
6500 stIoStatus.Information);
6502 ntStatus = stIoStatus.Status;
6505 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6510 __except( EXCEPTION_EXECUTE_HANDLER)
6512 ntStatus = GetExceptionCode();
6516 AFSReleaseResource( &Fcb->NPFcb->Resource);
6519 // Wait for any currently running flush or release requests to complete
6522 AFSWaitOnQueuedFlushes( Fcb);
6525 // Now perform another flush on the file
6528 if( !NT_SUCCESS( AFSFlushExtents( Fcb)))
6531 AFSReleaseExtentsWithFlush( Fcb);
6535 if( Fcb->OpenReferenceCount == 0 ||
6536 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6537 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6540 AFSTearDownFcbExtents( Fcb);
6543 try_return( ntStatus);
6546 KeQueryTickCount( &liTime);
6549 // First up are there dirty extents in the cache to flush?
6553 ( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6554 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
6555 ( Fcb->Specific.File.ExtentsDirtyCount ||
6556 Fcb->Specific.File.ExtentCount) &&
6557 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6558 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6561 if( !NT_SUCCESS( AFSFlushExtents( Fcb)) &&
6562 Fcb->OpenReferenceCount == 0)
6565 AFSReleaseExtentsWithFlush( Fcb);
6568 else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6569 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6573 // The file has been marked as invalid. Dump it
6576 AFSTearDownFcbExtents( Fcb);
6580 // If there are extents and they haven't been used recently *and*
6581 // are not being used
6585 ( 0 != Fcb->Specific.File.ExtentCount &&
6586 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6587 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6588 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
6589 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6596 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6601 if( !NT_SUCCESS( stIoStatus.Status))
6604 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6605 AFS_TRACE_LEVEL_ERROR,
6606 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6607 Fcb->ObjectInformation->FileId.Cell,
6608 Fcb->ObjectInformation->FileId.Volume,
6609 Fcb->ObjectInformation->FileId.Vnode,
6610 Fcb->ObjectInformation->FileId.Unique,
6612 stIoStatus.Information);
6614 ntStatus = stIoStatus.Status;
6620 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6626 __except( EXCEPTION_EXECUTE_HANDLER)
6628 ntStatus = GetExceptionCode();
6631 AFSReleaseResource( &Fcb->NPFcb->Resource);
6633 if( Fcb->OpenReferenceCount == 0)
6637 // Tear em down we'll not be needing them again
6640 AFSTearDownFcbExtents( Fcb);
6653 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
6654 IN UNICODE_STRING *NewFileName)
6657 NTSTATUS ntStatus = STATUS_SUCCESS;
6658 WCHAR *pTmpBuffer = NULL;
6663 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
6666 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
6669 AFSExFreePool( DirectoryCB->NameInformation.FileName.Buffer);
6671 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6673 DirectoryCB->NameInformation.FileName.Buffer = NULL;
6677 // OK, we need to allocate a new name buffer
6680 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6681 NewFileName->Length,
6682 AFS_NAME_BUFFER_NINE_TAG);
6684 if( pTmpBuffer == NULL)
6687 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6690 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
6692 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
6694 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6697 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
6699 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
6700 NewFileName->Buffer,
6701 NewFileName->Length);
6712 AFSReadCacheFile( IN void *ReadBuffer,
6713 IN LARGE_INTEGER *ReadOffset,
6714 IN ULONG RequestedDataLength,
6715 IN OUT PULONG BytesRead)
6718 NTSTATUS ntStatus = STATUS_SUCCESS;
6721 PIO_STACK_LOCATION pIoStackLocation = NULL;
6722 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6723 DEVICE_OBJECT *pTargetDeviceObject = NULL;
6724 FILE_OBJECT *pCacheFileObject = NULL;
6729 pCacheFileObject = AFSReferenceCacheFileObject();
6731 if( pCacheFileObject == NULL)
6733 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
6736 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
6739 // Initialize the event
6742 KeInitializeEvent( &kEvent,
6743 SynchronizationEvent,
6747 // Allocate an irp for this request. This could also come from a
6748 // private pool, for instance.
6751 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
6757 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6761 // Build the IRP's main body
6764 pIrp->UserBuffer = ReadBuffer;
6766 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
6767 pIrp->RequestorMode = KernelMode;
6768 pIrp->Flags |= IRP_READ_OPERATION;
6771 // Set up the I/O stack location.
6774 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
6775 pIoStackLocation->MajorFunction = IRP_MJ_READ;
6776 pIoStackLocation->DeviceObject = pTargetDeviceObject;
6777 pIoStackLocation->FileObject = pCacheFileObject;
6778 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
6780 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
6783 // Set the completion routine.
6786 IoSetCompletionRoutine( pIrp,
6794 // Send it to the FSD
6797 ntStatus = IoCallDriver( pTargetDeviceObject,
6800 if( NT_SUCCESS( ntStatus))
6807 ntStatus = KeWaitForSingleObject( &kEvent,
6813 if( NT_SUCCESS( ntStatus))
6816 ntStatus = pIrp->IoStatus.Status;
6818 *BytesRead = (ULONG)pIrp->IoStatus.Information;
6824 if( pCacheFileObject != NULL)
6826 AFSReleaseCacheFileObject( pCacheFileObject);
6832 if( pIrp->MdlAddress != NULL)
6835 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
6838 MmUnlockPages( pIrp->MdlAddress);
6841 IoFreeMdl( pIrp->MdlAddress);
6844 pIrp->MdlAddress = NULL;
6858 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
6863 KEVENT *pEvent = (KEVENT *)Context;
6869 return STATUS_MORE_PROCESSING_REQUIRED;
6873 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
6876 BOOLEAN bIsEmpty = FALSE;
6877 AFSDirectoryCB *pDirEntry = NULL;
6882 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
6887 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
6890 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
6892 while( pDirEntry != NULL)
6895 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
6896 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
6904 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
6909 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
6916 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
6917 IN AFSDirectoryCB *DirEntry)
6920 NTSTATUS ntStatus = STATUS_SUCCESS;
6925 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
6928 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6929 AFS_TRACE_LEVEL_VERBOSE,
6930 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
6932 &DirEntry->NameInformation.FileName);
6934 try_return( ntStatus);
6937 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
6940 // Remove the entry from the parent tree
6943 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6944 AFS_TRACE_LEVEL_VERBOSE,
6945 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
6947 &DirEntry->NameInformation.FileName);
6949 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
6952 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6953 AFS_TRACE_LEVEL_VERBOSE,
6954 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
6956 &DirEntry->NameInformation.FileName);
6958 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
6961 if( ParentObjectInfo->Specific.Directory.ShortNameTree &&
6962 DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
6966 // From the short name tree
6969 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6970 AFS_TRACE_LEVEL_VERBOSE,
6971 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
6973 &DirEntry->NameInformation.FileName);
6975 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
6979 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
6980 AFS_TRACE_LEVEL_VERBOSE,
6981 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
6983 &DirEntry->NameInformation.FileName);
6985 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
6996 AFSGetAuthenticationId()
6999 LARGE_INTEGER liAuthId = {0,0};
7000 NTSTATUS ntStatus = STATUS_SUCCESS;
7001 PACCESS_TOKEN hToken = NULL;
7002 PTOKEN_STATISTICS pTokenInfo = NULL;
7003 BOOLEAN bCopyOnOpen = FALSE;
7004 BOOLEAN bEffectiveOnly = FALSE;
7005 BOOLEAN bPrimaryToken = FALSE;
7006 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7011 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7014 &stImpersonationLevel);
7019 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7024 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7025 AFS_TRACE_LEVEL_ERROR,
7026 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7028 try_return( ntStatus);
7031 bPrimaryToken = TRUE;
7034 ntStatus = SeQueryInformationToken( hToken,
7036 (PVOID *)&pTokenInfo);
7038 if( !NT_SUCCESS( ntStatus))
7041 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7042 AFS_TRACE_LEVEL_ERROR,
7043 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7045 try_return( ntStatus);
7048 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7049 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7051 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7052 AFS_TRACE_LEVEL_VERBOSE,
7053 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7064 PsDereferenceImpersonationToken( hToken);
7069 PsDereferencePrimaryToken( hToken);
7073 if( pTokenInfo != NULL)
7076 AFSExFreePool( pTokenInfo);
7084 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7088 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7090 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7093 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7095 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7098 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7100 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7103 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7105 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7108 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7110 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7117 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7120 BOOLEAN bIsValid = TRUE;
7122 AFSDirectoryCB *pCurrentDirEntry = NULL;
7124 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7126 while( pCurrentDirEntry != NULL)
7129 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7134 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7137 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7140 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7142 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7144 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7153 AFSReferenceCacheFileObject()
7156 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7157 FILE_OBJECT *pCacheFileObject = NULL;
7159 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7162 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7164 if( pCacheFileObject != NULL)
7166 ObReferenceObject( pCacheFileObject);
7169 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7171 return pCacheFileObject;
7175 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7178 ASSERT( CacheFileObject != NULL);
7180 ObDereferenceObject( CacheFileObject);
7186 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7189 NTSTATUS ntStatus = STATUS_SUCCESS;
7190 AFSDeviceExt *pControlDevExt = NULL;
7191 ULONG ulTimeIncrement = 0;
7196 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7198 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7200 AFSServerName = LibraryInit->AFSServerName;
7202 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7205 // Callbacks in the framework
7208 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7210 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7212 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7214 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7216 AFSExFreePool = LibraryInit->AFSExFreePool;
7218 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7220 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7222 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7224 if( LibraryInit->AFSCacheBaseAddress != NULL)
7227 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7229 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7231 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7235 // Initialize some flush parameters
7238 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7240 ulTimeIncrement = KeQueryTimeIncrement();
7242 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7243 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_ONE_SECOND;
7244 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart *= AFS_SERVER_PURGE_DELAY;
7245 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7246 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)(AFS_ONE_SECOND * AFS_SERVER_FLUSH_DELAY) / (ULONGLONG)ulTimeIncrement);
7247 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7250 // Initialize the global root entry
7253 ntStatus = AFSInitVolume( NULL,
7254 &LibraryInit->GlobalRootFid,
7257 if( !NT_SUCCESS( ntStatus))
7260 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7261 AFS_TRACE_LEVEL_ERROR,
7262 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7265 try_return( ntStatus);
7268 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7271 if( !NT_SUCCESS( ntStatus))
7274 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7275 AFS_TRACE_LEVEL_ERROR,
7276 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7279 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7281 try_return( ntStatus);
7285 // Update the node type code to AFS_ROOT_ALL
7288 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7290 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7293 // Drop the locks acquired above
7296 AFSInitVolumeWorker( AFSGlobalRoot);
7298 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7300 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7314 NTSTATUS ntStatus = STATUS_SUCCESS;
7315 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7320 if( AFSGlobalDotDirEntry != NULL)
7323 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
7325 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7327 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7329 ExFreePool( AFSGlobalDotDirEntry);
7331 AFSGlobalDotDirEntry = NULL;
7334 if( AFSGlobalDotDotDirEntry != NULL)
7337 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
7339 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7341 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7343 ExFreePool( AFSGlobalDotDotDirEntry);
7345 AFSGlobalDotDotDirEntry = NULL;
7348 if( AFSSpecialShareNames != NULL)
7351 pDirNode = AFSSpecialShareNames;
7353 while( pDirNode != NULL)
7356 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7358 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
7360 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7362 ExFreePool( pDirNode->NonPaged);
7364 ExFreePool( pDirNode);
7366 pDirNode = pLastDirNode;
7369 AFSSpecialShareNames = NULL;
7377 AFSDefaultLogMsg( IN ULONG Subsystem,
7383 NTSTATUS ntStatus = STATUS_SUCCESS;
7385 char chDebugBuffer[ 256];
7390 va_start( va_args, Format);
7392 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7397 if( NT_SUCCESS( ntStatus))
7399 DbgPrint( chDebugBuffer);
7409 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7410 IN ULONG InputBufferLength,
7411 IN AFSStatusInfoCB *StatusInfo,
7412 OUT ULONG *ReturnLength)
7415 NTSTATUS ntStatus = STATUS_SUCCESS;
7416 AFSFcb *pFcb = NULL;
7417 AFSVolumeCB *pVolumeCB = NULL;
7418 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7419 AFSObjectInfoCB *pObjectInfo = NULL;
7420 ULONGLONG ullIndex = 0;
7421 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7422 AFSNameArrayHdr *pNameArray = NULL;
7423 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7429 // If we are given a FID then look up the entry by that, otherwise
7433 if( GetStatusInfo->FileID.Cell != 0 &&
7434 GetStatusInfo->FileID.Volume != 0 &&
7435 GetStatusInfo->FileID.Vnode != 0 &&
7436 GetStatusInfo->FileID.Unique != 0)
7439 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7442 // Locate the volume node
7445 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7447 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7449 (AFSBTreeEntry **)&pVolumeCB);
7451 if( pVolumeCB != NULL)
7454 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7456 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7457 AFS_TRACE_LEVEL_VERBOSE,
7458 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7460 pVolumeCB->VolumeReferenceCount);
7463 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7465 if( !NT_SUCCESS( ntStatus) ||
7468 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7471 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
7474 pObjectInfo = &pVolumeCB->ObjectInformation;
7476 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7478 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7483 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
7486 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7488 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7489 AFS_TRACE_LEVEL_VERBOSE,
7490 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7492 pVolumeCB->VolumeReferenceCount);
7494 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
7496 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
7498 (AFSBTreeEntry **)&pObjectInfo);
7500 if( pObjectInfo != NULL)
7504 // Reference the node so it won't be torn down
7507 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7509 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7510 AFS_TRACE_LEVEL_VERBOSE,
7511 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
7513 pObjectInfo->ObjectReferenceCount);
7516 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
7518 if( !NT_SUCCESS( ntStatus) ||
7519 pObjectInfo == NULL)
7521 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7528 if( GetStatusInfo->FileNameLength == 0 ||
7529 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
7531 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7534 uniFullPathName.Length = GetStatusInfo->FileNameLength;
7535 uniFullPathName.MaximumLength = uniFullPathName.Length;
7537 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
7540 // This name should begin with the \afs server so parse it off and check it
7543 FsRtlDissectName( uniFullPathName,
7547 if( RtlCompareUnicodeString( &uniComponentName,
7551 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7552 AFS_TRACE_LEVEL_ERROR,
7553 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
7556 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
7559 uniFullPathName = uniRemainingPath;
7561 uniParsedName = uniFullPathName;
7567 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7570 if( pNameArray == NULL)
7572 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7575 pVolumeCB = AFSGlobalRoot;
7577 AFSAcquireShared( pVolumeCB->VolumeLock,
7580 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7583 // Increment the ref count on the volume and dir entry for correct processing below
7586 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7588 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7589 AFS_TRACE_LEVEL_VERBOSE,
7590 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7592 pVolumeCB->VolumeReferenceCount);
7594 InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
7596 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7597 AFS_TRACE_LEVEL_VERBOSE,
7598 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7599 &pParentDirEntry->NameInformation.FileName,
7602 pParentDirEntry->OpenReferenceCount);
7604 ntStatus = AFSLocateNameEntry( NULL,
7609 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
7610 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
7616 if( !NT_SUCCESS( ntStatus))
7620 // The volume lock was released on failure above
7621 // Except for STATUS_OBJECT_NAME_NOT_FOUND
7624 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
7627 if( pVolumeCB != NULL)
7630 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7632 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7633 AFS_TRACE_LEVEL_VERBOSE,
7634 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7636 pVolumeCB->VolumeReferenceCount);
7638 AFSReleaseResource( pVolumeCB->VolumeLock);
7641 if( pDirectoryEntry != NULL)
7644 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7646 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7647 AFS_TRACE_LEVEL_VERBOSE,
7648 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7649 &pDirectoryEntry->NameInformation.FileName,
7652 pDirectoryEntry->OpenReferenceCount);
7657 InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
7659 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7660 AFS_TRACE_LEVEL_VERBOSE,
7661 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7662 &pParentDirEntry->NameInformation.FileName,
7665 pParentDirEntry->OpenReferenceCount);
7671 try_return( ntStatus);
7675 // Remove the reference made above
7678 InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7680 pObjectInfo = pDirectoryEntry->ObjectInformation;
7682 InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7684 if( pVolumeCB != NULL)
7687 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7689 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7690 AFS_TRACE_LEVEL_VERBOSE,
7691 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
7693 pVolumeCB->VolumeReferenceCount);
7695 AFSReleaseResource( pVolumeCB->VolumeLock);
7700 // At this point we have an object info block, return the information
7703 StatusInfo->FileId = pObjectInfo->FileId;
7705 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
7707 StatusInfo->Expiration = pObjectInfo->Expiration;
7709 StatusInfo->DataVersion = pObjectInfo->DataVersion;
7711 StatusInfo->FileType = pObjectInfo->FileType;
7713 StatusInfo->ObjectFlags = pObjectInfo->Flags;
7715 StatusInfo->CreationTime = pObjectInfo->CreationTime;
7717 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
7719 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
7721 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
7723 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
7725 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
7727 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
7729 StatusInfo->EaSize = pObjectInfo->EaSize;
7731 StatusInfo->Links = pObjectInfo->Links;
7734 // Return the information length
7737 *ReturnLength = sizeof( AFSStatusInfoCB);
7741 if( pObjectInfo != NULL)
7744 InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
7747 if( pNameArray != NULL)
7750 AFSFreeNameArray( pNameArray);
7758 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
7759 IN UNICODE_STRING *ComponentName)
7762 NTSTATUS ntStatus = STATUS_SUCCESS;
7763 AFSDirectoryCB *pDirEntry = NULL;
7770 // Search for the entry in the parent
7773 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7774 AFS_TRACE_LEVEL_VERBOSE_2,
7775 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
7778 ulCRC = AFSGenerateCRC( ComponentName,
7781 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7784 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7788 if( pDirEntry == NULL)
7792 // Missed so perform a case insensitive lookup
7795 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7796 AFS_TRACE_LEVEL_VERBOSE_2,
7797 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
7800 ulCRC = AFSGenerateCRC( ComponentName,
7803 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7807 if( pDirEntry == NULL)
7811 // OK, if this component is a valid short name then try
7812 // a lookup in the short name tree
7815 if( RtlIsNameLegalDOS8Dot3( ComponentName,
7820 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7821 AFS_TRACE_LEVEL_VERBOSE_2,
7822 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
7825 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
7832 if( pDirEntry != NULL)
7834 InterlockedIncrement( &pDirEntry->OpenReferenceCount);
7837 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7839 if( pDirEntry == NULL)
7842 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7843 AFS_TRACE_LEVEL_VERBOSE_2,
7844 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
7847 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
7851 // We have the symlink object but previously failed to process it so return access
7855 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7856 AFS_TRACE_LEVEL_VERBOSE_2,
7857 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ ACCESS_DENIED\n",
7860 ntStatus = STATUS_ACCESS_DENIED;
7862 InterlockedDecrement( &pDirEntry->OpenReferenceCount);
7873 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
7874 OUT UNICODE_STRING *ComponentName)
7877 NTSTATUS ntStatus = STATUS_SUCCESS;
7878 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
7880 uniFullPathName = *FullPathName;
7885 FsRtlDissectName( uniFullPathName,
7889 if( uniRemainingPath.Length == 0)
7894 uniFullPathName = uniRemainingPath;
7897 if( uniComponentName.Length > 0)
7899 *ComponentName = uniComponentName;
7906 AFSDumpTraceFiles_Default()
7912 AFSValidNameFormat( IN UNICODE_STRING *FileName)
7915 BOOLEAN bIsValidName = TRUE;
7921 while( usIndex < FileName->Length/sizeof( WCHAR))
7924 if( FileName->Buffer[ usIndex] == L':' ||
7925 FileName->Buffer[ usIndex] == L'*' ||
7926 FileName->Buffer[ usIndex] == L'?' ||
7927 FileName->Buffer[ usIndex] == L'"' ||
7928 FileName->Buffer[ usIndex] == L'<' ||
7929 FileName->Buffer[ usIndex] == L'>')
7931 bIsValidName = FALSE;
7939 return bIsValidName;
7943 AFSCreateDefaultSecurityDescriptor()
7946 NTSTATUS ntStatus = STATUS_SUCCESS;
7948 ULONG ulSACLSize = 0;
7949 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
7950 ULONG ulACESize = 0;
7951 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
7952 ULONG ulSDLength = 0;
7953 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
7958 if( AFSRtlSetSaclSecurityDescriptor == NULL)
7961 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
7966 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
7968 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
7970 AFS_GENERIC_MEMORY_29_TAG);
7975 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
7977 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7980 RtlZeroMemory( pACE,
7983 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
7984 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
7985 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
7986 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
7988 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
7990 SeExports->SeLowMandatorySid);
7992 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
7993 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
7995 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
7997 AFS_GENERIC_MEMORY_29_TAG);
8002 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8004 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8007 ntStatus = RtlCreateAcl( pSACL,
8011 if( !NT_SUCCESS( ntStatus))
8014 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8017 try_return( ntStatus);
8020 ntStatus = RtlAddAce( pSACL,
8024 pACE->Header.AceSize);
8026 if( !NT_SUCCESS( ntStatus))
8029 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8032 try_return( ntStatus);
8036 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8037 sizeof( SECURITY_DESCRIPTOR),
8038 AFS_GENERIC_MEMORY_27_TAG);
8040 if( pSecurityDescr == NULL)
8043 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8045 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8048 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8049 SECURITY_DESCRIPTOR_REVISION);
8051 if( !NT_SUCCESS( ntStatus))
8054 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8057 try_return( ntStatus);
8060 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8062 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8067 if( !NT_SUCCESS( ntStatus))
8070 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8073 try_return( ntStatus);
8077 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8080 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8082 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8085 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8087 AFS_GENERIC_MEMORY_27_TAG);
8089 if( pRelativeSecurityDescr == NULL)
8092 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8094 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8097 ulSDLength = PAGE_SIZE;
8099 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8100 pRelativeSecurityDescr,
8103 if( !NT_SUCCESS( ntStatus))
8106 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8109 try_return( ntStatus);
8112 AFSDefaultSD = pRelativeSecurityDescr;
8116 if( !NT_SUCCESS( ntStatus))
8119 if( pRelativeSecurityDescr != NULL)
8121 ExFreePool( pRelativeSecurityDescr);
8125 if( pSecurityDescr != NULL)
8127 ExFreePool( pSecurityDescr);