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;
652 // Initialize the global . entry
655 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
658 if( pObjectInfoCB == NULL)
661 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
662 AFS_TRACE_LEVEL_ERROR,
663 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo failure %08lX\n",
666 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
669 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
671 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
672 AFS_TRACE_LEVEL_VERBOSE,
673 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
677 ntStatus = STATUS_SUCCESS;
679 ulEntryLength = sizeof( AFSDirectoryCB) +
682 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
686 if( pDirNode == NULL)
689 AFSDeleteObjectInfo( pObjectInfoCB);
691 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
692 AFS_TRACE_LEVEL_ERROR,
693 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_TAG allocation failure\n");
695 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
698 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
699 sizeof( AFSNonPagedDirectoryCB),
700 AFS_DIR_ENTRY_NP_TAG);
702 if( pNonPagedDirEntry == NULL)
705 ExFreePool( pDirNode);
707 AFSDeleteObjectInfo( pObjectInfoCB);
709 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
710 AFS_TRACE_LEVEL_ERROR,
711 "AFSInitializeGlobalDirectory AFS_DIR_ENTRY_NP_TAG allocation failure\n");
713 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
716 RtlZeroMemory( pDirNode,
719 RtlZeroMemory( pNonPagedDirEntry,
720 sizeof( AFSNonPagedDirectoryCB));
722 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
724 pDirNode->NonPaged = pNonPagedDirEntry;
726 pDirNode->ObjectInformation = pObjectInfoCB;
732 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
734 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_INDEX;
737 // Setup the names in the entry
740 pDirNode->NameInformation.FileName.Length = sizeof( WCHAR);
742 pDirNode->NameInformation.FileName.MaximumLength = sizeof( WCHAR);
744 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
746 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
749 // Populate the rest of the data
752 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
754 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
756 AFSGlobalDotDirEntry = pDirNode;
762 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
765 if( pObjectInfoCB == NULL)
768 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
769 AFS_TRACE_LEVEL_ERROR,
770 "AFSInitializeGlobalDirectory AFSAllocateObjectInfo (2) failure %08lX\n",
773 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
776 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
778 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
779 AFS_TRACE_LEVEL_VERBOSE,
780 "AFSInitializeGlobalDirectoryEntries Increment count on object %08lX Cnt %d\n",
784 ntStatus = STATUS_SUCCESS;
786 ulEntryLength = sizeof( AFSDirectoryCB) +
787 ( 2 * sizeof( WCHAR));
789 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
793 if( pDirNode == NULL)
796 AFSDeleteObjectInfo( pObjectInfoCB);
798 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
801 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
802 sizeof( AFSNonPagedDirectoryCB),
803 AFS_DIR_ENTRY_NP_TAG);
805 if( pNonPagedDirEntry == NULL)
808 ExFreePool( pDirNode);
810 AFSDeleteObjectInfo( pObjectInfoCB);
812 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
815 RtlZeroMemory( pDirNode,
818 RtlZeroMemory( pNonPagedDirEntry,
819 sizeof( AFSNonPagedDirectoryCB));
821 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
823 pDirNode->NonPaged = pNonPagedDirEntry;
825 pDirNode->ObjectInformation = pObjectInfoCB;
831 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE | AFS_DIR_ENTRY_FAKE | AFS_DIR_ENTRY_VALID);
833 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_DOT_DOT_INDEX;
836 // Setup the names in the entry
839 pDirNode->NameInformation.FileName.Length = 2 * sizeof( WCHAR);
841 pDirNode->NameInformation.FileName.MaximumLength = 2 * sizeof( WCHAR);
843 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
845 pDirNode->NameInformation.FileName.Buffer[ 0] = L'.';
847 pDirNode->NameInformation.FileName.Buffer[ 1] = L'.';
850 // Populate the rest of the data
853 pObjectInfoCB->FileType = AFS_FILE_TYPE_DIRECTORY;
855 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
857 AFSGlobalDotDotDirEntry = pDirNode;
861 if( !NT_SUCCESS( ntStatus))
864 if( AFSGlobalDotDirEntry != NULL)
867 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
869 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
871 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
873 ExFreePool( AFSGlobalDotDirEntry);
875 AFSGlobalDotDirEntry = NULL;
878 if( AFSGlobalDotDotDirEntry != NULL)
881 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
883 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
885 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
887 ExFreePool( AFSGlobalDotDotDirEntry);
889 AFSGlobalDotDotDirEntry = NULL;
898 AFSInitDirEntry( IN AFSObjectInfoCB *ParentObjectInfo,
899 IN PUNICODE_STRING FileName,
900 IN PUNICODE_STRING TargetName,
901 IN AFSDirEnumEntry *DirEnumEntry,
905 AFSDirectoryCB *pDirNode = NULL;
906 NTSTATUS ntStatus = STATUS_SUCCESS;
907 ULONG ulEntryLength = 0;
908 AFSDirEnumEntry *pDirEnumCB = NULL;
909 AFSFileID stTargetFileID;
911 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
912 AFSObjectInfoCB *pObjectInfoCB = NULL;
913 BOOLEAN bAllocatedObjectCB = FALSE;
914 ULONGLONG ullIndex = 0;
915 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
921 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
922 AFS_TRACE_LEVEL_VERBOSE,
923 "AFSInitDirEntry Initializing entry %wZ parent FID %08lX-%08lX-%08lX-%08lX\n",
925 ParentObjectInfo->FileId.Cell,
926 ParentObjectInfo->FileId.Volume,
927 ParentObjectInfo->FileId.Vnode,
928 ParentObjectInfo->FileId.Unique);
931 // First thing is to locate/create our object information block
935 AFSAcquireExcl( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
938 ullIndex = AFSCreateLowIndex( &DirEnumEntry->FileId);
940 ntStatus = AFSLocateHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
942 (AFSBTreeEntry **)&pObjectInfoCB);
944 if( !NT_SUCCESS( ntStatus) ||
945 pObjectInfoCB == NULL)
949 // Allocate our object info cb
952 pObjectInfoCB = AFSAllocateObjectInfo( ParentObjectInfo,
955 if( pObjectInfoCB == NULL)
958 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
960 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
963 bAllocatedObjectCB = TRUE;
965 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
966 AFS_TRACE_LEVEL_VERBOSE,
967 "AFSInitDirEntry initialized object %08lX Parent Object %08lX for %wZ\n",
973 lCount = InterlockedIncrement( &pObjectInfoCB->ObjectReferenceCount);
975 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
976 AFS_TRACE_LEVEL_VERBOSE,
977 "AFSInitDirEntry Increment count on object %08lX Cnt %d\n",
981 AFSReleaseResource( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
983 ntStatus = STATUS_SUCCESS;
985 ulEntryLength = sizeof( AFSDirectoryCB) +
988 if( TargetName != NULL)
991 ulEntryLength += TargetName->Length;
994 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
998 if( pDirNode == NULL)
1001 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1004 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
1005 sizeof( AFSNonPagedDirectoryCB),
1006 AFS_DIR_ENTRY_NP_TAG);
1008 if( pNonPagedDirEntry == NULL)
1011 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1014 RtlZeroMemory( pDirNode,
1017 RtlZeroMemory( pNonPagedDirEntry,
1018 sizeof( AFSNonPagedDirectoryCB));
1020 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
1022 pDirNode->NonPaged = pNonPagedDirEntry;
1024 pDirNode->ObjectInformation = pObjectInfoCB;
1027 // Set valid entry and NOT_IN_PARENT flag
1030 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
1032 pDirNode->FileIndex = FileIndex;
1035 // Setup the names in the entry
1038 if( FileName->Length > 0)
1041 pDirNode->NameInformation.FileName.Length = FileName->Length;
1043 pDirNode->NameInformation.FileName.MaximumLength = FileName->Length;
1045 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
1047 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
1049 pDirNode->NameInformation.FileName.Length);
1052 // Create a CRC for the file
1055 pDirNode->CaseSensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1058 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
1062 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1063 AFS_TRACE_LEVEL_VERBOSE,
1064 "AFSInitDirEntry Initialized DE %p for %wZ in parent FID %08lX-%08lX-%08lX-%08lX\n",
1067 ParentObjectInfo->FileId.Cell,
1068 ParentObjectInfo->FileId.Volume,
1069 ParentObjectInfo->FileId.Vnode,
1070 ParentObjectInfo->FileId.Unique);
1072 if( TargetName != NULL &&
1073 TargetName->Length > 0)
1076 pDirNode->NameInformation.TargetName.Length = TargetName->Length;
1078 pDirNode->NameInformation.TargetName.MaximumLength = pDirNode->NameInformation.TargetName.Length;
1080 pDirNode->NameInformation.TargetName.Buffer = (WCHAR *)((char *)pDirNode +
1081 sizeof( AFSDirectoryCB) +
1082 pDirNode->NameInformation.FileName.Length);
1084 RtlCopyMemory( pDirNode->NameInformation.TargetName.Buffer,
1086 pDirNode->NameInformation.TargetName.Length);
1090 // If we allocated the object information cb then update the information
1093 if( bAllocatedObjectCB)
1097 // Populate the rest of the data
1100 pObjectInfoCB->FileId = DirEnumEntry->FileId;
1102 pObjectInfoCB->TargetFileId = DirEnumEntry->TargetFileId;
1104 pObjectInfoCB->FileType = DirEnumEntry->FileType;
1106 pObjectInfoCB->CreationTime = DirEnumEntry->CreationTime;
1108 pObjectInfoCB->LastAccessTime = DirEnumEntry->LastAccessTime;
1110 pObjectInfoCB->LastWriteTime = DirEnumEntry->LastWriteTime;
1112 pObjectInfoCB->ChangeTime = DirEnumEntry->ChangeTime;
1114 pObjectInfoCB->EndOfFile = DirEnumEntry->EndOfFile;
1116 pObjectInfoCB->AllocationSize = DirEnumEntry->AllocationSize;
1118 pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
1120 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1123 pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1126 if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
1127 pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
1130 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1133 pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
1136 // Object specific information
1139 pObjectInfoCB->Links = DirEnumEntry->Links;
1141 pObjectInfoCB->Expiration = DirEnumEntry->Expiration;
1143 pObjectInfoCB->DataVersion = DirEnumEntry->DataVersion;
1146 // Check for the case where we have a filetype of SymLink but both the TargetFid and the
1147 // TargetName are empty. In this case set the filetype to zero so we evaluate it later in
1151 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK &&
1152 pObjectInfoCB->TargetFileId.Vnode == 0 &&
1153 pObjectInfoCB->TargetFileId.Unique == 0 &&
1154 pDirNode->NameInformation.TargetName.Length == 0)
1158 // This will ensure we perform a validation on the node
1161 pObjectInfoCB->FileType = AFS_FILE_TYPE_UNKNOWN;
1164 if( pObjectInfoCB->FileType == AFS_FILE_TYPE_UNKNOWN)
1167 SetFlag( pObjectInfoCB->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1173 if( !NT_SUCCESS( ntStatus))
1176 if( pNonPagedDirEntry != NULL)
1179 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
1181 AFSExFreePool( pNonPagedDirEntry);
1184 if( pDirNode != NULL)
1187 AFSExFreePool( pDirNode);
1193 // Dereference our object info block if we have one
1196 if( pObjectInfoCB != NULL)
1199 lCount = InterlockedDecrement( &pObjectInfoCB->ObjectReferenceCount);
1201 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1202 AFS_TRACE_LEVEL_VERBOSE,
1203 "AFSInitDirEntry Decrement count on object %08lX Cnt %d\n",
1207 if( bAllocatedObjectCB)
1210 ASSERT( pObjectInfoCB->ObjectReferenceCount == 0);
1212 AFSDeleteObjectInfo( pObjectInfoCB);
1222 AFSCheckForReadOnlyAccess( IN ACCESS_MASK DesiredAccess,
1223 IN BOOLEAN DirectoryEntry)
1226 BOOLEAN bReturn = TRUE;
1227 ACCESS_MASK stAccessMask = 0;
1230 // Get rid of anything we don't know about
1233 DesiredAccess = (DesiredAccess &
1239 ACCESS_SYSTEM_SECURITY |
1243 FILE_READ_ATTRIBUTES |
1244 FILE_WRITE_ATTRIBUTES |
1245 FILE_LIST_DIRECTORY |
1251 // Our 'read only' access mask. These are the accesses we will
1252 // allow for a read only file
1255 stAccessMask = DELETE |
1260 ACCESS_SYSTEM_SECURITY |
1264 FILE_READ_ATTRIBUTES |
1265 FILE_WRITE_ATTRIBUTES |
1267 FILE_LIST_DIRECTORY |
1271 // For a directory, add in the directory specific accesses
1277 stAccessMask |= FILE_ADD_SUBDIRECTORY |
1282 if( FlagOn( DesiredAccess, ~stAccessMask))
1286 // A write access is set ...
1296 AFSEvaluateNode( IN GUID *AuthGroup,
1297 IN AFSDirectoryCB *DirEntry)
1300 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1301 NTSTATUS ntStatus = STATUS_SUCCESS;
1302 AFSDirEnumEntry *pDirEntry = NULL;
1303 UNICODE_STRING uniTargetName;
1308 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1313 if( !NT_SUCCESS( ntStatus))
1316 try_return( ntStatus);
1319 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1321 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1323 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1325 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1327 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1329 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1331 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1333 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1335 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1337 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1339 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1341 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1344 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1347 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1348 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1351 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1354 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1356 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1359 // If we have a target name then see if it needs updating ...
1362 if( pDirEntry->TargetNameLength > 0)
1366 // Update the target name information if needed
1369 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1371 uniTargetName.MaximumLength = uniTargetName.Length;
1373 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1375 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1378 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1379 RtlCompareUnicodeString( &uniTargetName,
1380 &DirEntry->NameInformation.TargetName,
1385 // Update the target name
1388 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1390 uniTargetName.Buffer,
1391 uniTargetName.Length);
1393 if( !NT_SUCCESS( ntStatus))
1396 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1398 try_return( ntStatus);
1402 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1407 if( pDirEntry != NULL)
1410 AFSExFreePool( pDirEntry);
1418 AFSValidateSymLink( IN GUID *AuthGroup,
1419 IN AFSDirectoryCB *DirEntry)
1422 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1423 NTSTATUS ntStatus = STATUS_SUCCESS;
1424 AFSDirEnumEntry *pDirEntry = NULL;
1425 UNICODE_STRING uniTargetName;
1430 ntStatus = AFSEvaluateTargetByID( DirEntry->ObjectInformation,
1435 if( !NT_SUCCESS( ntStatus))
1438 try_return( ntStatus);
1441 if( pDirEntry->FileType == AFS_FILE_TYPE_UNKNOWN ||
1442 pDirEntry->FileType == AFS_FILE_TYPE_INVALID)
1445 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1448 DirEntry->ObjectInformation->TargetFileId = pDirEntry->TargetFileId;
1450 DirEntry->ObjectInformation->Expiration = pDirEntry->Expiration;
1452 DirEntry->ObjectInformation->DataVersion = pDirEntry->DataVersion;
1455 // Update the target name information if needed
1458 uniTargetName.Length = (USHORT)pDirEntry->TargetNameLength;
1460 uniTargetName.MaximumLength = uniTargetName.Length;
1462 uniTargetName.Buffer = (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset);
1464 if( uniTargetName.Length > 0)
1467 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
1470 if( DirEntry->NameInformation.TargetName.Length == 0 ||
1471 RtlCompareUnicodeString( &uniTargetName,
1472 &DirEntry->NameInformation.TargetName,
1477 // Update the target name
1480 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
1482 uniTargetName.Buffer,
1483 uniTargetName.Length);
1485 if( !NT_SUCCESS( ntStatus))
1488 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1490 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1494 AFSReleaseResource( &DirEntry->NonPaged->Lock);
1498 // If the FileType is the same then nothing to do since it IS
1502 if( pDirEntry->FileType == DirEntry->ObjectInformation->FileType)
1505 ASSERT( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK);
1507 try_return( ntStatus = STATUS_SUCCESS);
1510 DirEntry->ObjectInformation->FileType = pDirEntry->FileType;
1512 DirEntry->ObjectInformation->CreationTime = pDirEntry->CreationTime;
1514 DirEntry->ObjectInformation->LastAccessTime = pDirEntry->LastAccessTime;
1516 DirEntry->ObjectInformation->LastWriteTime = pDirEntry->LastWriteTime;
1518 DirEntry->ObjectInformation->ChangeTime = pDirEntry->ChangeTime;
1520 DirEntry->ObjectInformation->EndOfFile = pDirEntry->EndOfFile;
1522 DirEntry->ObjectInformation->AllocationSize = pDirEntry->AllocationSize;
1524 DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
1526 if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1529 DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
1532 if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
1533 pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
1536 DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
1539 DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
1541 DirEntry->ObjectInformation->Links = pDirEntry->Links;
1545 if( pDirEntry != NULL)
1548 AFSExFreePool( pDirEntry);
1556 AFSInvalidateCache( IN AFSInvalidateCacheCB *InvalidateCB)
1559 NTSTATUS ntStatus = STATUS_SUCCESS;
1560 AFSFcb *pDcb = NULL, *pFcb = NULL, *pNextFcb = NULL;
1561 AFSVolumeCB *pVolumeCB = NULL;
1562 AFSFcb *pTargetDcb = NULL;
1563 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
1564 AFSDirectoryCB *pCurrentDirEntry = NULL;
1565 BOOLEAN bIsChild = FALSE;
1566 ULONGLONG ullIndex = 0;
1567 AFSObjectInfoCB *pObjectInfo = NULL;
1568 IO_STATUS_BLOCK stIoStatus;
1576 // Need to locate the Fcb for the directory to purge
1579 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1580 AFS_TRACE_LEVEL_VERBOSE,
1581 "AFSInvalidateCache Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
1582 &pDevExt->Specific.RDR.VolumeTreeLock,
1583 PsGetCurrentThread());
1586 // Starve any exclusive waiters on this paticular call
1589 AFSAcquireSharedStarveExclusive( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
1592 // Locate the volume node
1595 ullIndex = AFSCreateHighIndex( &InvalidateCB->FileID);
1597 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
1599 (AFSBTreeEntry **)&pVolumeCB);
1601 if( pVolumeCB != NULL)
1604 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
1606 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1607 AFS_TRACE_LEVEL_VERBOSE,
1608 "AFSInvalidateCache Increment count on volume %08lX Cnt %d\n",
1613 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
1615 if( !NT_SUCCESS( ntStatus) ||
1618 try_return( ntStatus = STATUS_SUCCESS);
1622 // If this is a whole volume invalidation then go do it now
1625 if( InvalidateCB->WholeVolume ||
1626 AFSIsVolumeFID( &InvalidateCB->FileID))
1629 ntStatus = AFSInvalidateVolume( pVolumeCB,
1630 InvalidateCB->Reason);
1632 AFSFsRtlNotifyFullReportChange( &pVolumeCB->ObjectInformation,
1634 FILE_NOTIFY_CHANGE_FILE_NAME |
1635 FILE_NOTIFY_CHANGE_DIR_NAME |
1636 FILE_NOTIFY_CHANGE_NAME |
1637 FILE_NOTIFY_CHANGE_ATTRIBUTES |
1638 FILE_NOTIFY_CHANGE_SIZE,
1639 FILE_ACTION_MODIFIED);
1641 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1643 try_return( ntStatus);
1646 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
1649 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1651 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1652 AFS_TRACE_LEVEL_VERBOSE,
1653 "AFSInvalidateCache Decrement count on volume %08lX Cnt %d\n",
1655 pVolumeCB->VolumeReferenceCount);
1657 ullIndex = AFSCreateLowIndex( &InvalidateCB->FileID);
1659 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
1661 (AFSBTreeEntry **)&pObjectInfo);
1663 if( pObjectInfo != NULL)
1667 // Reference the node so it won't be torn down
1670 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
1672 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1673 AFS_TRACE_LEVEL_VERBOSE,
1674 "AFSInvalidateCache Increment count on object %08lX Cnt %d\n",
1679 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
1681 if( !NT_SUCCESS( ntStatus) ||
1682 pObjectInfo == NULL)
1684 try_return( ntStatus = STATUS_SUCCESS);
1687 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
1688 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK ||
1689 pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
1692 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1693 AFS_TRACE_LEVEL_VERBOSE,
1694 "AFSInvalidateCache Invalidation on node type %d for fid %08lX-%08lX-%08lX-%08lX Reason %d\n",
1695 pObjectInfo->FileType,
1696 pObjectInfo->FileId.Cell,
1697 pObjectInfo->FileId.Volume,
1698 pObjectInfo->FileId.Vnode,
1699 pObjectInfo->FileId.Unique,
1700 InvalidateCB->Reason);
1703 // We only act on the mount point itself, not the target. If the
1704 // node has been deleted then mark it as such otherwise indicate
1705 // it requires verification
1708 if( InvalidateCB->Reason == AFS_INVALIDATE_DELETED)
1710 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
1715 if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED)
1718 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1720 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1723 pObjectInfo->Expiration.QuadPart = 0;
1725 pObjectInfo->TargetFileId.Vnode = 0;
1727 pObjectInfo->TargetFileId.Unique = 0;
1729 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1730 AFS_TRACE_LEVEL_VERBOSE,
1731 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1732 pObjectInfo->FileId.Cell,
1733 pObjectInfo->FileId.Volume,
1734 pObjectInfo->FileId.Vnode,
1735 pObjectInfo->FileId.Unique);
1737 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1740 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1742 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1744 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1747 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION ||
1748 InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED)
1750 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1754 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1757 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1759 FILE_NOTIFY_CHANGE_FILE_NAME |
1760 FILE_NOTIFY_CHANGE_ATTRIBUTES,
1761 FILE_ACTION_MODIFIED);
1763 try_return( ntStatus);
1767 // Depending on the reason for invalidation then perform work on the node
1770 switch( InvalidateCB->Reason)
1773 case AFS_INVALIDATE_DELETED:
1777 // Mark this node as invalid
1780 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DELETED);
1782 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1783 AFS_TRACE_LEVEL_VERBOSE,
1784 "AFSInvalidateCache Set DELETE flag on fid %08lX-%08lX-%08lX-%08lX\n",
1785 pObjectInfo->FileId.Cell,
1786 pObjectInfo->FileId.Volume,
1787 pObjectInfo->FileId.Vnode,
1788 pObjectInfo->FileId.Unique);
1790 if( pObjectInfo->ParentObjectInformation != NULL)
1793 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1794 AFS_TRACE_LEVEL_VERBOSE,
1795 "AFSInvalidateCache Set VERIFY flag on parent fid %08lX-%08lX-%08lX-%08lX\n",
1796 pObjectInfo->ParentObjectInformation->FileId.Cell,
1797 pObjectInfo->ParentObjectInformation->FileId.Volume,
1798 pObjectInfo->ParentObjectInformation->FileId.Vnode,
1799 pObjectInfo->ParentObjectInformation->FileId.Unique);
1801 SetFlag( pObjectInfo->ParentObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
1803 pObjectInfo->ParentObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
1805 pObjectInfo->ParentObjectInformation->Expiration.QuadPart = 0;
1808 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1810 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1814 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1817 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1820 FILE_ACTION_REMOVED);
1822 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
1823 pObjectInfo->Fcb != NULL)
1828 // Clear out the extents
1829 // And get rid of them (note this involves waiting
1830 // for any writes or reads to the cache to complete)
1833 (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb,
1840 case AFS_INVALIDATE_FLUSHED:
1843 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE &&
1844 pObjectInfo->Fcb != NULL)
1847 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1848 AFS_TRACE_LEVEL_VERBOSE,
1849 "AFSInvalidateCache Flush/purge file fid %08lX-%08lX-%08lX-%08lX\n",
1850 pObjectInfo->FileId.Cell,
1851 pObjectInfo->FileId.Volume,
1852 pObjectInfo->FileId.Vnode,
1853 pObjectInfo->FileId.Unique);
1855 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
1861 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1866 if( !NT_SUCCESS( stIoStatus.Status))
1869 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1870 AFS_TRACE_LEVEL_ERROR,
1871 "AFSInvalidateCache CcFlushCache failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
1872 pObjectInfo->FileId.Cell,
1873 pObjectInfo->FileId.Volume,
1874 pObjectInfo->FileId.Vnode,
1875 pObjectInfo->FileId.Unique,
1877 stIoStatus.Information);
1879 ntStatus = stIoStatus.Status;
1882 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
1887 __except( EXCEPTION_EXECUTE_HANDLER)
1890 ntStatus = GetExceptionCode();
1893 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
1896 // Clear out the extents
1897 // Get rid of them (note this involves waiting
1898 // for any writes or reads to the cache to complete)
1901 (VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb,
1905 pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
1908 if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
1911 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1912 AFS_TRACE_LEVEL_VERBOSE,
1913 "AFSInvalidateCache Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
1914 pObjectInfo->FileId.Cell,
1915 pObjectInfo->FileId.Volume,
1916 pObjectInfo->FileId.Vnode,
1917 pObjectInfo->FileId.Unique);
1919 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
1922 // Fall through to the default processing
1928 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
1930 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
1934 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
1937 if( InvalidateCB->Reason == AFS_INVALIDATE_CREDS)
1939 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
1942 if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
1944 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
1948 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
1951 AFSFsRtlNotifyFullReportChange( pObjectInfo->ParentObjectInformation,
1954 FILE_ACTION_MODIFIED);
1957 // Indicate this node requires re-evaluation for the remaining reasons
1960 pObjectInfo->Expiration.QuadPart = 0;
1962 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1963 AFS_TRACE_LEVEL_VERBOSE,
1964 "AFSInvalidateCache Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
1965 pObjectInfo->FileId.Cell,
1966 pObjectInfo->FileId.Volume,
1967 pObjectInfo->FileId.Vnode,
1968 pObjectInfo->FileId.Unique);
1970 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
1978 if( pObjectInfo != NULL)
1981 lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
1983 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1984 AFS_TRACE_LEVEL_VERBOSE,
1985 "AFSInvalidateCache Decrement count on object %08lX Cnt %d\n",
1995 AFSIsChildOfParent( IN AFSFcb *Dcb,
1999 BOOLEAN bIsChild = FALSE;
2000 AFSFcb *pCurrentFcb = Fcb;
2002 while( pCurrentFcb != NULL)
2005 if( pCurrentFcb->ObjectInformation->ParentObjectInformation == Dcb->ObjectInformation)
2013 pCurrentFcb = pCurrentFcb->ObjectInformation->ParentObjectInformation->Fcb;
2021 AFSCreateHighIndex( IN AFSFileID *FileID)
2024 ULONGLONG ullIndex = 0;
2026 ullIndex = (((ULONGLONG)FileID->Cell << 32) | FileID->Volume);
2033 AFSCreateLowIndex( IN AFSFileID *FileID)
2036 ULONGLONG ullIndex = 0;
2038 ullIndex = (((ULONGLONG)FileID->Vnode << 32) | FileID->Unique);
2044 AFSCheckAccess( IN ACCESS_MASK DesiredAccess,
2045 IN ACCESS_MASK GrantedAccess,
2046 IN BOOLEAN DirectoryEntry)
2049 BOOLEAN bAccessGranted = TRUE;
2052 // Check if we are asking for read/write and granted only read only
2053 // NOTE: There will be more checks here
2056 if( !AFSCheckForReadOnlyAccess( DesiredAccess,
2058 AFSCheckForReadOnlyAccess( GrantedAccess,
2062 bAccessGranted = FALSE;
2065 return bAccessGranted;
2069 AFSGetDriverStatus( IN AFSDriverStatusRespCB *DriverStatus)
2072 NTSTATUS ntStatus = STATUS_SUCCESS;
2073 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2079 DriverStatus->Status = AFS_DRIVER_STATUS_READY;
2081 if( AFSGlobalRoot == NULL)
2088 DriverStatus->Status = AFS_DRIVER_STATUS_NOT_READY;
2091 if( pControlDevExt->Specific.Control.CommServiceCB.IrpPoolControlFlag != POOL_ACTIVE)
2098 DriverStatus->Status = AFS_DRIVER_STATUS_NO_SERVICE;
2105 AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
2106 IN UNICODE_STRING *SubstituteName,
2107 IN ULONG StringIndex)
2110 NTSTATUS ntStatus = STATUS_SUCCESS;
2111 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
2112 AFSSysNameCB *pSysName = NULL;
2113 ERESOURCE *pSysNameLock = NULL;
2116 UNICODE_STRING uniSysName;
2123 if( IoIs32bitProcess( NULL))
2126 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2128 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2133 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
2135 pSysName = pControlDevExt->Specific.Control.SysName64ListHead;
2139 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
2141 pSysName = pControlDevExt->Specific.Control.SysName32ListHead;
2145 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2146 AFS_TRACE_LEVEL_VERBOSE,
2147 "AFSSubstituteSysName Acquiring SysName lock %08lX SHARED %08lX\n",
2149 PsGetCurrentThread());
2151 AFSAcquireShared( pSysNameLock,
2155 // Find where we are in the list
2158 while( pSysName != NULL &&
2159 ulIndex < StringIndex)
2162 pSysName = pSysName->fLink;
2167 if( pSysName == NULL)
2170 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
2173 RtlInitUnicodeString( &uniSysName,
2176 // If it is a full component of @SYS then just substitue the
2180 if( RtlCompareUnicodeString( &uniSysName,
2185 SubstituteName->Length = pSysName->SysName.Length;
2186 SubstituteName->MaximumLength = SubstituteName->Length;
2188 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2189 SubstituteName->Length,
2190 AFS_SUBST_BUFFER_TAG);
2192 if( SubstituteName->Buffer == NULL)
2195 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2198 RtlCopyMemory( SubstituteName->Buffer,
2199 pSysName->SysName.Buffer,
2200 pSysName->SysName.Length);
2207 while( ComponentName->Buffer[ usIndex] != L'@')
2213 SubstituteName->Length = (usIndex * sizeof( WCHAR)) + pSysName->SysName.Length;
2214 SubstituteName->MaximumLength = SubstituteName->Length;
2216 SubstituteName->Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2217 SubstituteName->Length,
2218 AFS_SUBST_BUFFER_TAG);
2220 if( SubstituteName->Buffer == NULL)
2223 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2226 RtlCopyMemory( SubstituteName->Buffer,
2227 ComponentName->Buffer,
2228 usIndex * sizeof( WCHAR));
2230 RtlCopyMemory( &SubstituteName->Buffer[ usIndex],
2231 pSysName->SysName.Buffer,
2232 pSysName->SysName.Length);
2237 AFSReleaseResource( pSysNameLock);
2244 AFSSubstituteNameInPath( IN OUT UNICODE_STRING *FullPathName,
2245 IN OUT UNICODE_STRING *ComponentName,
2246 IN UNICODE_STRING *SubstituteName,
2247 IN OUT UNICODE_STRING *RemainingPath,
2248 IN BOOLEAN FreePathName)
2251 NTSTATUS ntStatus = STATUS_SUCCESS;
2252 UNICODE_STRING uniPathName;
2253 USHORT usPrefixNameLen = 0;
2254 SHORT sNameLenDelta = 0;
2260 // If the passed in name can handle the additional length
2261 // then just moves things around
2264 sNameLenDelta = SubstituteName->Length - ComponentName->Length;
2266 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2268 if( FullPathName->MaximumLength > FullPathName->Length + sNameLenDelta)
2271 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2274 RtlMoveMemory( &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + SubstituteName->Length)/sizeof( WCHAR))],
2275 &FullPathName->Buffer[ ((usPrefixNameLen*sizeof( WCHAR) + ComponentName->Length)/sizeof( WCHAR))],
2276 FullPathName->Length - usPrefixNameLen*sizeof( WCHAR) - ComponentName->Length);
2279 RtlCopyMemory( &FullPathName->Buffer[ usPrefixNameLen],
2280 SubstituteName->Buffer,
2281 SubstituteName->Length);
2283 FullPathName->Length += sNameLenDelta;
2285 ComponentName->Length += sNameLenDelta;
2287 ComponentName->MaximumLength = ComponentName->Length;
2289 if ( RemainingPath->Buffer)
2292 RemainingPath->Buffer += sNameLenDelta/sizeof( WCHAR);
2295 try_return( ntStatus);
2299 // Need to re-allocate the buffer
2302 uniPathName.Length = FullPathName->Length -
2303 ComponentName->Length +
2304 SubstituteName->Length;
2306 uniPathName.MaximumLength = FullPathName->MaximumLength + PAGE_SIZE;
2308 uniPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
2309 uniPathName.MaximumLength,
2310 AFS_NAME_BUFFER_FOUR_TAG);
2312 if( uniPathName.Buffer == NULL)
2315 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2318 usPrefixNameLen = (USHORT)(ComponentName->Buffer - FullPathName->Buffer);
2320 usPrefixNameLen *= sizeof( WCHAR);
2322 RtlZeroMemory( uniPathName.Buffer,
2323 uniPathName.MaximumLength);
2325 RtlCopyMemory( uniPathName.Buffer,
2326 FullPathName->Buffer,
2329 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen/sizeof( WCHAR))],
2330 SubstituteName->Buffer,
2331 SubstituteName->Length);
2333 if( FullPathName->Length > usPrefixNameLen + ComponentName->Length)
2336 RtlCopyMemory( &uniPathName.Buffer[ (usPrefixNameLen + SubstituteName->Length)/sizeof( WCHAR)],
2337 &FullPathName->Buffer[ (usPrefixNameLen + ComponentName->Length)/sizeof( WCHAR)],
2338 FullPathName->Length - usPrefixNameLen - ComponentName->Length);
2341 ComponentName->Buffer = uniPathName.Buffer + (ComponentName->Buffer - FullPathName->Buffer);
2343 ComponentName->Length += sNameLenDelta;
2345 ComponentName->MaximumLength = ComponentName->Length;
2347 if ( RemainingPath->Buffer)
2350 RemainingPath->Buffer = uniPathName.Buffer
2351 + (RemainingPath->Buffer - FullPathName->Buffer)
2352 + sNameLenDelta/sizeof( WCHAR);
2357 AFSExFreePool( FullPathName->Buffer);
2360 *FullPathName = uniPathName;
2371 AFSInvalidateVolume( IN AFSVolumeCB *VolumeCB,
2375 NTSTATUS ntStatus = STATUS_SUCCESS;
2376 AFSFcb *pFcb = NULL;
2377 AFSObjectInfoCB *pCurrentObject = NULL;
2383 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2384 AFS_TRACE_LEVEL_VERBOSE,
2385 "AFSInvalidateVolume Invalidate volume fid %08lX-%08lX-%08lX-%08lX Reason %08lX\n",
2386 VolumeCB->ObjectInformation.FileId.Cell,
2387 VolumeCB->ObjectInformation.FileId.Volume,
2388 VolumeCB->ObjectInformation.FileId.Vnode,
2389 VolumeCB->ObjectInformation.FileId.Unique,
2393 // Depending on the reason for invalidation then perform work on the node
2399 case AFS_INVALIDATE_DELETED:
2403 // Mark this volume as invalid
2406 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2408 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2410 SetFlag( VolumeCB->Flags, AFS_VOLUME_FLAGS_OFFLINE);
2412 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2414 FILE_NOTIFY_CHANGE_DIR_NAME,
2415 FILE_ACTION_REMOVED);
2417 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2420 pCurrentObject = VolumeCB->ObjectInfoListHead;
2422 while( pCurrentObject != NULL)
2425 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2427 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2431 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2434 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2437 FILE_ACTION_REMOVED);
2439 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
2441 pFcb = pCurrentObject->Fcb;
2444 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
2449 // Clear out the extents
2450 // And get rid of them (note this involves waiting
2451 // for any writes or reads to the cache to complete)
2454 (VOID) AFSTearDownFcbExtents( pFcb,
2458 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2461 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2470 // Indicate this node requires re-evaluation for the remaining reasons
2473 VolumeCB->ObjectInformation.Expiration.QuadPart = 0;
2475 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2476 AFS_TRACE_LEVEL_VERBOSE,
2477 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2478 VolumeCB->ObjectInformation.FileId.Cell,
2479 VolumeCB->ObjectInformation.FileId.Volume,
2480 VolumeCB->ObjectInformation.FileId.Vnode,
2481 VolumeCB->ObjectInformation.FileId.Unique);
2483 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY);
2485 if( Reason == AFS_INVALIDATE_FLUSHED)
2488 VolumeCB->ObjectInformation.DataVersion.QuadPart = (ULONGLONG)-1;
2492 // Notify anyone that cares
2495 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2497 if( Reason == AFS_INVALIDATE_CREDS)
2499 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2502 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2503 Reason == AFS_INVALIDATE_FLUSHED)
2505 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2509 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2512 AFSFsRtlNotifyFullReportChange( &VolumeCB->ObjectInformation,
2515 FILE_ACTION_MODIFIED);
2518 // Volume invalidations require all objects in the volume be re-verified
2521 AFSAcquireShared( VolumeCB->ObjectInfoTree.TreeLock,
2524 pCurrentObject = VolumeCB->ObjectInfoListHead;
2526 while( pCurrentObject != NULL)
2529 pCurrentObject->Expiration.QuadPart = 0;
2531 pCurrentObject->TargetFileId.Vnode = 0;
2533 pCurrentObject->TargetFileId.Unique = 0;
2535 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2536 AFS_TRACE_LEVEL_VERBOSE,
2537 "AFSInvalidateVolume Setting VERIFY flag on fid %08lX-%08lX-%08lX-%08lX\n",
2538 pCurrentObject->FileId.Cell,
2539 pCurrentObject->FileId.Volume,
2540 pCurrentObject->FileId.Vnode,
2541 pCurrentObject->FileId.Unique);
2543 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
2545 if( Reason == AFS_INVALIDATE_FLUSHED)
2548 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
2551 if( Reason == AFS_INVALIDATE_FLUSHED &&
2552 pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
2555 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2556 AFS_TRACE_LEVEL_VERBOSE,
2557 "AFSInvalidateVolume Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
2558 pCurrentObject->FileId.Cell,
2559 pCurrentObject->FileId.Volume,
2560 pCurrentObject->FileId.Vnode,
2561 pCurrentObject->FileId.Unique);
2563 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2566 if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
2568 ulFilter = FILE_NOTIFY_CHANGE_DIR_NAME;
2572 ulFilter = FILE_NOTIFY_CHANGE_FILE_NAME;
2575 if( Reason == AFS_INVALIDATE_CREDS)
2577 ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
2580 if( Reason == AFS_INVALIDATE_DATA_VERSION ||
2581 Reason == AFS_INVALIDATE_FLUSHED)
2583 ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
2587 ulFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
2590 AFSFsRtlNotifyFullReportChange( pCurrentObject,
2593 FILE_ACTION_MODIFIED);
2595 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
2598 AFSReleaseResource( VolumeCB->ObjectInfoTree.TreeLock);
2609 AFSVerifyEntry( IN GUID *AuthGroup,
2610 IN AFSDirectoryCB *DirEntry)
2613 NTSTATUS ntStatus = STATUS_SUCCESS;
2614 AFSDirEnumEntry *pDirEnumEntry = NULL;
2615 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
2616 IO_STATUS_BLOCK stIoStatus;
2621 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2622 AFS_TRACE_LEVEL_VERBOSE_2,
2623 "AFSVerifyEntry Verifying entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2624 &DirEntry->NameInformation.FileName,
2625 pObjectInfo->FileId.Cell,
2626 pObjectInfo->FileId.Volume,
2627 pObjectInfo->FileId.Vnode,
2628 pObjectInfo->FileId.Unique);
2630 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
2635 if( !NT_SUCCESS( ntStatus))
2638 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2639 AFS_TRACE_LEVEL_ERROR,
2640 "AFSValidateEntry Evaluate Target failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2641 &DirEntry->NameInformation.FileName,
2642 pObjectInfo->FileId.Cell,
2643 pObjectInfo->FileId.Volume,
2644 pObjectInfo->FileId.Vnode,
2645 pObjectInfo->FileId.Unique,
2648 try_return( ntStatus);
2652 // Check the data version of the file
2655 if( pObjectInfo->DataVersion.QuadPart == pDirEnumEntry->DataVersion.QuadPart &&
2656 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2659 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2660 AFS_TRACE_LEVEL_VERBOSE,
2661 "AFSVerifyEntry No DV change %I64X for Fcb %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2662 pObjectInfo->DataVersion.QuadPart,
2663 &DirEntry->NameInformation.FileName,
2664 pObjectInfo->FileId.Cell,
2665 pObjectInfo->FileId.Volume,
2666 pObjectInfo->FileId.Vnode,
2667 pObjectInfo->FileId.Unique);
2670 // We are ok, just get out
2673 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2675 try_return( ntStatus = STATUS_SUCCESS);
2679 // New data version so we will need to process the node based on the type
2682 switch( pDirEnumEntry->FileType)
2685 case AFS_FILE_TYPE_MOUNTPOINT:
2689 // For a mount point we need to ensure the target is the same
2692 if( !AFSIsEqualFID( &pObjectInfo->TargetFileId,
2693 &pDirEnumEntry->TargetFileId))
2699 // Update the metadata for the entry
2702 ntStatus = AFSUpdateMetaData( DirEntry,
2705 if( NT_SUCCESS( ntStatus))
2708 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2714 case AFS_FILE_TYPE_SYMLINK:
2717 ASSERT( pDirEnumEntry->TargetNameLength > 0);
2720 // Update the metadata for the entry
2723 ntStatus = AFSUpdateMetaData( DirEntry,
2726 if( NT_SUCCESS( ntStatus))
2729 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2735 case AFS_FILE_TYPE_FILE:
2737 FILE_OBJECT * pCCFileObject = NULL;
2738 BOOLEAN bPurgeExtents = FALSE;
2740 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
2742 bPurgeExtents = TRUE;
2744 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2745 AFS_TRACE_LEVEL_VERBOSE,
2746 "AFSVerifyEntry Clearing VERIFY_DATA flag %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 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
2757 // Update the metadata for the entry
2760 ntStatus = AFSUpdateMetaData( DirEntry,
2763 if( !NT_SUCCESS( ntStatus))
2766 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2767 AFS_TRACE_LEVEL_ERROR,
2768 "AFSInvalidateCache Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX ntStatus %08lX\n",
2769 &DirEntry->NameInformation.FileName,
2770 pObjectInfo->FileId.Cell,
2771 pObjectInfo->FileId.Volume,
2772 pObjectInfo->FileId.Vnode,
2773 pObjectInfo->FileId.Unique,
2779 if( pObjectInfo->Fcb != NULL)
2782 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2783 AFS_TRACE_LEVEL_VERBOSE,
2784 "AFSVerifyEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2785 &DirEntry->NameInformation.FileName,
2786 pObjectInfo->FileId.Cell,
2787 pObjectInfo->FileId.Volume,
2788 pObjectInfo->FileId.Vnode,
2789 pObjectInfo->FileId.Unique);
2791 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2797 CcFlushCache( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2802 if( !NT_SUCCESS( stIoStatus.Status))
2805 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2806 AFS_TRACE_LEVEL_ERROR,
2807 "AFSVerifyEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
2808 &DirEntry->NameInformation.FileName,
2809 pObjectInfo->FileId.Cell,
2810 pObjectInfo->FileId.Volume,
2811 pObjectInfo->FileId.Vnode,
2812 pObjectInfo->FileId.Unique,
2814 stIoStatus.Information);
2816 ntStatus = stIoStatus.Status;
2822 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2828 __except( EXCEPTION_EXECUTE_HANDLER)
2830 ntStatus = GetExceptionCode();
2832 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
2833 AFS_TRACE_LEVEL_ERROR,
2834 "AFSVerifyEntry CcFlushCache or CcPurgeCacheSection Exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
2835 &DirEntry->NameInformation.FileName,
2836 pObjectInfo->FileId.Cell,
2837 pObjectInfo->FileId.Volume,
2838 pObjectInfo->FileId.Vnode,
2839 pObjectInfo->FileId.Unique,
2843 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2847 AFSFlushExtents( pObjectInfo->Fcb,
2852 // Reacquire the Fcb to purge the cache
2855 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2856 AFS_TRACE_LEVEL_VERBOSE,
2857 "AFSVerifyEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
2858 &pObjectInfo->Fcb->NPFcb->Resource,
2859 PsGetCurrentThread());
2861 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
2865 // Update file sizes
2868 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2869 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2870 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2872 pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
2874 if ( pCCFileObject != NULL)
2876 CcSetFileSizes( pCCFileObject,
2877 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
2880 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->Resource);
2884 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2885 AFS_TRACE_LEVEL_WARNING,
2886 "AFSValidateEntry Fcb NULL %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2887 &DirEntry->NameInformation.FileName,
2888 pObjectInfo->FileId.Cell,
2889 pObjectInfo->FileId.Volume,
2890 pObjectInfo->FileId.Vnode,
2891 pObjectInfo->FileId.Unique);
2894 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2899 case AFS_FILE_TYPE_DIRECTORY:
2902 AFSFcb *pCurrentFcb = NULL;
2903 AFSDirectoryCB *pCurrentDirEntry = NULL;
2906 // For a directory or root entry flush the content of
2907 // the directory enumeration.
2910 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
2913 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2914 AFS_TRACE_LEVEL_VERBOSE_2,
2915 "AFSVerifyEntry Validating directory content for entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2916 &DirEntry->NameInformation.FileName,
2917 pObjectInfo->FileId.Cell,
2918 pObjectInfo->FileId.Volume,
2919 pObjectInfo->FileId.Vnode,
2920 pObjectInfo->FileId.Unique);
2922 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2925 ntStatus = AFSValidateDirectoryCache( pObjectInfo,
2928 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2930 if ( !NT_SUCCESS( ntStatus))
2933 try_return( ntStatus);
2938 // Update the metadata for the entry
2941 ntStatus = AFSUpdateMetaData( DirEntry,
2944 if( NT_SUCCESS( ntStatus))
2947 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2953 case AFS_FILE_TYPE_DFSLINK:
2956 UNICODE_STRING uniTargetName;
2959 // For a DFS link need to check the target name has not changed
2962 uniTargetName.Length = (USHORT)pDirEnumEntry->TargetNameLength;
2964 uniTargetName.MaximumLength = uniTargetName.Length;
2966 uniTargetName.Buffer = (WCHAR *)((char *)pDirEnumEntry + pDirEnumEntry->TargetNameOffset);
2968 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
2971 if( DirEntry->NameInformation.TargetName.Length == 0 ||
2972 RtlCompareUnicodeString( &uniTargetName,
2973 &DirEntry->NameInformation.TargetName,
2978 // Update the target name
2981 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
2983 uniTargetName.Buffer,
2984 uniTargetName.Length);
2986 if( !NT_SUCCESS( ntStatus))
2989 AFSReleaseResource( &DirEntry->NonPaged->Lock);
2995 AFSReleaseResource( &DirEntry->NonPaged->Lock);
2998 // Update the metadata for the entry
3001 ntStatus = AFSUpdateMetaData( DirEntry,
3004 if( NT_SUCCESS( ntStatus))
3007 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
3015 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3016 AFS_TRACE_LEVEL_WARNING,
3017 "AFSVerifyEntry Attempt to verify node of type %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3018 pObjectInfo->FileType,
3019 &DirEntry->NameInformation.FileName,
3020 pObjectInfo->FileId.Cell,
3021 pObjectInfo->FileId.Volume,
3022 pObjectInfo->FileId.Vnode,
3023 pObjectInfo->FileId.Unique);
3030 if( pDirEnumEntry != NULL)
3033 AFSExFreePool( pDirEnumEntry);
3041 AFSSetVolumeState( IN AFSVolumeStatusCB *VolumeStatus)
3044 NTSTATUS ntStatus = STATUS_SUCCESS;
3045 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
3046 ULONGLONG ullIndex = 0;
3047 AFSVolumeCB *pVolumeCB = NULL;
3048 AFSFcb *pFcb = NULL;
3049 AFSObjectInfoCB *pCurrentObject = NULL;
3055 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3056 AFS_TRACE_LEVEL_VERBOSE,
3057 "AFSSetVolumeState Marking volume state %d Volume Cell %08lX Volume %08lX\n",
3058 VolumeStatus->Online,
3059 VolumeStatus->FileID.Cell,
3060 VolumeStatus->FileID.Volume);
3063 // Need to locate the Fcb for the directory to purge
3066 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3067 AFS_TRACE_LEVEL_VERBOSE,
3068 "AFSSetVolumeState Acquiring RDR VolumeTreeLock lock %08lX SHARED %08lX\n",
3069 &pDevExt->Specific.RDR.VolumeTreeLock,
3070 PsGetCurrentThread());
3072 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
3075 // Locate the volume node
3078 ullIndex = AFSCreateHighIndex( &VolumeStatus->FileID);
3080 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
3082 (AFSBTreeEntry **)&pVolumeCB);
3084 if( pVolumeCB != NULL)
3087 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
3089 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3092 // Set the volume state accordingly
3095 if( VolumeStatus->Online)
3098 InterlockedAnd( (LONG *)&(pVolumeCB->Flags), ~AFS_VOLUME_FLAGS_OFFLINE);
3103 InterlockedOr( (LONG *)&(pVolumeCB->Flags), AFS_VOLUME_FLAGS_OFFLINE);
3106 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
3109 pCurrentObject = pVolumeCB->ObjectInfoListHead;;
3111 while( pCurrentObject != NULL)
3114 if( VolumeStatus->Online)
3117 ClearFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3119 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
3121 pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
3126 SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID);
3129 pFcb = pCurrentObject->Fcb;
3132 !(VolumeStatus->Online) &&
3133 pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
3136 AFSDbgLogMsg( AFS_SUBSYSTEM_EXTENT_PROCESSING,
3137 AFS_TRACE_LEVEL_ERROR,
3138 "AFSSetVolumeState Marking volume offline and canceling extents Volume Cell %08lX Volume %08lX\n",
3139 VolumeStatus->FileID.Cell,
3140 VolumeStatus->FileID.Volume);
3143 // Clear out the extents
3146 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3147 AFS_TRACE_LEVEL_VERBOSE,
3148 "AFSSetVolumeState Acquiring Fcb extents lock %08lX EXCL %08lX\n",
3149 &pFcb->NPFcb->Specific.File.ExtentsResource,
3150 PsGetCurrentThread());
3152 AFSAcquireExcl( &pFcb->NPFcb->Specific.File.ExtentsResource,
3155 pFcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_CANCELLED;
3157 KeSetEvent( &pFcb->NPFcb->Specific.File.ExtentsRequestComplete,
3161 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3162 AFS_TRACE_LEVEL_VERBOSE,
3163 "AFSSetVolumeState Releasing Fcb extents lock %08lX EXCL %08lX\n",
3164 &pFcb->NPFcb->Specific.File.ExtentsResource,
3165 PsGetCurrentThread());
3167 AFSReleaseResource( &pFcb->NPFcb->Specific.File.ExtentsResource);
3170 // And get rid of them (note this involves waiting
3171 // for any writes or reads to the cache to complete)
3174 (VOID) AFSTearDownFcbExtents( pFcb,
3178 pCurrentObject = (AFSObjectInfoCB *)pCurrentObject->ListEntry.fLink;
3181 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
3183 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
3188 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
3196 AFSSetNetworkState( IN AFSNetworkStatusCB *NetworkStatus)
3199 NTSTATUS ntStatus = STATUS_SUCCESS;
3204 if( AFSGlobalRoot == NULL)
3207 try_return( ntStatus);
3210 AFSAcquireExcl( AFSGlobalRoot->VolumeLock,
3214 // Set the network state according to the information
3217 if( NetworkStatus->Online)
3220 ClearFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3225 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_FLAGS_OFFLINE);
3228 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
3239 AFSValidateDirectoryCache( IN AFSObjectInfoCB *ObjectInfo,
3243 NTSTATUS ntStatus = STATUS_SUCCESS;
3244 BOOLEAN bAcquiredLock = FALSE;
3245 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
3246 AFSFcb *pFcb = NULL;
3251 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3252 AFS_TRACE_LEVEL_VERBOSE,
3253 "AFSValidateDirectoryCache Validating content for FID %08lX-%08lX-%08lX-%08lX\n",
3254 ObjectInfo->FileId.Cell,
3255 ObjectInfo->FileId.Volume,
3256 ObjectInfo->FileId.Vnode,
3257 ObjectInfo->FileId.Unique);
3259 if( !ExIsResourceAcquiredLite( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock))
3262 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3263 AFS_TRACE_LEVEL_VERBOSE,
3264 "AFSValidateDirectoryCache Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
3265 ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3266 PsGetCurrentThread());
3268 AFSAcquireExcl( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
3271 bAcquiredLock = TRUE;
3275 // Check for inconsistency between DirectoryNodeList and DirectoryNodeCount
3278 if ( ObjectInfo->Specific.Directory.DirectoryNodeListHead == NULL &&
3279 ObjectInfo->Specific.Directory.DirectoryNodeCount > 0)
3282 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3283 AFS_TRACE_LEVEL_ERROR,
3284 "AFSValidateDirectoryCache Empty Node List but Non-Zero Node Count %08lX for dir FID %08lX-%08lX-%08lX-%08lX\n",
3285 ObjectInfo->Specific.Directory.DirectoryNodeCount,
3286 ObjectInfo->FileId.Cell,
3287 ObjectInfo->FileId.Volume,
3288 ObjectInfo->FileId.Vnode,
3289 ObjectInfo->FileId.Unique);
3293 // Reset the directory list information by clearing all valid entries
3296 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3298 while( pCurrentDirEntry != NULL)
3301 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3303 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3307 // If this entry has been deleted then process it here
3310 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
3311 pCurrentDirEntry->OpenReferenceCount == 0)
3314 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3315 AFS_TRACE_LEVEL_VERBOSE,
3316 "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
3318 &pCurrentDirEntry->NameInformation.FileName);
3320 AFSDeleteDirEntry( ObjectInfo,
3326 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
3328 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3329 AFS_TRACE_LEVEL_VERBOSE,
3330 "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
3332 pCurrentDirEntry->OpenReferenceCount);
3335 // We pull the short name from the parent tree since it could change below
3338 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
3341 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3342 AFS_TRACE_LEVEL_VERBOSE,
3343 "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
3345 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3346 &pCurrentDirEntry->NameInformation.FileName);
3348 AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
3351 ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3356 pCurrentDirEntry = pNextDirEntry;
3360 // Reget the directory contents
3363 ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
3366 if ( !NT_SUCCESS( ntStatus))
3368 try_return( ntStatus);
3372 // Now start again and tear down any entries not valid
3375 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
3377 while( pCurrentDirEntry != NULL)
3380 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
3382 if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
3385 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
3386 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
3389 if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
3392 ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
3394 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3395 AFS_TRACE_LEVEL_VERBOSE,
3396 "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
3398 &pCurrentDirEntry->NameInformation.FileName);
3400 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3405 if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
3408 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3409 AFS_TRACE_LEVEL_VERBOSE,
3410 "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
3412 pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
3413 &pCurrentDirEntry->NameInformation.FileName);
3417 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
3419 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3420 AFS_TRACE_LEVEL_VERBOSE,
3421 "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
3423 &pCurrentDirEntry->NameInformation.FileName);
3428 pCurrentDirEntry = pNextDirEntry;
3433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3434 AFS_TRACE_LEVEL_VERBOSE,
3435 "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
3437 pCurrentDirEntry->OpenReferenceCount);
3439 if( pCurrentDirEntry->OpenReferenceCount == 0)
3442 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3443 AFS_TRACE_LEVEL_VERBOSE,
3444 "AFSValidateDirectoryCache Deleting dir entry %wZ from parent FID %08lX-%08lX-%08lX-%08lX\n",
3445 &pCurrentDirEntry->NameInformation.FileName,
3446 ObjectInfo->FileId.Cell,
3447 ObjectInfo->FileId.Volume,
3448 ObjectInfo->FileId.Vnode,
3449 ObjectInfo->FileId.Unique);
3451 AFSDeleteDirEntry( ObjectInfo,
3457 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3458 AFS_TRACE_LEVEL_VERBOSE,
3459 "AFSValidateDirectoryCache Setting dir entry %p Name %wZ DELETED in parent FID %08lX-%08lX-%08lX-%08lX\n",
3461 &pCurrentDirEntry->NameInformation.FileName,
3462 ObjectInfo->FileId.Cell,
3463 ObjectInfo->FileId.Volume,
3464 ObjectInfo->FileId.Vnode,
3465 ObjectInfo->FileId.Unique);
3467 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
3469 AFSRemoveNameEntry( ObjectInfo,
3473 pCurrentDirEntry = pNextDirEntry;
3477 if( !AFSValidateDirList( ObjectInfo))
3480 AFSPrint("AFSValidateDirectoryCache Invalid count ...\n");
3489 AFSReleaseResource( ObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
3497 AFSIsVolumeFID( IN AFSFileID *FileID)
3500 BOOLEAN bIsVolume = FALSE;
3502 if( FileID->Vnode == 1 &&
3503 FileID->Unique == 1)
3513 AFSIsFinalNode( IN AFSFcb *Fcb)
3516 BOOLEAN bIsFinalNode = FALSE;
3518 if( Fcb->Header.NodeTypeCode == AFS_ROOT_FCB ||
3519 Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3520 Fcb->Header.NodeTypeCode == AFS_FILE_FCB ||
3521 Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3522 Fcb->Header.NodeTypeCode == AFS_INVALID_FCB )
3525 bIsFinalNode = TRUE;
3530 ASSERT( Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3531 Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB);
3534 return bIsFinalNode;
3538 AFSUpdateMetaData( IN AFSDirectoryCB *DirEntry,
3539 IN AFSDirEnumEntry *DirEnumEntry)
3542 NTSTATUS ntStatus = STATUS_SUCCESS;
3543 UNICODE_STRING uniTargetName;
3544 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3549 pObjectInfo->TargetFileId = DirEnumEntry->TargetFileId;
3551 pObjectInfo->Expiration = DirEnumEntry->Expiration;
3553 pObjectInfo->DataVersion = DirEnumEntry->DataVersion;
3555 pObjectInfo->FileType = DirEnumEntry->FileType;
3557 pObjectInfo->CreationTime = DirEnumEntry->CreationTime;
3559 pObjectInfo->LastAccessTime = DirEnumEntry->LastAccessTime;
3561 pObjectInfo->LastWriteTime = DirEnumEntry->LastWriteTime;
3563 pObjectInfo->ChangeTime = DirEnumEntry->ChangeTime;
3565 pObjectInfo->EndOfFile = DirEnumEntry->EndOfFile;
3567 pObjectInfo->AllocationSize = DirEnumEntry->AllocationSize;
3569 pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
3571 if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
3574 pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
3577 if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
3578 pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
3581 pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
3584 pObjectInfo->EaSize = DirEnumEntry->EaSize;
3586 pObjectInfo->Links = DirEnumEntry->Links;
3588 if( DirEnumEntry->TargetNameLength > 0)
3592 // Update the target name information if needed
3595 uniTargetName.Length = (USHORT)DirEnumEntry->TargetNameLength;
3597 uniTargetName.MaximumLength = uniTargetName.Length;
3599 uniTargetName.Buffer = (WCHAR *)((char *)DirEnumEntry + DirEnumEntry->TargetNameOffset);
3601 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3604 if( DirEntry->NameInformation.TargetName.Length == 0 ||
3605 RtlCompareUnicodeString( &uniTargetName,
3606 &DirEntry->NameInformation.TargetName,
3611 // Update the target name
3614 ntStatus = AFSUpdateTargetName( &DirEntry->NameInformation.TargetName,
3616 uniTargetName.Buffer,
3617 uniTargetName.Length);
3619 if( !NT_SUCCESS( ntStatus))
3622 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3624 try_return( ntStatus);
3628 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3630 else if( DirEntry->NameInformation.TargetName.Length > 0)
3633 AFSAcquireExcl( &DirEntry->NonPaged->Lock,
3636 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER) &&
3637 DirEntry->NameInformation.TargetName.Buffer != NULL)
3639 AFSExFreePool( DirEntry->NameInformation.TargetName.Buffer);
3642 ClearFlag( DirEntry->Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
3644 DirEntry->NameInformation.TargetName.Length = 0;
3645 DirEntry->NameInformation.TargetName.MaximumLength = 0;
3646 DirEntry->NameInformation.TargetName.Buffer = NULL;
3648 AFSReleaseResource( &DirEntry->NonPaged->Lock);
3660 AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
3662 IN BOOLEAN PurgeContent,
3663 IN BOOLEAN FastCall)
3666 NTSTATUS ntStatus = STATUS_SUCCESS;
3667 LARGE_INTEGER liSystemTime;
3668 AFSDirEnumEntry *pDirEnumEntry = NULL;
3669 AFSFcb *pCurrentFcb = NULL;
3670 BOOLEAN bReleaseFcb = FALSE;
3671 AFSObjectInfoCB *pObjectInfo = DirEntry->ObjectInformation;
3677 // If we have an Fcb hanging off the directory entry then be sure to acquire the locks in the
3681 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3682 AFS_TRACE_LEVEL_VERBOSE_2,
3683 "AFSValidateEntry Validating entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3684 &DirEntry->NameInformation.FileName,
3685 pObjectInfo->FileId.Cell,
3686 pObjectInfo->FileId.Volume,
3687 pObjectInfo->FileId.Vnode,
3688 pObjectInfo->FileId.Unique);
3691 // If this is a fake node then bail since the service knows nothing about it
3694 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_FAKE))
3697 try_return( ntStatus);
3701 pObjectInfo->Fcb != NULL)
3704 pCurrentFcb = pObjectInfo->Fcb;
3706 if( !ExIsResourceAcquiredLite( &pCurrentFcb->NPFcb->Resource))
3709 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3710 AFS_TRACE_LEVEL_VERBOSE,
3711 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3712 &pCurrentFcb->NPFcb->Resource,
3713 PsGetCurrentThread());
3715 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3723 // This routine ensures that the current entry is valid by:
3725 // 1) Checking that the expiration time is non-zero and after where we
3729 KeQuerySystemTime( &liSystemTime);
3731 if( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) &&
3732 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY) &&
3733 !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA) &&
3734 pObjectInfo->Expiration.QuadPart >= liSystemTime.QuadPart)
3737 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3738 AFS_TRACE_LEVEL_VERBOSE_2,
3739 "AFSValidateEntry Directory entry %wZ FID %08lX-%08lX-%08lX-%08lX VALID\n",
3740 &DirEntry->NameInformation.FileName,
3741 pObjectInfo->FileId.Cell,
3742 pObjectInfo->FileId.Volume,
3743 pObjectInfo->FileId.Vnode,
3744 pObjectInfo->FileId.Unique);
3746 try_return( ntStatus);
3750 // This node requires updating
3753 ntStatus = AFSEvaluateTargetByID( pObjectInfo,
3758 if( !NT_SUCCESS( ntStatus))
3761 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3762 AFS_TRACE_LEVEL_ERROR,
3763 "AFSValidateEntry Failed to evaluate entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
3765 &DirEntry->NameInformation.FileName,
3766 pObjectInfo->FileId.Cell,
3767 pObjectInfo->FileId.Volume,
3768 pObjectInfo->FileId.Vnode,
3769 pObjectInfo->FileId.Unique,
3773 // Failed validation of node so return access-denied
3776 try_return( ntStatus);
3779 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3780 AFS_TRACE_LEVEL_VERBOSE,
3781 "AFSValidateEntry Validating entry FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX DV %I64X returned DV %I64X FT %d\n",
3783 &DirEntry->NameInformation.FileName,
3784 pObjectInfo->FileId.Cell,
3785 pObjectInfo->FileId.Volume,
3786 pObjectInfo->FileId.Vnode,
3787 pObjectInfo->FileId.Unique,
3788 pObjectInfo->DataVersion.QuadPart,
3789 pDirEnumEntry->DataVersion.QuadPart,
3790 pDirEnumEntry->FileType);
3794 // Based on the file type, process the node
3797 switch( pDirEnumEntry->FileType)
3800 case AFS_FILE_TYPE_MOUNTPOINT:
3804 // Update the metadata for the entry
3807 ntStatus = AFSUpdateMetaData( DirEntry,
3810 if( NT_SUCCESS( ntStatus))
3813 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3819 case AFS_FILE_TYPE_SYMLINK:
3820 case AFS_FILE_TYPE_DFSLINK:
3824 // Update the metadata for the entry
3827 ntStatus = AFSUpdateMetaData( DirEntry,
3830 if( NT_SUCCESS( ntStatus))
3833 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3839 case AFS_FILE_TYPE_FILE:
3843 // For a file where the data version has become invalid we need to
3844 // fail any current extent requests and purge the cache for the file
3845 // Can't hold the Fcb resource while doing this
3848 if( pCurrentFcb != NULL &&
3849 (pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart ||
3850 BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA)))
3853 IO_STATUS_BLOCK stIoStatus;
3854 BOOLEAN bPurgeExtents = FALSE;
3856 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3857 AFS_TRACE_LEVEL_VERBOSE_2,
3858 "AFSValidateEntry Flush/purge entry %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3859 &DirEntry->NameInformation.FileName,
3860 pObjectInfo->FileId.Cell,
3861 pObjectInfo->FileId.Volume,
3862 pObjectInfo->FileId.Vnode,
3863 pObjectInfo->FileId.Unique);
3865 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA))
3867 bPurgeExtents = TRUE;
3869 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3870 AFS_TRACE_LEVEL_VERBOSE,
3871 "AFSVerifyEntry Clearing VERIFY_DATA flag %wZ FID %08lX-%08lX-%08lX-%08lX\n",
3872 &DirEntry->NameInformation.FileName,
3873 pObjectInfo->FileId.Cell,
3874 pObjectInfo->FileId.Volume,
3875 pObjectInfo->FileId.Vnode,
3876 pObjectInfo->FileId.Unique);
3878 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
3884 CcFlushCache( &pCurrentFcb->NPFcb->SectionObjectPointers,
3889 if( !NT_SUCCESS( stIoStatus.Status))
3892 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3893 AFS_TRACE_LEVEL_ERROR,
3894 "AFSValidateEntry CcFlushCache failure %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
3895 &DirEntry->NameInformation.FileName,
3896 pObjectInfo->FileId.Cell,
3897 pObjectInfo->FileId.Volume,
3898 pObjectInfo->FileId.Vnode,
3899 pObjectInfo->FileId.Unique,
3901 stIoStatus.Information);
3903 ntStatus = stIoStatus.Status;
3909 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3915 __except( EXCEPTION_EXECUTE_HANDLER)
3917 ntStatus = GetExceptionCode();
3919 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
3920 AFS_TRACE_LEVEL_ERROR,
3921 "AFSValidateEntry CcFlushCache or CcPurgeCacheSection exception %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3922 &DirEntry->NameInformation.FileName,
3923 pObjectInfo->FileId.Cell,
3924 pObjectInfo->FileId.Volume,
3925 pObjectInfo->FileId.Vnode,
3926 pObjectInfo->FileId.Unique,
3931 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
3935 AFSFlushExtents( pCurrentFcb,
3940 // Reacquire the Fcb to purge the cache
3943 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3944 AFS_TRACE_LEVEL_VERBOSE,
3945 "AFSValidateEntry Acquiring Fcb lock %08lX EXCL %08lX\n",
3946 &pCurrentFcb->NPFcb->Resource,
3947 PsGetCurrentThread());
3949 AFSAcquireExcl( &pCurrentFcb->NPFcb->Resource,
3954 // Update the metadata for the entry
3957 ntStatus = AFSUpdateMetaData( DirEntry,
3960 if( !NT_SUCCESS( ntStatus))
3963 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3964 AFS_TRACE_LEVEL_ERROR,
3965 "AFSValidateEntry Meta Data Update failed %wZ FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3966 &DirEntry->NameInformation.FileName,
3967 pObjectInfo->FileId.Cell,
3968 pObjectInfo->FileId.Volume,
3969 pObjectInfo->FileId.Vnode,
3970 pObjectInfo->FileId.Unique,
3976 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
3979 // Update file sizes
3982 if( pObjectInfo->Fcb != NULL)
3984 FILE_OBJECT *pCCFileObject = CcGetFileObjectFromSectionPtrs( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers);
3986 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
3987 pObjectInfo->Fcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3988 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
3990 if ( pCCFileObject != NULL)
3992 CcSetFileSizes( pCCFileObject,
3993 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
4000 case AFS_FILE_TYPE_DIRECTORY:
4003 AFSDirectoryCB *pCurrentDirEntry = NULL;
4005 if( pCurrentFcb != NULL &&
4006 pObjectInfo->DataVersion.QuadPart != pDirEnumEntry->DataVersion.QuadPart)
4010 // For a directory or root entry flush the content of
4011 // the directory enumeration.
4014 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4015 AFS_TRACE_LEVEL_VERBOSE,
4016 "AFSValidateEntry Acquiring DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4017 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4018 PsGetCurrentThread());
4020 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4023 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4024 AFS_TRACE_LEVEL_VERBOSE_2,
4025 "AFSValidateEntry Validating directory content for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4026 &DirEntry->NameInformation.FileName,
4027 pObjectInfo->FileId.Cell,
4028 pObjectInfo->FileId.Volume,
4029 pObjectInfo->FileId.Vnode,
4030 pObjectInfo->FileId.Unique);
4032 AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
4035 AFSValidateDirectoryCache( pCurrentFcb->ObjectInformation,
4038 AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
4041 if( !NT_SUCCESS( ntStatus))
4044 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4045 AFS_TRACE_LEVEL_ERROR,
4046 "AFSValidateEntry Failed to re-enumerate %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
4047 &DirEntry->NameInformation.FileName,
4048 pObjectInfo->FileId.Cell,
4049 pObjectInfo->FileId.Volume,
4050 pObjectInfo->FileId.Vnode,
4051 pObjectInfo->FileId.Unique,
4059 // Update the metadata for the entry
4062 ntStatus = AFSUpdateMetaData( DirEntry,
4065 if( NT_SUCCESS( ntStatus))
4068 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY | AFS_OBJECT_FLAGS_NOT_EVALUATED);
4076 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4077 AFS_TRACE_LEVEL_WARNING,
4078 "AFSValidateEntry Attempt to verify node of type %d FastCall %d %wZ FID %08lX-%08lX-%08lX-%08lX\n",
4079 pObjectInfo->FileType,
4081 &DirEntry->NameInformation.FileName,
4082 pObjectInfo->FileId.Cell,
4083 pObjectInfo->FileId.Volume,
4084 pObjectInfo->FileId.Vnode,
4085 pObjectInfo->FileId.Unique);
4095 AFSReleaseResource( &pCurrentFcb->NPFcb->Resource);
4098 if( pDirEnumEntry != NULL)
4101 AFSExFreePool( pDirEnumEntry);
4109 AFSInitializeSpecialShareNameList()
4112 NTSTATUS ntStatus = STATUS_SUCCESS;
4113 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
4114 AFSObjectInfoCB *pObjectInfoCB = NULL;
4115 UNICODE_STRING uniShareName;
4116 ULONG ulEntryLength = 0;
4117 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
4122 RtlInitUnicodeString( &uniShareName,
4125 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4128 if( pObjectInfoCB == NULL)
4131 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4134 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4135 AFS_TRACE_LEVEL_VERBOSE,
4136 "AFSInitializeSpecialShareNameList (srvsvc) Initializing count (1) on object %08lX\n",
4139 pObjectInfoCB->ObjectReferenceCount = 1;
4141 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4143 ulEntryLength = sizeof( AFSDirectoryCB) +
4144 uniShareName.Length;
4146 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4150 if( pDirNode == NULL)
4153 AFSDeleteObjectInfo( pObjectInfoCB);
4155 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4158 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4159 sizeof( AFSNonPagedDirectoryCB),
4160 AFS_DIR_ENTRY_NP_TAG);
4162 if( pNonPagedDirEntry == NULL)
4165 ExFreePool( pDirNode);
4167 AFSDeleteObjectInfo( pObjectInfoCB);
4169 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4172 RtlZeroMemory( pDirNode,
4175 RtlZeroMemory( pNonPagedDirEntry,
4176 sizeof( AFSNonPagedDirectoryCB));
4178 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4180 pDirNode->NonPaged = pNonPagedDirEntry;
4182 pDirNode->ObjectInformation = pObjectInfoCB;
4188 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_SERVER_SERVICE);
4190 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4192 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4194 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4196 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4197 uniShareName.Buffer,
4198 pDirNode->NameInformation.FileName.Length);
4200 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4203 AFSSpecialShareNames = pDirNode;
4205 pLastDirNode = pDirNode;
4207 RtlInitUnicodeString( &uniShareName,
4210 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4213 if( pObjectInfoCB == NULL)
4216 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4219 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4220 AFS_TRACE_LEVEL_VERBOSE,
4221 "AFSInitializeSpecialShareNameList (wkssvc) Initializing count (1) on object %08lX\n",
4224 pObjectInfoCB->ObjectReferenceCount = 1;
4226 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4228 ulEntryLength = sizeof( AFSDirectoryCB) +
4229 uniShareName.Length;
4231 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4235 if( pDirNode == NULL)
4238 AFSDeleteObjectInfo( pObjectInfoCB);
4240 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4243 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4244 sizeof( AFSNonPagedDirectoryCB),
4245 AFS_DIR_ENTRY_NP_TAG);
4247 if( pNonPagedDirEntry == NULL)
4250 ExFreePool( pDirNode);
4252 AFSDeleteObjectInfo( pObjectInfoCB);
4254 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4257 RtlZeroMemory( pDirNode,
4260 RtlZeroMemory( pNonPagedDirEntry,
4261 sizeof( AFSNonPagedDirectoryCB));
4263 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4265 pDirNode->NonPaged = pNonPagedDirEntry;
4267 pDirNode->ObjectInformation = pObjectInfoCB;
4273 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_WORKSTATION_SERVICE);
4275 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4277 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4279 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4281 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4282 uniShareName.Buffer,
4283 pDirNode->NameInformation.FileName.Length);
4285 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4288 pLastDirNode->ListEntry.fLink = pDirNode;
4290 pDirNode->ListEntry.bLink = pLastDirNode;
4292 pLastDirNode = pDirNode;
4294 RtlInitUnicodeString( &uniShareName,
4297 pObjectInfoCB = AFSAllocateObjectInfo( &AFSGlobalRoot->ObjectInformation,
4300 if( pObjectInfoCB == NULL)
4303 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4306 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4307 AFS_TRACE_LEVEL_VERBOSE,
4308 "AFSInitializeSpecialShareNameList (ipc$) Initializing count (1) on object %08lX\n",
4311 pObjectInfoCB->ObjectReferenceCount = 1;
4313 pObjectInfoCB->FileType = AFS_FILE_TYPE_SPECIAL_SHARE_NAME;
4315 ulEntryLength = sizeof( AFSDirectoryCB) +
4316 uniShareName.Length;
4318 pDirNode = (AFSDirectoryCB *)AFSLibExAllocatePoolWithTag( PagedPool,
4322 if( pDirNode == NULL)
4325 AFSDeleteObjectInfo( pObjectInfoCB);
4327 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4330 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSLibExAllocatePoolWithTag( NonPagedPool,
4331 sizeof( AFSNonPagedDirectoryCB),
4332 AFS_DIR_ENTRY_NP_TAG);
4334 if( pNonPagedDirEntry == NULL)
4337 ExFreePool( pDirNode);
4339 AFSDeleteObjectInfo( pObjectInfoCB);
4341 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4344 RtlZeroMemory( pDirNode,
4347 RtlZeroMemory( pNonPagedDirEntry,
4348 sizeof( AFSNonPagedDirectoryCB));
4350 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
4352 pDirNode->NonPaged = pNonPagedDirEntry;
4354 pDirNode->ObjectInformation = pObjectInfoCB;
4360 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_IPC);
4362 pDirNode->NameInformation.FileName.Length = uniShareName.Length;
4364 pDirNode->NameInformation.FileName.MaximumLength = uniShareName.Length;
4366 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
4368 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
4369 uniShareName.Buffer,
4370 pDirNode->NameInformation.FileName.Length);
4372 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
4375 pLastDirNode->ListEntry.fLink = pDirNode;
4377 pDirNode->ListEntry.bLink = pLastDirNode;
4381 if( !NT_SUCCESS( ntStatus))
4384 if( AFSSpecialShareNames != NULL)
4387 pDirNode = AFSSpecialShareNames;
4389 while( pDirNode != NULL)
4392 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
4394 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
4396 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
4398 ExFreePool( pDirNode->NonPaged);
4400 ExFreePool( pDirNode);
4402 pDirNode = pLastDirNode;
4405 AFSSpecialShareNames = NULL;
4414 AFSGetSpecialShareNameEntry( IN UNICODE_STRING *ShareName,
4415 IN UNICODE_STRING *SecondaryName)
4418 AFSDirectoryCB *pDirectoryCB = NULL;
4419 ULONGLONG ullHash = 0;
4420 UNICODE_STRING uniFullShareName;
4426 // Build up the entire name here. We are guaranteed that if there is a
4427 // secondary name, it is pointing to a portion of the share name buffer
4430 if( SecondaryName->Length > 0 &&
4431 SecondaryName->Buffer != NULL)
4434 uniFullShareName = *SecondaryName;
4437 // The calling routine strips off the leading slash so add it back in
4440 uniFullShareName.Buffer--;
4441 uniFullShareName.Length += sizeof( WCHAR);
4442 uniFullShareName.MaximumLength += sizeof( WCHAR);
4445 // And the share name
4448 uniFullShareName.Buffer -= (ShareName->Length/sizeof( WCHAR));
4449 uniFullShareName.Length += ShareName->Length;
4450 uniFullShareName.MaximumLength += ShareName->Length;
4455 uniFullShareName = *ShareName;
4459 // Generate our hash value
4462 ullHash = AFSGenerateCRC( &uniFullShareName,
4466 // Loop through our special share names to see if this is one of them
4469 pDirectoryCB = AFSSpecialShareNames;
4471 while( pDirectoryCB != NULL)
4474 if( ullHash == pDirectoryCB->CaseInsensitiveTreeEntry.HashIndex)
4480 pDirectoryCB = (AFSDirectoryCB *)pDirectoryCB->ListEntry.fLink;
4484 return pDirectoryCB;
4488 AFSWaitOnQueuedFlushes( IN AFSFcb *Fcb)
4492 // Block on the queue flush event
4495 KeWaitForSingleObject( &Fcb->NPFcb->Specific.File.QueuedFlushEvent,
4505 AFSWaitOnQueuedReleases()
4508 AFSDeviceExt *pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
4511 // Block on the queue flush event
4514 KeWaitForSingleObject( &pRDRDeviceExt->Specific.RDR.QueuedReleaseExtentEvent,
4524 AFSIsEqualFID( IN AFSFileID *FileId1,
4525 IN AFSFileID *FileId2)
4528 BOOLEAN bIsEqual = FALSE;
4530 if( FileId1->Unique == FileId2->Unique &&
4531 FileId1->Vnode == FileId2->Vnode &&
4532 FileId1->Volume == FileId2->Volume &&
4533 FileId1->Cell == FileId2->Cell)
4543 AFSResetDirectoryContent( IN AFSObjectInfoCB *ObjectInfoCB)
4546 NTSTATUS ntStatus = STATUS_SUCCESS;
4547 AFSDirectoryCB *pCurrentDirEntry = NULL, *pNextDirEntry = NULL;
4552 ASSERT( ExIsResourceAcquiredExclusiveLite( ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.TreeLock));
4555 // Reset the directory list information
4558 pCurrentDirEntry = ObjectInfoCB->Specific.Directory.DirectoryNodeListHead;
4560 while( pCurrentDirEntry != NULL)
4563 pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
4565 if( pCurrentDirEntry->OpenReferenceCount == 0)
4568 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4569 AFS_TRACE_LEVEL_VERBOSE,
4570 "AFSResetDirectoryContent Deleting dir entry %p for %wZ\n",
4572 &pCurrentDirEntry->NameInformation.FileName);
4574 AFSDeleteDirEntry( ObjectInfoCB,
4580 AFSDbgLogMsg( AFS_SUBSYSTEM_CLEANUP_PROCESSING,
4581 AFS_TRACE_LEVEL_VERBOSE,
4582 "AFSResetDirectoryContent Setting DELETE flag in dir entry %p for %wZ\n",
4584 &pCurrentDirEntry->NameInformation.FileName);
4586 SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
4588 AFSRemoveNameEntry( ObjectInfoCB,
4592 pCurrentDirEntry = pNextDirEntry;
4595 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead = NULL;
4597 ObjectInfoCB->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead = NULL;
4599 ObjectInfoCB->Specific.Directory.ShortNameTree = NULL;
4601 ObjectInfoCB->Specific.Directory.DirectoryNodeListHead = NULL;
4603 ObjectInfoCB->Specific.Directory.DirectoryNodeListTail = NULL;
4605 ObjectInfoCB->Specific.Directory.DirectoryNodeCount = 0;
4607 AFSDbgLogMsg( AFS_SUBSYSTEM_DIR_NODE_COUNT,
4608 AFS_TRACE_LEVEL_VERBOSE,
4609 "AFSResetDirectoryContent Reset count to 0 on parent FID %08lX-%08lX-%08lX-%08lX\n",
4610 ObjectInfoCB->FileId.Cell,
4611 ObjectInfoCB->FileId.Volume,
4612 ObjectInfoCB->FileId.Vnode,
4613 ObjectInfoCB->FileId.Unique);
4620 AFSEnumerateGlobalRoot( IN GUID *AuthGroup)
4623 NTSTATUS ntStatus = STATUS_SUCCESS;
4624 AFSDirectoryCB *pDirGlobalDirNode = NULL;
4625 UNICODE_STRING uniFullName;
4630 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
4631 AFS_TRACE_LEVEL_VERBOSE,
4632 "AFSEnumerateGlobalRoot Acquiring GlobalRoot DirectoryNodeHdr.TreeLock lock %08lX EXCL %08lX\n",
4633 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4634 PsGetCurrentThread());
4636 AFSAcquireExcl( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
4639 if( BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
4642 try_return( ntStatus);
4646 // Initialize the root information
4649 AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.ContentIndex = 1;
4652 // Enumerate the shares in the volume
4655 ntStatus = AFSEnumerateDirectory( AuthGroup,
4656 &AFSGlobalRoot->ObjectInformation,
4659 if( !NT_SUCCESS( ntStatus))
4662 try_return( ntStatus);
4665 pDirGlobalDirNode = AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeListHead;
4668 // Indicate the node is initialized
4671 SetFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4673 uniFullName.MaximumLength = PAGE_SIZE;
4674 uniFullName.Length = 0;
4676 uniFullName.Buffer = (WCHAR *)AFSLibExAllocatePoolWithTag( PagedPool,
4677 uniFullName.MaximumLength,
4678 AFS_GENERIC_MEMORY_12_TAG);
4680 if( uniFullName.Buffer == NULL)
4684 // Reset the directory content
4687 AFSResetDirectoryContent( &AFSGlobalRoot->ObjectInformation);
4689 ClearFlag( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
4691 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4695 // Populate our list of entries in the NP enumeration list
4698 while( pDirGlobalDirNode != NULL)
4701 uniFullName.Buffer[ 0] = L'\\';
4702 uniFullName.Buffer[ 1] = L'\\';
4704 uniFullName.Length = 2 * sizeof( WCHAR);
4706 RtlCopyMemory( &uniFullName.Buffer[ 2],
4707 AFSServerName.Buffer,
4708 AFSServerName.Length);
4710 uniFullName.Length += AFSServerName.Length;
4712 uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
4714 uniFullName.Length += sizeof( WCHAR);
4716 RtlCopyMemory( &uniFullName.Buffer[ uniFullName.Length/sizeof( WCHAR)],
4717 pDirGlobalDirNode->NameInformation.FileName.Buffer,
4718 pDirGlobalDirNode->NameInformation.FileName.Length);
4720 uniFullName.Length += pDirGlobalDirNode->NameInformation.FileName.Length;
4722 AFSAddConnectionEx( &uniFullName,
4723 RESOURCEDISPLAYTYPE_SHARE,
4726 pDirGlobalDirNode = (AFSDirectoryCB *)pDirGlobalDirNode->ListEntry.fLink;
4729 AFSExFreePool( uniFullName.Buffer);
4733 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
4740 AFSIsRelativeName( IN UNICODE_STRING *Name)
4743 BOOLEAN bIsRelative = FALSE;
4745 if( Name->Buffer[ 0] != L'\\')
4755 AFSUpdateName( IN UNICODE_STRING *Name)
4760 while( usIndex < Name->Length/sizeof( WCHAR))
4763 if( Name->Buffer[ usIndex] == L'/')
4766 Name->Buffer[ usIndex] = L'\\';
4776 AFSUpdateTargetName( IN OUT UNICODE_STRING *TargetName,
4777 IN OUT ULONG *Flags,
4778 IN WCHAR *NameBuffer,
4779 IN USHORT NameLength)
4782 NTSTATUS ntStatus = STATUS_SUCCESS;
4783 WCHAR *pTmpBuffer = NULL;
4789 // If we have enough space then just move in the name otherwise
4790 // allocate a new buffer
4793 if( TargetName->Length < NameLength)
4796 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
4798 AFS_NAME_BUFFER_FIVE_TAG);
4800 if( pTmpBuffer == NULL)
4803 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
4806 if( BooleanFlagOn( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER))
4809 AFSExFreePool( TargetName->Buffer);
4812 TargetName->MaximumLength = NameLength;
4814 TargetName->Buffer = pTmpBuffer;
4816 SetFlag( *Flags, AFS_DIR_RELEASE_TARGET_NAME_BUFFER);
4819 TargetName->Length = NameLength;
4821 RtlCopyMemory( TargetName->Buffer,
4823 TargetName->Length);
4826 // Update the name in the buffer
4829 AFSUpdateName( TargetName);
4840 AFSInitNameArray( IN AFSDirectoryCB *DirectoryCB,
4841 IN ULONG InitialElementCount)
4844 AFSNameArrayHdr *pNameArray = NULL;
4845 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
4851 if( InitialElementCount == 0)
4854 InitialElementCount = pDevExt->Specific.RDR.NameArrayLength;
4857 pNameArray = (AFSNameArrayHdr *)AFSExAllocatePoolWithTag( PagedPool,
4858 sizeof( AFSNameArrayHdr) +
4859 (InitialElementCount * sizeof( AFSNameArrayCB)),
4860 AFS_NAME_ARRAY_TAG);
4862 if( pNameArray == NULL)
4865 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
4866 AFS_TRACE_LEVEL_ERROR,
4867 "AFSInitNameArray Failed to allocate name array\n");
4869 try_return( pNameArray);
4872 RtlZeroMemory( pNameArray,
4873 sizeof( AFSNameArrayHdr) +
4874 (InitialElementCount * sizeof( AFSNameArrayCB)));
4876 pNameArray->MaxElementCount = InitialElementCount;
4878 if( DirectoryCB != NULL)
4881 pNameArray->CurrentEntry = &pNameArray->ElementArray[ 0];
4883 lCount = InterlockedIncrement( &pNameArray->Count);
4885 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
4887 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4888 AFS_TRACE_LEVEL_VERBOSE,
4889 "AFSInitNameArray Increment count on %wZ DE %p Cnt %d\n",
4890 &DirectoryCB->NameInformation.FileName,
4894 pNameArray->CurrentEntry->DirectoryCB = DirectoryCB;
4896 pNameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
4898 pNameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
4910 AFSPopulateNameArray( IN AFSNameArrayHdr *NameArray,
4911 IN UNICODE_STRING *Path,
4912 IN AFSDirectoryCB *DirectoryCB)
4915 NTSTATUS ntStatus = STATUS_SUCCESS;
4916 AFSNameArrayCB *pCurrentElement = NULL;
4917 UNICODE_STRING uniComponentName, uniRemainingPath;
4918 AFSObjectInfoCB *pCurrentObject = NULL;
4919 ULONG ulTotalCount = 0;
4921 USHORT usLength = 0;
4928 // Init some info in the header
4931 pCurrentElement = &NameArray->ElementArray[ 0];
4933 NameArray->CurrentEntry = pCurrentElement;
4936 // The first entry points at the root
4939 pCurrentElement->DirectoryCB = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB;
4941 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
4943 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
4944 AFS_TRACE_LEVEL_VERBOSE,
4945 "AFSPopulateNameArray Increment count on volume %wZ DE %p Cnt %d\n",
4946 &pCurrentElement->DirectoryCB->NameInformation.FileName,
4947 pCurrentElement->DirectoryCB,
4950 pCurrentElement->Component = DirectoryCB->ObjectInformation->VolumeCB->DirectoryCB->NameInformation.FileName;
4952 pCurrentElement->FileId = DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation.FileId;
4954 NameArray->Count = 1;
4956 NameArray->LinkCount = 0;
4959 // If the root is the parent then we are done ...
4962 if( &DirectoryCB->ObjectInformation->VolumeCB->ObjectInformation == DirectoryCB->ObjectInformation)
4964 try_return( ntStatus);
4976 AFSPopulateNameArrayFromRelatedArray( IN AFSNameArrayHdr *NameArray,
4977 IN AFSNameArrayHdr *RelatedNameArray,
4978 IN AFSDirectoryCB *DirectoryCB)
4981 NTSTATUS ntStatus = STATUS_SUCCESS;
4982 AFSNameArrayCB *pCurrentElement = NULL, *pCurrentRelatedElement = NULL;
4983 UNICODE_STRING uniComponentName, uniRemainingPath;
4984 AFSObjectInfoCB *pObjectInfo = NULL;
4985 ULONG ulTotalCount = 0;
4987 USHORT usLength = 0;
4994 // Init some info in the header
4997 pCurrentElement = &NameArray->ElementArray[ 0];
4999 pCurrentRelatedElement = &RelatedNameArray->ElementArray[ 0];
5001 NameArray->Count = 0;
5003 NameArray->LinkCount = RelatedNameArray->LinkCount;
5006 // Populate the name array with the data from the related array
5012 pCurrentElement->DirectoryCB = pCurrentRelatedElement->DirectoryCB;
5014 pCurrentElement->Component = pCurrentRelatedElement->DirectoryCB->NameInformation.FileName;
5016 pCurrentElement->FileId = pCurrentElement->DirectoryCB->ObjectInformation->FileId;
5018 lCount = InterlockedIncrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5020 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5021 AFS_TRACE_LEVEL_VERBOSE,
5022 "AFSPopulateNameArrayFromRelatedArray Increment count on %wZ DE %p Cnt %d\n",
5023 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5024 pCurrentElement->DirectoryCB,
5027 lCount = InterlockedIncrement( &NameArray->Count);
5029 if( pCurrentElement->DirectoryCB == DirectoryCB ||
5030 NameArray->Count == RelatedNameArray->Count)
5042 pCurrentRelatedElement++;
5045 if( NameArray->Count > 0)
5047 NameArray->CurrentEntry = pCurrentElement;
5055 AFSFreeNameArray( IN AFSNameArrayHdr *NameArray)
5058 NTSTATUS ntStatus = STATUS_SUCCESS;
5059 AFSNameArrayCB *pCurrentElement = NULL;
5065 pCurrentElement = &NameArray->ElementArray[ 0];
5070 if( pCurrentElement->DirectoryCB == NULL)
5076 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5078 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5079 AFS_TRACE_LEVEL_VERBOSE,
5080 "AFSFreeNameArray Decrement count on %wZ DE %p Cnt %d\n",
5081 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5082 pCurrentElement->DirectoryCB,
5088 AFSExFreePool( NameArray);
5095 AFSInsertNextElement( IN AFSNameArrayHdr *NameArray,
5096 IN AFSDirectoryCB *DirEntry)
5099 NTSTATUS ntStatus = STATUS_SUCCESS;
5100 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5106 if( NameArray->Count == NameArray->MaxElementCount)
5109 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5112 if( NameArray->CurrentEntry != NULL &&
5113 NameArray->CurrentEntry->DirectoryCB == DirEntry)
5116 try_return( ntStatus);
5119 if( NameArray->Count > 0)
5122 NameArray->CurrentEntry++;
5126 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5129 lCount = InterlockedIncrement( &NameArray->Count);
5131 lCount = InterlockedIncrement( &DirEntry->OpenReferenceCount);
5133 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5134 AFS_TRACE_LEVEL_VERBOSE,
5135 "AFSInsertNextElement Increment count on %wZ DE %p Cnt %d\n",
5136 &DirEntry->NameInformation.FileName,
5140 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5142 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5144 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5155 AFSReplaceCurrentElement( IN AFSNameArrayHdr *NameArray,
5156 IN AFSDirectoryCB *DirectoryCB)
5160 ASSERT( NameArray->CurrentEntry != NULL);
5162 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5164 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5165 AFS_TRACE_LEVEL_VERBOSE,
5166 "AFSReplaceCurrentElement Decrement count on %wZ DE %p Cnt %d\n",
5167 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5168 NameArray->CurrentEntry->DirectoryCB,
5171 lCount = InterlockedIncrement( &DirectoryCB->OpenReferenceCount);
5173 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5174 AFS_TRACE_LEVEL_VERBOSE,
5175 "AFSReplaceCurrentElement Increment count on %wZ DE %p Cnt %d\n",
5176 &DirectoryCB->NameInformation.FileName,
5180 NameArray->CurrentEntry->DirectoryCB = DirectoryCB;
5182 NameArray->CurrentEntry->Component = DirectoryCB->NameInformation.FileName;
5184 NameArray->CurrentEntry->FileId = DirectoryCB->ObjectInformation->FileId;
5186 if( DirectoryCB->ObjectInformation->ParentObjectInformation == NULL)
5189 SetFlag( NameArray->CurrentEntry->Flags, AFS_NAME_ARRAY_FLAG_ROOT_ELEMENT);
5196 AFSBackupEntry( IN AFSNameArrayHdr *NameArray)
5199 AFSDirectoryCB *pCurrentDirEntry = NULL;
5205 if( NameArray->Count == 0)
5207 try_return( pCurrentDirEntry);
5210 lCount = InterlockedDecrement( &NameArray->CurrentEntry->DirectoryCB->OpenReferenceCount);
5212 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5213 AFS_TRACE_LEVEL_VERBOSE,
5214 "AFSBackupEntry Decrement count on %wZ DE %p Cnt %d\n",
5215 &NameArray->CurrentEntry->DirectoryCB->NameInformation.FileName,
5216 NameArray->CurrentEntry->DirectoryCB,
5219 NameArray->CurrentEntry->DirectoryCB = NULL;
5221 lCount = InterlockedDecrement( &NameArray->Count);
5225 NameArray->CurrentEntry = NULL;
5229 NameArray->CurrentEntry--;
5230 pCurrentDirEntry = NameArray->CurrentEntry->DirectoryCB;
5238 return pCurrentDirEntry;
5242 AFSGetParentEntry( IN AFSNameArrayHdr *NameArray)
5245 AFSDirectoryCB *pDirEntry = NULL;
5246 AFSNameArrayCB *pElement = NULL;
5251 if( NameArray->Count == 0 ||
5252 NameArray->Count == 1)
5255 try_return( pDirEntry = NULL);
5258 pElement = &NameArray->ElementArray[ NameArray->Count - 2];
5260 pDirEntry = pElement->DirectoryCB;
5271 AFSResetNameArray( IN AFSNameArrayHdr *NameArray,
5272 IN AFSDirectoryCB *DirEntry)
5275 AFSNameArrayCB *pCurrentElement = NULL;
5276 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
5282 pCurrentElement = &NameArray->ElementArray[ 0];
5287 if( pCurrentElement->DirectoryCB == NULL)
5293 lCount = InterlockedDecrement( &pCurrentElement->DirectoryCB->OpenReferenceCount);
5295 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5296 AFS_TRACE_LEVEL_VERBOSE,
5297 "AFSResetNameArray Decrement count on %wZ DE %p Cnt %d\n",
5298 &pCurrentElement->DirectoryCB->NameInformation.FileName,
5299 pCurrentElement->DirectoryCB,
5305 RtlZeroMemory( NameArray,
5306 sizeof( AFSNameArrayHdr) +
5307 ((pDevExt->Specific.RDR.NameArrayLength - 1) * sizeof( AFSNameArrayCB)));
5309 NameArray->MaxElementCount = pDevExt->Specific.RDR.NameArrayLength;
5311 if( DirEntry != NULL)
5314 NameArray->CurrentEntry = &NameArray->ElementArray[ 0];
5316 lCount = InterlockedIncrement( &NameArray->Count);
5318 lCount = InterlockedIncrement( &DirEntry->OpenReferenceCount);
5320 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5321 AFS_TRACE_LEVEL_VERBOSE,
5322 "AFSResetNameArray Increment count on %wZ DE %p Cnt %d\n",
5323 &DirEntry->NameInformation.FileName,
5327 NameArray->CurrentEntry->DirectoryCB = DirEntry;
5329 NameArray->CurrentEntry->Component = DirEntry->NameInformation.FileName;
5331 NameArray->CurrentEntry->FileId = DirEntry->ObjectInformation->FileId;
5339 AFSDumpNameArray( IN AFSNameArrayHdr *NameArray)
5342 AFSNameArrayCB *pCurrentElement = NULL;
5344 pCurrentElement = &NameArray->ElementArray[ 0];
5346 AFSPrint("AFSDumpNameArray Start (%d)\n", NameArray->Count);
5348 while( pCurrentElement->DirectoryCB != NULL)
5351 AFSPrint("FID %08lX-%08lX-%08lX-%08lX %wZ\n",
5352 pCurrentElement->FileId.Cell,
5353 pCurrentElement->FileId.Volume,
5354 pCurrentElement->FileId.Vnode,
5355 pCurrentElement->FileId.Unique,
5356 &pCurrentElement->DirectoryCB->NameInformation.FileName);
5361 AFSPrint("AFSDumpNameArray End\n\n");
5367 AFSSetEnumerationEvent( IN AFSFcb *Fcb)
5372 // Depending on the type of node, set the event
5375 switch( Fcb->Header.NodeTypeCode)
5378 case AFS_DIRECTORY_FCB:
5381 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5385 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5394 KeSetEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
5398 lCount = InterlockedIncrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5408 AFSClearEnumerationEvent( IN AFSFcb *Fcb)
5414 // Depending on the type of node, set the event
5417 switch( Fcb->Header.NodeTypeCode)
5420 case AFS_DIRECTORY_FCB:
5423 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5425 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5430 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5440 ASSERT( Fcb->NPFcb->Specific.Directory.DirectoryEnumCount > 0);
5442 lCount = InterlockedDecrement( &Fcb->NPFcb->Specific.Directory.DirectoryEnumCount);
5447 KeClearEvent( &Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent);
5458 AFSIsEnumerationInProcess( IN AFSObjectInfoCB *ObjectInfo)
5461 BOOLEAN bIsInProcess = FALSE;
5466 if( ObjectInfo->Fcb == NULL)
5469 try_return( bIsInProcess);
5473 // Depending on the type of node, set the event
5476 switch( ObjectInfo->Fcb->Header.NodeTypeCode)
5479 case AFS_DIRECTORY_FCB:
5482 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5485 bIsInProcess = TRUE;
5495 if( KeReadStateEvent( &ObjectInfo->Fcb->NPFcb->Specific.Directory.DirectoryEnumEvent))
5498 bIsInProcess = TRUE;
5510 return bIsInProcess;
5514 AFSVerifyVolume( IN ULONGLONG ProcessId,
5515 IN AFSVolumeCB *VolumeCB)
5518 NTSTATUS ntStatus = STATUS_SUCCESS;
5525 AFSInitPIOCtlDirectoryCB( IN AFSObjectInfoCB *ObjectInfo)
5528 NTSTATUS ntStatus = STATUS_SUCCESS;
5529 AFSObjectInfoCB *pObjectInfoCB = NULL;
5530 AFSDirectoryCB *pDirNode = NULL;
5531 ULONG ulEntryLength = 0;
5532 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
5537 pObjectInfoCB = AFSAllocateObjectInfo( ObjectInfo,
5540 if( pObjectInfoCB == NULL)
5543 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5546 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
5547 AFS_TRACE_LEVEL_VERBOSE,
5548 "AFSInitPIOCtlDirectoryCB Initializing count (1) on object %08lX\n",
5551 pObjectInfoCB->ObjectReferenceCount = 1;
5553 pObjectInfoCB->FileType = AFS_FILE_TYPE_PIOCTL;
5555 pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
5557 ulEntryLength = sizeof( AFSDirectoryCB) + AFSPIOCtlName.Length;
5559 pDirNode = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
5563 if( pDirNode == NULL)
5566 AFSDeleteObjectInfo( pObjectInfoCB);
5568 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5571 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
5572 sizeof( AFSNonPagedDirectoryCB),
5573 AFS_DIR_ENTRY_NP_TAG);
5575 if( pNonPagedDirEntry == NULL)
5578 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5581 RtlZeroMemory( pDirNode,
5584 RtlZeroMemory( pNonPagedDirEntry,
5585 sizeof( AFSNonPagedDirectoryCB));
5587 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
5589 pDirNode->NonPaged = pNonPagedDirEntry;
5591 pDirNode->ObjectInformation = pObjectInfoCB;
5593 pDirNode->FileIndex = (ULONG)AFS_DIR_ENTRY_PIOCTL_INDEX;
5599 SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_FAKE);
5601 pDirNode->NameInformation.FileName.Length = AFSPIOCtlName.Length;
5603 pDirNode->NameInformation.FileName.MaximumLength = AFSPIOCtlName.Length;
5605 pDirNode->NameInformation.FileName.Buffer = (WCHAR *)((char *)pDirNode + sizeof( AFSDirectoryCB));
5607 RtlCopyMemory( pDirNode->NameInformation.FileName.Buffer,
5608 AFSPIOCtlName.Buffer,
5609 pDirNode->NameInformation.FileName.Length);
5611 pDirNode->CaseInsensitiveTreeEntry.HashIndex = AFSGenerateCRC( &pDirNode->NameInformation.FileName,
5614 ObjectInfo->Specific.Directory.PIOCtlDirectoryCB = pDirNode;
5618 if ( !NT_SUCCESS( ntStatus))
5621 if ( pDirNode != NULL)
5624 AFSExFreePool( pDirNode);
5627 if ( pObjectInfoCB != NULL)
5630 AFSDeleteObjectInfo( pObjectInfoCB);
5639 AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
5640 IN AFSDirectoryCB *DirectoryCB,
5641 IN UNICODE_STRING *ParentPathName,
5642 IN AFSNameArrayHdr *RelatedNameArray,
5644 OUT AFSFileInfoCB *FileInfo)
5647 NTSTATUS ntStatus = STATUS_SUCCESS;
5648 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
5649 UNICODE_STRING uniFullPathName;
5650 AFSNameArrayHdr *pNameArray = NULL;
5651 AFSVolumeCB *pVolumeCB = NULL;
5652 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
5653 WCHAR *pwchBuffer = NULL;
5654 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
5655 ULONG ulNameDifference = 0;
5662 // Retrieve a target name for the entry
5665 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
5668 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5671 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5673 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
5678 if( !NT_SUCCESS( ntStatus) ||
5679 pDirEntry->TargetNameLength == 0)
5682 if( pDirEntry != NULL)
5685 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
5688 try_return( ntStatus);
5691 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
5694 if( DirectoryCB->NameInformation.TargetName.Length == 0)
5698 // Update the target name
5701 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
5702 &DirectoryCB->Flags,
5703 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
5704 (USHORT)pDirEntry->TargetNameLength);
5706 if( !NT_SUCCESS( ntStatus))
5709 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5711 try_return( ntStatus);
5715 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
5719 // Need to pass the full path in for parsing.
5722 if( AFSIsRelativeName( &DirectoryCB->NameInformation.TargetName))
5725 uniFullPathName.Length = 0;
5726 uniFullPathName.MaximumLength = ParentPathName->Length +
5728 DirectoryCB->NameInformation.TargetName.Length;
5730 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5731 uniFullPathName.MaximumLength,
5732 AFS_NAME_BUFFER_SIX_TAG);
5734 if( uniFullPathName.Buffer == NULL)
5737 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5739 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5742 pwchBuffer = uniFullPathName.Buffer;
5744 RtlZeroMemory( uniFullPathName.Buffer,
5745 uniFullPathName.MaximumLength);
5747 RtlCopyMemory( uniFullPathName.Buffer,
5748 ParentPathName->Buffer,
5749 ParentPathName->Length);
5751 uniFullPathName.Length = ParentPathName->Length;
5753 if( uniFullPathName.Buffer[ (uniFullPathName.Length/sizeof( WCHAR)) - 1] != L'\\' &&
5754 DirectoryCB->NameInformation.TargetName.Buffer[ 0] != L'\\')
5757 uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)] = L'\\';
5759 uniFullPathName.Length += sizeof( WCHAR);
5762 RtlCopyMemory( &uniFullPathName.Buffer[ uniFullPathName.Length/sizeof( WCHAR)],
5763 DirectoryCB->NameInformation.TargetName.Buffer,
5764 DirectoryCB->NameInformation.TargetName.Length);
5766 uniFullPathName.Length += DirectoryCB->NameInformation.TargetName.Length;
5768 uniParsedName.Length = uniFullPathName.Length - ParentPathName->Length;
5769 uniParsedName.MaximumLength = uniParsedName.Length;
5771 uniParsedName.Buffer = &uniFullPathName.Buffer[ ParentPathName->Length/sizeof( WCHAR)];
5773 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5776 // We populate up to the current parent
5779 if( RelatedNameArray != NULL)
5782 pNameArray = AFSInitNameArray( NULL,
5783 RelatedNameArray->MaxElementCount);
5785 if( pNameArray == NULL)
5788 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5791 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArray,
5798 pNameArray = AFSInitNameArray( NULL,
5801 if( pNameArray == NULL)
5804 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5807 ntStatus = AFSPopulateNameArray( pNameArray,
5812 if( !NT_SUCCESS( ntStatus))
5815 try_return( ntStatus);
5818 pVolumeCB = ParentDirectoryCB->ObjectInformation->VolumeCB;
5820 pParentDirEntry = ParentDirectoryCB;
5825 uniFullPathName.Length = 0;
5826 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
5828 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
5829 uniFullPathName.MaximumLength,
5830 AFS_NAME_BUFFER_SEVEN_TAG);
5832 if( uniFullPathName.Buffer == NULL)
5835 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5837 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5840 pwchBuffer = uniFullPathName.Buffer;
5842 RtlZeroMemory( uniFullPathName.Buffer,
5843 uniFullPathName.MaximumLength);
5845 RtlCopyMemory( uniFullPathName.Buffer,
5846 DirectoryCB->NameInformation.TargetName.Buffer,
5847 DirectoryCB->NameInformation.TargetName.Length);
5849 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
5852 // This name should begin with the \afs server so parse it off and check it
5855 FsRtlDissectName( uniFullPathName,
5859 if( RtlCompareUnicodeString( &uniComponentName,
5864 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5866 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
5867 AFS_TRACE_LEVEL_ERROR,
5868 "AFSRetrieveFileAttributes Name %wZ contains invalid server name\n",
5871 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
5874 uniFullPathName = uniRemainingPath;
5876 uniParsedName = uniFullPathName;
5878 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
5880 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
5886 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
5889 if( pNameArray == NULL)
5892 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
5895 pVolumeCB = AFSGlobalRoot;
5897 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
5901 // Increment the ref count on the volume and dir entry for correct processing below
5904 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
5906 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5907 AFS_TRACE_LEVEL_VERBOSE,
5908 "AFSRetrieveFileAttributes Increment count on volume %08lX Cnt %d\n",
5912 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
5914 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5915 AFS_TRACE_LEVEL_VERBOSE,
5916 "AFSRetrieveFileAttributes Increment count on %wZ DE %p Ccb %p Cnt %d\n",
5917 &pParentDirEntry->NameInformation.FileName,
5922 ntStatus = AFSLocateNameEntry( NULL,
5927 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL,
5933 if( !NT_SUCCESS( ntStatus))
5937 // The volume lock was released on failure above
5938 // Except for STATUS_OBJECT_NAME_NOT_FOUND
5941 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
5944 if( pVolumeCB != NULL)
5947 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
5949 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
5950 AFS_TRACE_LEVEL_VERBOSE,
5951 "AFSRetrieveFileAttributes Decrement count on volume %08lX Cnt %d\n",
5956 if( pDirectoryEntry != NULL)
5959 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
5961 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5962 AFS_TRACE_LEVEL_VERBOSE,
5963 "AFSRetrieveFileAttributes Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
5964 &pDirectoryEntry->NameInformation.FileName,
5972 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
5974 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
5975 AFS_TRACE_LEVEL_VERBOSE,
5976 "AFSRetrieveFileAttributes Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
5977 &pParentDirEntry->NameInformation.FileName,
5986 try_return( ntStatus);
5990 // Store off the information
5993 FileInfo->FileAttributes = pDirectoryEntry->ObjectInformation->FileAttributes;
5996 // Check for the mount point being returned
5999 if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
6002 FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
6004 else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
6005 pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
6008 if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
6011 FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
6016 FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
6020 FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
6022 FileInfo->EndOfFile = pDirectoryEntry->ObjectInformation->EndOfFile;
6024 FileInfo->CreationTime = pDirectoryEntry->ObjectInformation->CreationTime;
6026 FileInfo->LastAccessTime = pDirectoryEntry->ObjectInformation->LastAccessTime;
6028 FileInfo->LastWriteTime = pDirectoryEntry->ObjectInformation->LastWriteTime;
6030 FileInfo->ChangeTime = pDirectoryEntry->ObjectInformation->ChangeTime;
6033 // Remove the reference made above
6036 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6038 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6039 AFS_TRACE_LEVEL_VERBOSE,
6040 "AFSRetrieveFileAttributes Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
6041 &pDirectoryEntry->NameInformation.FileName,
6048 if( pDirEntry != NULL)
6051 AFSExFreePool( pDirEntry);
6054 if( pVolumeCB != NULL)
6057 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6059 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6060 AFS_TRACE_LEVEL_VERBOSE,
6061 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
6066 if( pNameArray != NULL)
6069 AFSFreeNameArray( pNameArray);
6072 if( pwchBuffer != NULL)
6076 // Always free the buffer that we allocated as AFSLocateNameEntry
6077 // will not free it. If uniFullPathName.Buffer was allocated by
6078 // AFSLocateNameEntry, then we must free that as well.
6079 // Check that the uniFullPathName.Buffer in the string is not the same
6080 // offset by the length of the server name
6083 if( uniFullPathName.Length > 0 &&
6084 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6087 AFSExFreePool( uniFullPathName.Buffer);
6090 AFSExFreePool( pwchBuffer);
6098 AFSAllocateObjectInfo( IN AFSObjectInfoCB *ParentObjectInfo,
6099 IN ULONGLONG HashIndex)
6102 NTSTATUS ntStatus = STATUS_SUCCESS;
6103 AFSObjectInfoCB *pObjectInfo = NULL;
6109 pObjectInfo = (AFSObjectInfoCB *)AFSExAllocatePoolWithTag( PagedPool,
6110 sizeof( AFSObjectInfoCB),
6111 AFS_OBJECT_INFO_TAG);
6113 if( pObjectInfo == NULL)
6116 try_return( pObjectInfo);
6119 RtlZeroMemory( pObjectInfo,
6120 sizeof( AFSObjectInfoCB));
6122 pObjectInfo->NonPagedInfo = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
6123 sizeof( AFSNonPagedObjectInfoCB),
6124 AFS_NP_OBJECT_INFO_TAG);
6126 if( pObjectInfo->NonPagedInfo == NULL)
6129 AFSExFreePool( pObjectInfo);
6131 try_return( pObjectInfo = NULL);
6134 ExInitializeResourceLite( &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6136 pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock = &pObjectInfo->NonPagedInfo->DirectoryNodeHdrLock;
6138 pObjectInfo->VolumeCB = ParentObjectInfo->VolumeCB;
6140 pObjectInfo->ParentObjectInformation = ParentObjectInfo;
6142 if( ParentObjectInfo != NULL)
6144 lCount = InterlockedIncrement( &ParentObjectInfo->ObjectReferenceCount);
6148 // Initialize the access time
6151 KeQueryTickCount( &pObjectInfo->LastAccessCount);
6157 // Insert the entry into the object tree and list
6160 pObjectInfo->TreeEntry.HashIndex = HashIndex;
6162 if( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead == NULL)
6165 ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead = &pObjectInfo->TreeEntry;
6170 ntStatus = AFSInsertHashEntry( ParentObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6171 &pObjectInfo->TreeEntry);
6173 ASSERT( NT_SUCCESS( ntStatus));
6177 // And the object list in the volume
6180 if( ParentObjectInfo->VolumeCB->ObjectInfoListHead == NULL)
6183 ParentObjectInfo->VolumeCB->ObjectInfoListHead = pObjectInfo;
6188 ParentObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = (void *)pObjectInfo;
6190 pObjectInfo->ListEntry.bLink = (void *)ParentObjectInfo->VolumeCB->ObjectInfoListTail;
6193 ParentObjectInfo->VolumeCB->ObjectInfoListTail = pObjectInfo;
6196 // Indicate the object is in the hash tree and linked list in the volume
6199 SetFlag( pObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE | AFS_OBJECT_INSERTED_VOLUME_LIST);
6211 AFSDeleteObjectInfo( IN AFSObjectInfoCB *ObjectInfo)
6214 BOOLEAN bAcquiredTreeLock = FALSE;
6217 if( !ExIsResourceAcquiredExclusiveLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
6220 ASSERT( !ExIsResourceAcquiredLite( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock));
6222 AFSAcquireExcl( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock,
6225 bAcquiredTreeLock = TRUE;
6229 // Remove it from the tree and list if it was inserted
6232 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_HASH_TREE))
6235 AFSRemoveHashEntry( &ObjectInfo->VolumeCB->ObjectInfoTree.TreeHead,
6236 &ObjectInfo->TreeEntry);
6239 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_INSERTED_VOLUME_LIST))
6242 if( ObjectInfo->ListEntry.fLink == NULL)
6245 ObjectInfo->VolumeCB->ObjectInfoListTail = (AFSObjectInfoCB *)ObjectInfo->ListEntry.bLink;
6247 if( ObjectInfo->VolumeCB->ObjectInfoListTail != NULL)
6250 ObjectInfo->VolumeCB->ObjectInfoListTail->ListEntry.fLink = NULL;
6256 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.fLink))->ListEntry.bLink = ObjectInfo->ListEntry.bLink;
6259 if( ObjectInfo->ListEntry.bLink == NULL)
6262 ObjectInfo->VolumeCB->ObjectInfoListHead = (AFSObjectInfoCB *)ObjectInfo->ListEntry.fLink;
6264 if( ObjectInfo->VolumeCB->ObjectInfoListHead != NULL)
6267 ObjectInfo->VolumeCB->ObjectInfoListHead->ListEntry.bLink = NULL;
6273 ((AFSObjectInfoCB *)(ObjectInfo->ListEntry.bLink))->ListEntry.fLink = ObjectInfo->ListEntry.fLink;
6277 if( ObjectInfo->ParentObjectInformation != NULL)
6280 lCount = InterlockedDecrement( &ObjectInfo->ParentObjectInformation->ObjectReferenceCount);
6283 if( bAcquiredTreeLock)
6286 AFSReleaseResource( ObjectInfo->VolumeCB->ObjectInfoTree.TreeLock);
6290 // Release the fid in the service
6293 if( BooleanFlagOn( ObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE))
6296 AFSReleaseFid( &ObjectInfo->FileId);
6299 ExDeleteResourceLite( &ObjectInfo->NonPagedInfo->DirectoryNodeHdrLock);
6301 AFSExFreePool( ObjectInfo->NonPagedInfo);
6303 AFSExFreePool( ObjectInfo);
6309 AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
6310 OUT AFSDirectoryCB **TargetDirEntry)
6313 NTSTATUS ntStatus = STATUS_SUCCESS;
6314 AFSDirEnumEntry *pDirEntry = NULL, *pLastDirEntry = NULL;
6315 UNICODE_STRING uniFullPathName;
6316 AFSNameArrayHdr *pNameArray = NULL;
6317 AFSVolumeCB *pVolumeCB = NULL;
6318 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
6319 WCHAR *pwchBuffer = NULL;
6320 UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
6321 ULONG ulNameDifference = 0;
6328 ntStatus = AFSRetrieveValidAuthGroup( NULL,
6329 DirectoryCB->ObjectInformation,
6333 if( !NT_SUCCESS( ntStatus))
6335 try_return( ntStatus);
6339 // Retrieve a target name for the entry
6342 AFSAcquireShared( &DirectoryCB->NonPaged->Lock,
6345 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6348 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6350 ntStatus = AFSEvaluateTargetByID( DirectoryCB->ObjectInformation,
6355 if( !NT_SUCCESS( ntStatus) ||
6356 pDirEntry->TargetNameLength == 0)
6359 if( pDirEntry != NULL)
6362 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
6365 try_return( ntStatus);
6368 AFSAcquireExcl( &DirectoryCB->NonPaged->Lock,
6371 if( DirectoryCB->NameInformation.TargetName.Length == 0)
6375 // Update the target name
6378 ntStatus = AFSUpdateTargetName( &DirectoryCB->NameInformation.TargetName,
6379 &DirectoryCB->Flags,
6380 (WCHAR *)((char *)pDirEntry + pDirEntry->TargetNameOffset),
6381 (USHORT)pDirEntry->TargetNameLength);
6383 if( !NT_SUCCESS( ntStatus))
6386 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6388 try_return( ntStatus);
6392 AFSConvertToShared( &DirectoryCB->NonPaged->Lock);
6396 // Need to pass the full path in for parsing.
6399 uniFullPathName.Length = 0;
6400 uniFullPathName.MaximumLength = DirectoryCB->NameInformation.TargetName.Length;
6402 uniFullPathName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6403 uniFullPathName.MaximumLength,
6404 AFS_NAME_BUFFER_EIGHT_TAG);
6406 if( uniFullPathName.Buffer == NULL)
6409 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6411 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6414 pwchBuffer = uniFullPathName.Buffer;
6416 RtlZeroMemory( uniFullPathName.Buffer,
6417 uniFullPathName.MaximumLength);
6419 RtlCopyMemory( uniFullPathName.Buffer,
6420 DirectoryCB->NameInformation.TargetName.Buffer,
6421 DirectoryCB->NameInformation.TargetName.Length);
6423 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6426 // This name should begin with the \afs server so parse it off and chech it
6429 FsRtlDissectName( uniFullPathName,
6433 if( RtlCompareUnicodeString( &uniComponentName,
6439 // Try evaluating the full path
6442 uniFullPathName.Buffer = pwchBuffer;
6444 uniFullPathName.Length = DirectoryCB->NameInformation.TargetName.Length;
6446 uniFullPathName.MaximumLength = uniFullPathName.Length;
6451 uniFullPathName = uniRemainingPath;
6454 uniParsedName = uniFullPathName;
6456 ulNameDifference = (ULONG)(uniFullPathName.Length > 0 ? ((char *)uniFullPathName.Buffer - (char *)pwchBuffer) : 0);
6458 AFSReleaseResource( &DirectoryCB->NonPaged->Lock);
6464 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
6467 if( pNameArray == NULL)
6470 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6473 pVolumeCB = AFSGlobalRoot;
6475 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
6477 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
6479 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6480 AFS_TRACE_LEVEL_VERBOSE,
6481 "AFSEvaluateRootEntry Increment count on volume %08lX Cnt %d\n",
6485 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
6487 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6488 AFS_TRACE_LEVEL_VERBOSE,
6489 "AFSEvaluateRootEntry Increment count on %wZ DE %p Ccb %p Cnt %d\n",
6490 &pParentDirEntry->NameInformation.FileName,
6495 ntStatus = AFSLocateNameEntry( NULL,
6506 if( !NT_SUCCESS( ntStatus))
6510 // The volume lock was released on failure above
6511 // Except for STATUS_OBJECT_NAME_NOT_FOUND
6514 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
6517 if( pVolumeCB != NULL)
6520 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6522 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6523 AFS_TRACE_LEVEL_VERBOSE,
6524 "AFSEvaluateRootEntry Decrement count on volume %08lX Cnt %d\n",
6529 if( pDirectoryEntry != NULL)
6532 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
6534 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6535 AFS_TRACE_LEVEL_VERBOSE,
6536 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6537 &pDirectoryEntry->NameInformation.FileName,
6545 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
6547 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
6548 AFS_TRACE_LEVEL_VERBOSE,
6549 "AFSEvaluateRootEntry Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
6550 &pParentDirEntry->NameInformation.FileName,
6559 try_return( ntStatus);
6563 // Pass back the target dir entry for this request
6566 *TargetDirEntry = pDirectoryEntry;
6570 if( pDirEntry != NULL)
6573 AFSExFreePool( pDirEntry);
6576 if( pVolumeCB != NULL)
6579 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
6581 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
6582 AFS_TRACE_LEVEL_VERBOSE,
6583 "AFSEvaluateRootEntry2 Decrement count on volume %08lX Cnt %d\n",
6588 if( pNameArray != NULL)
6591 AFSFreeNameArray( pNameArray);
6594 if( pwchBuffer != NULL)
6598 // Always free the buffer that we allocated as AFSLocateNameEntry
6599 // will not free it. If uniFullPathName.Buffer was allocated by
6600 // AFSLocateNameEntry, then we must free that as well.
6601 // Check that the uniFullPathName.Buffer in the string is not the same
6602 // offset by the length of the server name
6605 if( uniFullPathName.Length > 0 &&
6606 pwchBuffer != (WCHAR *)((char *)uniFullPathName.Buffer - ulNameDifference))
6609 AFSExFreePool( uniFullPathName.Buffer);
6612 AFSExFreePool( pwchBuffer);
6620 AFSCleanupFcb( IN AFSFcb *Fcb,
6621 IN BOOLEAN ForceFlush)
6624 NTSTATUS ntStatus = STATUS_SUCCESS;
6625 AFSDeviceExt *pRDRDeviceExt = NULL, *pControlDeviceExt = NULL;
6626 LARGE_INTEGER liTime;
6627 IO_STATUS_BLOCK stIoStatus;
6632 pControlDeviceExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
6634 pRDRDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6636 if( BooleanFlagOn( pRDRDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
6639 if( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6640 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6643 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6646 if( Fcb->OpenReferenceCount > 0)
6652 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6657 if( !NT_SUCCESS( stIoStatus.Status))
6660 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6661 AFS_TRACE_LEVEL_ERROR,
6662 "AFSCleanupFcb CcFlushCache [1] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6663 Fcb->ObjectInformation->FileId.Cell,
6664 Fcb->ObjectInformation->FileId.Volume,
6665 Fcb->ObjectInformation->FileId.Vnode,
6666 Fcb->ObjectInformation->FileId.Unique,
6668 stIoStatus.Information);
6670 ntStatus = stIoStatus.Status;
6673 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6678 __except( EXCEPTION_EXECUTE_HANDLER)
6680 ntStatus = GetExceptionCode();
6684 AFSReleaseResource( &Fcb->NPFcb->Resource);
6687 // Wait for any currently running flush or release requests to complete
6690 AFSWaitOnQueuedFlushes( Fcb);
6693 // Now perform another flush on the file
6696 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6700 AFSReleaseExtentsWithFlush( Fcb,
6705 if( Fcb->OpenReferenceCount == 0 ||
6706 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6707 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6710 AFSTearDownFcbExtents( Fcb,
6714 try_return( ntStatus);
6717 KeQueryTickCount( &liTime);
6720 // First up are there dirty extents in the cache to flush?
6724 ( !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) &&
6725 !BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED) &&
6726 ( Fcb->Specific.File.ExtentsDirtyCount ||
6727 Fcb->Specific.File.ExtentCount) &&
6728 (liTime.QuadPart - Fcb->Specific.File.LastServerFlush.QuadPart)
6729 >= pControlDeviceExt->Specific.Control.FcbFlushTimeCount.QuadPart))
6731 if( !NT_SUCCESS( AFSFlushExtents( Fcb,
6733 Fcb->OpenReferenceCount == 0)
6736 AFSReleaseExtentsWithFlush( Fcb,
6740 else if( BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_OBJECT_INVALID) ||
6741 BooleanFlagOn( Fcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_DELETED))
6745 // The file has been marked as invalid. Dump it
6748 AFSTearDownFcbExtents( Fcb,
6753 // If there are extents and they haven't been used recently *and*
6754 // are not being used
6758 ( 0 != Fcb->Specific.File.ExtentCount &&
6759 0 != Fcb->Specific.File.LastExtentAccess.QuadPart &&
6760 (liTime.QuadPart - Fcb->Specific.File.LastExtentAccess.QuadPart) >=
6761 (AFS_SERVER_PURGE_SLEEP * pControlDeviceExt->Specific.Control.FcbPurgeTimeCount.QuadPart))) &&
6762 AFSAcquireExcl( &Fcb->NPFcb->Resource,
6769 CcFlushCache( &Fcb->NPFcb->SectionObjectPointers,
6774 if( !NT_SUCCESS( stIoStatus.Status))
6777 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
6778 AFS_TRACE_LEVEL_ERROR,
6779 "AFSCleanupFcb CcFlushCache [2] failure FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX Bytes 0x%08lX\n",
6780 Fcb->ObjectInformation->FileId.Cell,
6781 Fcb->ObjectInformation->FileId.Volume,
6782 Fcb->ObjectInformation->FileId.Vnode,
6783 Fcb->ObjectInformation->FileId.Unique,
6785 stIoStatus.Information);
6787 ntStatus = stIoStatus.Status;
6793 CcPurgeCacheSection( &Fcb->NPFcb->SectionObjectPointers,
6799 __except( EXCEPTION_EXECUTE_HANDLER)
6801 ntStatus = GetExceptionCode();
6804 AFSReleaseResource( &Fcb->NPFcb->Resource);
6806 if( Fcb->OpenReferenceCount == 0)
6810 // Tear em down we'll not be needing them again
6813 AFSTearDownFcbExtents( Fcb,
6827 AFSUpdateDirEntryName( IN AFSDirectoryCB *DirectoryCB,
6828 IN UNICODE_STRING *NewFileName)
6831 NTSTATUS ntStatus = STATUS_SUCCESS;
6832 WCHAR *pTmpBuffer = NULL;
6837 if( NewFileName->Length > DirectoryCB->NameInformation.FileName.Length)
6840 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER))
6843 AFSExFreePool( DirectoryCB->NameInformation.FileName.Buffer);
6845 ClearFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6847 DirectoryCB->NameInformation.FileName.Buffer = NULL;
6851 // OK, we need to allocate a new name buffer
6854 pTmpBuffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
6855 NewFileName->Length,
6856 AFS_NAME_BUFFER_NINE_TAG);
6858 if( pTmpBuffer == NULL)
6861 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6864 DirectoryCB->NameInformation.FileName.Buffer = pTmpBuffer;
6866 DirectoryCB->NameInformation.FileName.MaximumLength = NewFileName->Length;
6868 SetFlag( DirectoryCB->Flags, AFS_DIR_RELEASE_NAME_BUFFER);
6871 DirectoryCB->NameInformation.FileName.Length = NewFileName->Length;
6873 RtlCopyMemory( DirectoryCB->NameInformation.FileName.Buffer,
6874 NewFileName->Buffer,
6875 NewFileName->Length);
6886 AFSReadCacheFile( IN void *ReadBuffer,
6887 IN LARGE_INTEGER *ReadOffset,
6888 IN ULONG RequestedDataLength,
6889 IN OUT PULONG BytesRead)
6892 NTSTATUS ntStatus = STATUS_SUCCESS;
6895 PIO_STACK_LOCATION pIoStackLocation = NULL;
6896 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
6897 DEVICE_OBJECT *pTargetDeviceObject = NULL;
6898 FILE_OBJECT *pCacheFileObject = NULL;
6903 pCacheFileObject = AFSReferenceCacheFileObject();
6905 if( pCacheFileObject == NULL)
6907 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
6910 pTargetDeviceObject = IoGetRelatedDeviceObject( pCacheFileObject);
6913 // Initialize the event
6916 KeInitializeEvent( &kEvent,
6917 SynchronizationEvent,
6921 // Allocate an irp for this request. This could also come from a
6922 // private pool, for instance.
6925 pIrp = IoAllocateIrp( pTargetDeviceObject->StackSize,
6931 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
6935 // Build the IRP's main body
6938 pIrp->UserBuffer = ReadBuffer;
6940 pIrp->Tail.Overlay.Thread = PsGetCurrentThread();
6941 pIrp->RequestorMode = KernelMode;
6942 pIrp->Flags |= IRP_READ_OPERATION;
6945 // Set up the I/O stack location.
6948 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
6949 pIoStackLocation->MajorFunction = IRP_MJ_READ;
6950 pIoStackLocation->DeviceObject = pTargetDeviceObject;
6951 pIoStackLocation->FileObject = pCacheFileObject;
6952 pIoStackLocation->Parameters.Read.Length = RequestedDataLength;
6954 pIoStackLocation->Parameters.Read.ByteOffset.QuadPart = ReadOffset->QuadPart;
6957 // Set the completion routine.
6960 IoSetCompletionRoutine( pIrp,
6968 // Send it to the FSD
6971 ntStatus = IoCallDriver( pTargetDeviceObject,
6974 if( NT_SUCCESS( ntStatus))
6981 ntStatus = KeWaitForSingleObject( &kEvent,
6987 if( NT_SUCCESS( ntStatus))
6990 ntStatus = pIrp->IoStatus.Status;
6992 *BytesRead = (ULONG)pIrp->IoStatus.Information;
6998 if( pCacheFileObject != NULL)
7000 AFSReleaseCacheFileObject( pCacheFileObject);
7006 if( pIrp->MdlAddress != NULL)
7009 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
7012 MmUnlockPages( pIrp->MdlAddress);
7015 IoFreeMdl( pIrp->MdlAddress);
7018 pIrp->MdlAddress = NULL;
7032 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
7037 KEVENT *pEvent = (KEVENT *)Context;
7043 return STATUS_MORE_PROCESSING_REQUIRED;
7047 AFSIsDirectoryEmptyForDelete( IN AFSFcb *Fcb)
7050 BOOLEAN bIsEmpty = FALSE;
7051 AFSDirectoryCB *pDirEntry = NULL;
7056 AFSAcquireShared( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7061 if( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead != NULL)
7064 pDirEntry = Fcb->ObjectInformation->Specific.Directory.DirectoryNodeListHead;
7066 while( pDirEntry != NULL)
7069 if( !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_FAKE) &&
7070 !BooleanFlagOn( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED))
7078 pDirEntry = (AFSDirectoryCB *)pDirEntry->ListEntry.fLink;
7083 AFSReleaseResource( Fcb->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
7090 AFSRemoveNameEntry( IN AFSObjectInfoCB *ParentObjectInfo,
7091 IN AFSDirectoryCB *DirEntry)
7094 NTSTATUS ntStatus = STATUS_SUCCESS;
7099 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7102 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7103 AFS_TRACE_LEVEL_VERBOSE,
7104 "AFSRemoveNameEntry DE %p for %wZ has NOT_IN flag set\n",
7106 &DirEntry->NameInformation.FileName);
7108 try_return( ntStatus);
7111 ASSERT( ExIsResourceAcquiredExclusiveLite( ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock));
7114 // Remove the entry from the parent tree
7117 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7118 AFS_TRACE_LEVEL_VERBOSE,
7119 "AFSRemoveNameEntry DE %p for %wZ removing from case sensitive tree\n",
7121 &DirEntry->NameInformation.FileName);
7123 AFSRemoveCaseSensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7126 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7127 AFS_TRACE_LEVEL_VERBOSE,
7128 "AFSRemoveNameEntry DE %p for %wZ removing from case insensitive tree\n",
7130 &DirEntry->NameInformation.FileName);
7132 AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7135 if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
7139 // From the short name tree
7142 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7143 AFS_TRACE_LEVEL_VERBOSE,
7144 "AFSRemoveNameEntry DE %p for %wZ removing from shortname tree\n",
7146 &DirEntry->NameInformation.FileName);
7148 AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
7151 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
7154 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7155 AFS_TRACE_LEVEL_VERBOSE,
7156 "AFSRemoveNameEntry DE %p for %wZ setting NOT_IN flag\n",
7158 &DirEntry->NameInformation.FileName);
7160 SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
7162 ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
7173 AFSGetAuthenticationId()
7176 LARGE_INTEGER liAuthId = {0,0};
7177 NTSTATUS ntStatus = STATUS_SUCCESS;
7178 PACCESS_TOKEN hToken = NULL;
7179 PTOKEN_STATISTICS pTokenInfo = NULL;
7180 BOOLEAN bCopyOnOpen = FALSE;
7181 BOOLEAN bEffectiveOnly = FALSE;
7182 BOOLEAN bPrimaryToken = FALSE;
7183 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
7188 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
7191 &stImpersonationLevel);
7196 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
7201 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7202 AFS_TRACE_LEVEL_ERROR,
7203 "AFSGetAuthenticationId Failed to retrieve impersonation or primary token\n");
7205 try_return( ntStatus);
7208 bPrimaryToken = TRUE;
7211 ntStatus = SeQueryInformationToken( hToken,
7213 (PVOID *)&pTokenInfo);
7215 if( !NT_SUCCESS( ntStatus))
7218 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7219 AFS_TRACE_LEVEL_ERROR,
7220 "AFSGetAuthenticationId Failed to retrieve information Status %08lX\n", ntStatus);
7222 try_return( ntStatus);
7225 liAuthId.HighPart = pTokenInfo->AuthenticationId.HighPart;
7226 liAuthId.LowPart = pTokenInfo->AuthenticationId.LowPart;
7228 AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER,
7229 AFS_TRACE_LEVEL_VERBOSE,
7230 "AFSGetAuthenticationId Successfully retrieved authentication ID %I64X\n",
7241 PsDereferenceImpersonationToken( hToken);
7246 PsDereferencePrimaryToken( hToken);
7250 if( pTokenInfo != NULL)
7253 AFSExFreePool( pTokenInfo);
7261 AFSUnwindFileInfo( IN AFSFcb *Fcb,
7265 if( Ccb->FileUnwindInfo.FileAttributes != (ULONG)-1)
7267 Ccb->DirectoryCB->ObjectInformation->FileAttributes = Ccb->FileUnwindInfo.FileAttributes;
7270 if( Ccb->FileUnwindInfo.CreationTime.QuadPart != (ULONGLONG)-1)
7272 Ccb->DirectoryCB->ObjectInformation->CreationTime.QuadPart = Ccb->FileUnwindInfo.CreationTime.QuadPart;
7275 if( Ccb->FileUnwindInfo.LastAccessTime.QuadPart != (ULONGLONG)-1)
7277 Ccb->DirectoryCB->ObjectInformation->LastAccessTime.QuadPart = Ccb->FileUnwindInfo.LastAccessTime.QuadPart;
7280 if( Ccb->FileUnwindInfo.LastWriteTime.QuadPart != (ULONGLONG)-1)
7282 Ccb->DirectoryCB->ObjectInformation->LastWriteTime.QuadPart = Ccb->FileUnwindInfo.LastWriteTime.QuadPart;
7285 if( Ccb->FileUnwindInfo.ChangeTime.QuadPart != (ULONGLONG)-1)
7287 Ccb->DirectoryCB->ObjectInformation->ChangeTime.QuadPart = Ccb->FileUnwindInfo.ChangeTime.QuadPart;
7294 AFSValidateDirList( IN AFSObjectInfoCB *ObjectInfo)
7297 BOOLEAN bIsValid = TRUE;
7299 AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
7301 pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
7303 while( pCurrentDirEntry != NULL)
7306 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
7310 if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
7315 AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7316 (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
7319 if( pDirEntry == NULL)
7326 pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
7329 if( ulCount != ObjectInfo->Specific.Directory.DirectoryNodeCount)
7332 AFSPrint("AFSValidateDirList Count off Calc: %d Stored: %d\n",
7334 ObjectInfo->Specific.Directory.DirectoryNodeCount);
7336 ObjectInfo->Specific.Directory.DirectoryNodeCount = ulCount;
7345 AFSReferenceCacheFileObject()
7348 AFSDeviceExt *pRdrDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
7349 FILE_OBJECT *pCacheFileObject = NULL;
7351 AFSAcquireShared( &pRdrDevExt->Specific.RDR.CacheFileLock,
7354 pCacheFileObject = pRdrDevExt->Specific.RDR.CacheFileObject;
7356 if( pCacheFileObject != NULL)
7358 ObReferenceObject( pCacheFileObject);
7361 AFSReleaseResource( &pRdrDevExt->Specific.RDR.CacheFileLock);
7363 return pCacheFileObject;
7367 AFSReleaseCacheFileObject( IN PFILE_OBJECT CacheFileObject)
7370 ASSERT( CacheFileObject != NULL);
7372 ObDereferenceObject( CacheFileObject);
7378 AFSInitializeLibrary( IN AFSLibraryInitCB *LibraryInit)
7381 NTSTATUS ntStatus = STATUS_SUCCESS;
7382 AFSDeviceExt *pControlDevExt = NULL;
7383 ULONG ulTimeIncrement = 0;
7388 AFSControlDeviceObject = LibraryInit->AFSControlDeviceObject;
7390 AFSRDRDeviceObject = LibraryInit->AFSRDRDeviceObject;
7392 AFSServerName = LibraryInit->AFSServerName;
7394 AFSDebugFlags = LibraryInit->AFSDebugFlags;
7397 // Callbacks in the framework
7400 AFSProcessRequest = LibraryInit->AFSProcessRequest;
7402 AFSDbgLogMsg = LibraryInit->AFSDbgLogMsg;
7404 AFSAddConnectionEx = LibraryInit->AFSAddConnectionEx;
7406 AFSExAllocatePoolWithTag = LibraryInit->AFSExAllocatePoolWithTag;
7408 AFSExFreePool = LibraryInit->AFSExFreePool;
7410 AFSDumpTraceFilesFnc = LibraryInit->AFSDumpTraceFiles;
7412 AFSRetrieveAuthGroupFnc = LibraryInit->AFSRetrieveAuthGroup;
7414 AFSLibCacheManagerCallbacks = LibraryInit->AFSCacheManagerCallbacks;
7416 if( LibraryInit->AFSCacheBaseAddress != NULL)
7419 SetFlag( AFSLibControlFlags, AFS_REDIR_LIB_FLAGS_NONPERSISTENT_CACHE);
7421 AFSLibCacheBaseAddress = LibraryInit->AFSCacheBaseAddress;
7423 AFSLibCacheLength = LibraryInit->AFSCacheLength;
7427 // Initialize some flush parameters
7430 pControlDevExt = (AFSDeviceExt *)AFSControlDeviceObject->DeviceExtension;
7432 ulTimeIncrement = KeQueryTimeIncrement();
7434 pControlDevExt->Specific.Control.ObjectLifeTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_OBJECT_LIFETIME / (ULONGLONG)ulTimeIncrement);
7435 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart = AFS_ONE_SECOND;
7436 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart *= AFS_SERVER_PURGE_DELAY;
7437 pControlDevExt->Specific.Control.FcbPurgeTimeCount.QuadPart /= ulTimeIncrement;
7438 pControlDevExt->Specific.Control.FcbFlushTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)(AFS_ONE_SECOND * AFS_SERVER_FLUSH_DELAY) / (ULONGLONG)ulTimeIncrement);
7439 pControlDevExt->Specific.Control.ExtentRequestTimeCount.QuadPart = (ULONGLONG)((ULONGLONG)AFS_EXTENT_REQUEST_TIME/(ULONGLONG)ulTimeIncrement);
7442 // Initialize the global root entry
7445 ntStatus = AFSInitVolume( NULL,
7446 &LibraryInit->GlobalRootFid,
7449 if( !NT_SUCCESS( ntStatus))
7452 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7453 AFS_TRACE_LEVEL_ERROR,
7454 "AFSInitializeLibrary AFSInitVolume failure %08lX\n",
7457 try_return( ntStatus);
7460 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
7463 if( !NT_SUCCESS( ntStatus))
7466 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
7467 AFS_TRACE_LEVEL_ERROR,
7468 "AFSInitializeLibrary AFSInitRootFcb failure %08lX\n",
7471 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7473 try_return( ntStatus);
7477 // Update the node type code to AFS_ROOT_ALL
7480 AFSGlobalRoot->ObjectInformation.Fcb->Header.NodeTypeCode = AFS_ROOT_ALL;
7482 SetFlag( AFSGlobalRoot->Flags, AFS_VOLUME_ACTIVE_GLOBAL_ROOT);
7485 // Drop the locks acquired above
7488 AFSInitVolumeWorker( AFSGlobalRoot);
7490 AFSReleaseResource( AFSGlobalRoot->VolumeLock);
7492 AFSReleaseResource( AFSGlobalRoot->ObjectInformation.Fcb->Header.Resource);
7506 NTSTATUS ntStatus = STATUS_SUCCESS;
7507 AFSDirectoryCB *pDirNode = NULL, *pLastDirNode = NULL;
7512 if( AFSGlobalDotDirEntry != NULL)
7515 AFSDeleteObjectInfo( AFSGlobalDotDirEntry->ObjectInformation);
7517 ExDeleteResourceLite( &AFSGlobalDotDirEntry->NonPaged->Lock);
7519 ExFreePool( AFSGlobalDotDirEntry->NonPaged);
7521 ExFreePool( AFSGlobalDotDirEntry);
7523 AFSGlobalDotDirEntry = NULL;
7526 if( AFSGlobalDotDotDirEntry != NULL)
7529 AFSDeleteObjectInfo( AFSGlobalDotDotDirEntry->ObjectInformation);
7531 ExDeleteResourceLite( &AFSGlobalDotDotDirEntry->NonPaged->Lock);
7533 ExFreePool( AFSGlobalDotDotDirEntry->NonPaged);
7535 ExFreePool( AFSGlobalDotDotDirEntry);
7537 AFSGlobalDotDotDirEntry = NULL;
7540 if( AFSSpecialShareNames != NULL)
7543 pDirNode = AFSSpecialShareNames;
7545 while( pDirNode != NULL)
7548 pLastDirNode = (AFSDirectoryCB *)pDirNode->ListEntry.fLink;
7550 AFSDeleteObjectInfo( pDirNode->ObjectInformation);
7552 ExDeleteResourceLite( &pDirNode->NonPaged->Lock);
7554 ExFreePool( pDirNode->NonPaged);
7556 ExFreePool( pDirNode);
7558 pDirNode = pLastDirNode;
7561 AFSSpecialShareNames = NULL;
7569 AFSDefaultLogMsg( IN ULONG Subsystem,
7575 NTSTATUS ntStatus = STATUS_SUCCESS;
7577 char chDebugBuffer[ 256];
7582 va_start( va_args, Format);
7584 ntStatus = RtlStringCbVPrintfA( chDebugBuffer,
7589 if( NT_SUCCESS( ntStatus))
7591 DbgPrint( chDebugBuffer);
7601 AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
7602 IN ULONG InputBufferLength,
7603 IN AFSStatusInfoCB *StatusInfo,
7604 OUT ULONG *ReturnLength)
7607 NTSTATUS ntStatus = STATUS_SUCCESS;
7608 AFSFcb *pFcb = NULL;
7609 AFSVolumeCB *pVolumeCB = NULL;
7610 AFSDeviceExt *pDevExt = (AFSDeviceExt *) AFSRDRDeviceObject->DeviceExtension;
7611 AFSObjectInfoCB *pObjectInfo = NULL;
7612 ULONGLONG ullIndex = 0;
7613 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName, uniParsedName;
7614 AFSNameArrayHdr *pNameArray = NULL;
7615 AFSDirectoryCB *pDirectoryEntry = NULL, *pParentDirEntry = NULL;
7622 // If we are given a FID then look up the entry by that, otherwise
7626 if( GetStatusInfo->FileID.Cell != 0 &&
7627 GetStatusInfo->FileID.Volume != 0 &&
7628 GetStatusInfo->FileID.Vnode != 0 &&
7629 GetStatusInfo->FileID.Unique != 0)
7632 AFSAcquireShared( &pDevExt->Specific.RDR.VolumeTreeLock, TRUE);
7635 // Locate the volume node
7638 ullIndex = AFSCreateHighIndex( &GetStatusInfo->FileID);
7640 ntStatus = AFSLocateHashEntry( pDevExt->Specific.RDR.VolumeTree.TreeHead,
7642 (AFSBTreeEntry **)&pVolumeCB);
7644 if( pVolumeCB != NULL)
7647 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7649 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7650 AFS_TRACE_LEVEL_VERBOSE,
7651 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7656 AFSReleaseResource( &pDevExt->Specific.RDR.VolumeTreeLock);
7658 if( !NT_SUCCESS( ntStatus) ||
7661 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7664 if( AFSIsVolumeFID( &GetStatusInfo->FileID))
7667 pObjectInfo = &pVolumeCB->ObjectInformation;
7669 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7671 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7676 AFSAcquireShared( pVolumeCB->ObjectInfoTree.TreeLock,
7679 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7681 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7682 AFS_TRACE_LEVEL_VERBOSE,
7683 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7687 ullIndex = AFSCreateLowIndex( &GetStatusInfo->FileID);
7689 ntStatus = AFSLocateHashEntry( pVolumeCB->ObjectInfoTree.TreeHead,
7691 (AFSBTreeEntry **)&pObjectInfo);
7693 if( pObjectInfo != NULL)
7697 // Reference the node so it won't be torn down
7700 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7702 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
7703 AFS_TRACE_LEVEL_VERBOSE,
7704 "AFSGetObjectStatus Increment count on object %08lX Cnt %d\n",
7709 AFSReleaseResource( pVolumeCB->ObjectInfoTree.TreeLock);
7711 if( !NT_SUCCESS( ntStatus) ||
7712 pObjectInfo == NULL)
7714 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7721 if( GetStatusInfo->FileNameLength == 0 ||
7722 InputBufferLength < (ULONG)(FIELD_OFFSET( AFSGetStatusInfoCB, FileName) + GetStatusInfo->FileNameLength))
7724 try_return( ntStatus = STATUS_INVALID_PARAMETER);
7727 uniFullPathName.Length = GetStatusInfo->FileNameLength;
7728 uniFullPathName.MaximumLength = uniFullPathName.Length;
7730 uniFullPathName.Buffer = (WCHAR *)GetStatusInfo->FileName;
7733 // This name should begin with the \afs server so parse it off and check it
7736 FsRtlDissectName( uniFullPathName,
7740 if( RtlCompareUnicodeString( &uniComponentName,
7744 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7745 AFS_TRACE_LEVEL_ERROR,
7746 "AFSGetObjectStatus Name %wZ contains invalid server name\n",
7749 try_return( ntStatus = STATUS_OBJECT_PATH_INVALID);
7752 uniFullPathName = uniRemainingPath;
7754 uniParsedName = uniFullPathName;
7760 pNameArray = AFSInitNameArray( AFSGlobalRoot->DirectoryCB,
7763 if( pNameArray == NULL)
7765 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
7768 pVolumeCB = AFSGlobalRoot;
7770 pParentDirEntry = AFSGlobalRoot->DirectoryCB;
7773 // Increment the ref count on the volume and dir entry for correct processing below
7776 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
7778 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7779 AFS_TRACE_LEVEL_VERBOSE,
7780 "AFSGetObjectStatus Increment count on volume %08lX Cnt %d\n",
7784 lCount = InterlockedIncrement( &pParentDirEntry->OpenReferenceCount);
7786 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7787 AFS_TRACE_LEVEL_VERBOSE,
7788 "AFSGetObjectStatus Increment count on %wZ DE %p Ccb %p Cnt %d\n",
7789 &pParentDirEntry->NameInformation.FileName,
7794 ntStatus = AFSLocateNameEntry( NULL,
7799 AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
7800 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL,
7806 if( !NT_SUCCESS( ntStatus))
7810 // The volume lock was released on failure above
7811 // Except for STATUS_OBJECT_NAME_NOT_FOUND
7814 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
7817 if( pVolumeCB != NULL)
7820 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7822 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7823 AFS_TRACE_LEVEL_VERBOSE,
7824 "AFSGetObjectStatus Decrement count on volume %08lX Cnt %d\n",
7829 if( pDirectoryEntry != NULL)
7832 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7834 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7835 AFS_TRACE_LEVEL_VERBOSE,
7836 "AFSGetObjectStatus Decrement1 count on %wZ DE %p Ccb %p Cnt %d\n",
7837 &pDirectoryEntry->NameInformation.FileName,
7845 lCount = InterlockedDecrement( &pParentDirEntry->OpenReferenceCount);
7847 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
7848 AFS_TRACE_LEVEL_VERBOSE,
7849 "AFSGetObjectStatus Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
7850 &pParentDirEntry->NameInformation.FileName,
7859 try_return( ntStatus);
7863 // Remove the reference made above
7866 lCount = InterlockedDecrement( &pDirectoryEntry->OpenReferenceCount);
7868 pObjectInfo = pDirectoryEntry->ObjectInformation;
7870 lCount = InterlockedIncrement( &pObjectInfo->ObjectReferenceCount);
7872 if( pVolumeCB != NULL)
7875 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
7877 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
7878 AFS_TRACE_LEVEL_VERBOSE,
7879 "AFSRetrieveFileAttributes Decrement2 count on volume %08lX Cnt %d\n",
7881 pVolumeCB->VolumeReferenceCount);
7886 // At this point we have an object info block, return the information
7889 StatusInfo->FileId = pObjectInfo->FileId;
7891 StatusInfo->TargetFileId = pObjectInfo->TargetFileId;
7893 StatusInfo->Expiration = pObjectInfo->Expiration;
7895 StatusInfo->DataVersion = pObjectInfo->DataVersion;
7897 StatusInfo->FileType = pObjectInfo->FileType;
7899 StatusInfo->ObjectFlags = pObjectInfo->Flags;
7901 StatusInfo->CreationTime = pObjectInfo->CreationTime;
7903 StatusInfo->LastAccessTime = pObjectInfo->LastAccessTime;
7905 StatusInfo->LastWriteTime = pObjectInfo->LastWriteTime;
7907 StatusInfo->ChangeTime = pObjectInfo->ChangeTime;
7909 StatusInfo->FileAttributes = pObjectInfo->FileAttributes;
7911 StatusInfo->EndOfFile = pObjectInfo->EndOfFile;
7913 StatusInfo->AllocationSize = pObjectInfo->AllocationSize;
7915 StatusInfo->EaSize = pObjectInfo->EaSize;
7917 StatusInfo->Links = pObjectInfo->Links;
7920 // Return the information length
7923 *ReturnLength = sizeof( AFSStatusInfoCB);
7927 if( pObjectInfo != NULL)
7930 lCount = InterlockedDecrement( &pObjectInfo->ObjectReferenceCount);
7933 if( pNameArray != NULL)
7936 AFSFreeNameArray( pNameArray);
7944 AFSCheckSymlinkAccess( IN AFSDirectoryCB *ParentDirectoryCB,
7945 IN UNICODE_STRING *ComponentName)
7948 NTSTATUS ntStatus = STATUS_SUCCESS;
7949 AFSDirectoryCB *pDirEntry = NULL;
7957 // Search for the entry in the parent
7960 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7961 AFS_TRACE_LEVEL_VERBOSE_2,
7962 "AFSCheckSymlinkAccess Searching for entry %wZ case sensitive\n",
7965 ulCRC = AFSGenerateCRC( ComponentName,
7968 AFSAcquireShared( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock,
7971 AFSLocateCaseSensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
7975 if( pDirEntry == NULL)
7979 // Missed so perform a case insensitive lookup
7982 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
7983 AFS_TRACE_LEVEL_VERBOSE_2,
7984 "AFSCheckSymlinkAccess Searching for entry %wZ case insensitive\n",
7987 ulCRC = AFSGenerateCRC( ComponentName,
7990 AFSLocateCaseInsensitiveDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
7994 if( pDirEntry == NULL)
7998 // OK, if this component is a valid short name then try
7999 // a lookup in the short name tree
8002 if( RtlIsNameLegalDOS8Dot3( ComponentName,
8007 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8008 AFS_TRACE_LEVEL_VERBOSE_2,
8009 "AFSCheckSymlinkAccess Searching for entry %wZ short name\n",
8012 AFSLocateShortNameDirEntry( ParentDirectoryCB->ObjectInformation->Specific.Directory.ShortNameTree,
8019 if( pDirEntry != NULL)
8021 lCount = InterlockedIncrement( &pDirEntry->OpenReferenceCount);
8024 AFSReleaseResource( ParentDirectoryCB->ObjectInformation->Specific.Directory.DirectoryNodeHdr.TreeLock);
8026 if( pDirEntry == NULL)
8029 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8030 AFS_TRACE_LEVEL_VERBOSE_2,
8031 "AFSCheckSymlinkAccess Failed to locate entry %wZ\n",
8034 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
8038 // We have the symlink object but previously failed to process it so return access
8042 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
8043 AFS_TRACE_LEVEL_VERBOSE_2,
8044 "AFSCheckSymlinkAccess Failing symlink access to entry %wZ REPARSE_POINT_NOT_RESOLVED\n",
8047 ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
8049 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
8060 AFSRetrieveFinalComponent( IN UNICODE_STRING *FullPathName,
8061 OUT UNICODE_STRING *ComponentName)
8064 NTSTATUS ntStatus = STATUS_SUCCESS;
8065 UNICODE_STRING uniFullPathName, uniRemainingPath, uniComponentName;
8067 uniFullPathName = *FullPathName;
8072 FsRtlDissectName( uniFullPathName,
8076 if( uniRemainingPath.Length == 0)
8081 uniFullPathName = uniRemainingPath;
8084 if( uniComponentName.Length > 0)
8086 *ComponentName = uniComponentName;
8093 AFSDumpTraceFiles_Default()
8099 AFSValidNameFormat( IN UNICODE_STRING *FileName)
8102 BOOLEAN bIsValidName = TRUE;
8108 while( usIndex < FileName->Length/sizeof( WCHAR))
8111 if( FileName->Buffer[ usIndex] == L':' ||
8112 FileName->Buffer[ usIndex] == L'*' ||
8113 FileName->Buffer[ usIndex] == L'?' ||
8114 FileName->Buffer[ usIndex] == L'"' ||
8115 FileName->Buffer[ usIndex] == L'<' ||
8116 FileName->Buffer[ usIndex] == L'>')
8118 bIsValidName = FALSE;
8126 return bIsValidName;
8130 AFSCreateDefaultSecurityDescriptor()
8133 NTSTATUS ntStatus = STATUS_SUCCESS;
8135 ULONG ulSACLSize = 0;
8136 SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
8137 ULONG ulACESize = 0;
8138 SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
8139 ULONG ulSDLength = 0;
8140 SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
8141 PSID pWorldSID = NULL;
8142 ULONG *pulSubAuthority = NULL;
8143 ULONG ulWorldSIDLEngth = 0;
8148 ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
8150 pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
8152 AFS_GENERIC_MEMORY_29_TAG);
8154 if( pWorldSID == NULL)
8156 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
8157 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8160 RtlZeroMemory( pWorldSID,
8163 RtlInitializeSid( pWorldSID,
8164 &SeWorldSidAuthority,
8167 pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
8168 *pulSubAuthority = SECURITY_WORLD_RID;
8170 if( AFSRtlSetSaclSecurityDescriptor == NULL)
8173 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor == NULL\n");
8178 ulACESize = sizeof( SYSTEM_MANDATORY_LABEL_ACE) + 128;
8180 pACE = (SYSTEM_MANDATORY_LABEL_ACE *)ExAllocatePoolWithTag( PagedPool,
8182 AFS_GENERIC_MEMORY_29_TAG);
8187 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8189 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8192 RtlZeroMemory( pACE,
8195 pACE->Header.AceFlags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
8196 pACE->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
8197 pACE->Header.AceSize = FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + (USHORT)RtlLengthSid( SeExports->SeLowMandatorySid);
8198 pACE->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
8200 RtlCopySid( RtlLengthSid( SeExports->SeLowMandatorySid),
8202 SeExports->SeLowMandatorySid);
8204 ulSACLSize = sizeof(ACL) + RtlLengthSid( SeExports->SeLowMandatorySid) +
8205 FIELD_OFFSET( SYSTEM_MANDATORY_LABEL_ACE, SidStart) + ulACESize;
8207 pSACL = (PACL)ExAllocatePoolWithTag( PagedPool,
8209 AFS_GENERIC_MEMORY_29_TAG);
8214 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_29_TAG\n");
8216 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8219 ntStatus = RtlCreateAcl( pSACL,
8223 if( !NT_SUCCESS( ntStatus))
8226 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateAcl ntStatus %08lX\n",
8229 try_return( ntStatus);
8232 ntStatus = RtlAddAce( pSACL,
8236 pACE->Header.AceSize);
8238 if( !NT_SUCCESS( ntStatus))
8241 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAddAce ntStatus %08lX\n",
8244 try_return( ntStatus);
8248 pSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8249 sizeof( SECURITY_DESCRIPTOR),
8250 AFS_GENERIC_MEMORY_27_TAG);
8252 if( pSecurityDescr == NULL)
8255 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8257 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8260 ntStatus = RtlCreateSecurityDescriptor( pSecurityDescr,
8261 SECURITY_DESCRIPTOR_REVISION);
8263 if( !NT_SUCCESS( ntStatus))
8266 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlCreateSecurityDescriptor ntStatus %08lX\n",
8269 try_return( ntStatus);
8272 if( AFSRtlSetSaclSecurityDescriptor != NULL)
8274 ntStatus = AFSRtlSetSaclSecurityDescriptor( pSecurityDescr,
8279 if( !NT_SUCCESS( ntStatus))
8282 AFSPrint( "AFSCreateDefaultSecurityDescriptor AFSRtlSetSaclSecurityDescriptor ntStatus %08lX\n",
8285 try_return( ntStatus);
8290 // Add in the group and owner to the SD
8293 if( AFSRtlSetGroupSecurityDescriptor != NULL)
8295 ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
8299 if( !NT_SUCCESS( ntStatus))
8302 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
8305 try_return( ntStatus);
8309 ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
8313 if( !NT_SUCCESS( ntStatus))
8316 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
8319 try_return( ntStatus);
8322 if( !RtlValidSecurityDescriptor( pSecurityDescr))
8325 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlValidSecurityDescriptor NOT\n");
8327 try_return( ntStatus = STATUS_INVALID_PARAMETER);
8330 pRelativeSecurityDescr = (SECURITY_DESCRIPTOR *)ExAllocatePoolWithTag( NonPagedPool,
8332 AFS_GENERIC_MEMORY_27_TAG);
8334 if( pRelativeSecurityDescr == NULL)
8337 AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate AFS_GENERIC_MEMORY_27_TAG\n");
8339 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
8342 ulSDLength = PAGE_SIZE;
8344 ntStatus = RtlAbsoluteToSelfRelativeSD( pSecurityDescr,
8345 pRelativeSecurityDescr,
8348 if( !NT_SUCCESS( ntStatus))
8351 AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlAbsoluteToSelfRelativeSD ntStatus %08lX\n",
8354 try_return( ntStatus);
8357 AFSDefaultSD = pRelativeSecurityDescr;
8361 if( !NT_SUCCESS( ntStatus))
8364 if( pRelativeSecurityDescr != NULL)
8366 ExFreePool( pRelativeSecurityDescr);
8370 if( pSecurityDescr != NULL)
8372 ExFreePool( pSecurityDescr);
8385 if( pWorldSID != NULL)
8387 ExFreePool( pWorldSID);
8395 AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
8396 OUT UNICODE_STRING *ParentPath)
8401 *ParentPath = *FullFileName;
8404 // If the final character is a \, jump over it
8407 if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
8409 ParentPath->Length -= sizeof( WCHAR);
8412 while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
8414 ParentPath->Length -= sizeof( WCHAR);
8418 // And the separator
8421 ParentPath->Length -= sizeof( WCHAR);
8427 AFSRetrieveValidAuthGroup( IN AFSFcb *Fcb,
8428 IN AFSObjectInfoCB *ObjectInfo,
8429 IN BOOLEAN WriteAccess,
8430 OUT GUID *AuthGroup)
8433 NTSTATUS ntStatus = STATUS_SUCCESS;
8434 GUID stAuthGroup, stZeroAuthGroup;
8435 BOOLEAN bFoundAuthGroup = FALSE;
8436 AFSCcb *pCcb = NULL;
8442 RtlZeroMemory( &stAuthGroup,
8445 RtlZeroMemory( &stZeroAuthGroup,
8451 if( ObjectInfo != NULL &&
8452 ObjectInfo->Fcb != NULL)
8454 pFcb = ObjectInfo->Fcb;
8461 AFSAcquireShared( &Fcb->NPFcb->CcbListLock,
8464 pCcb = Fcb->CcbListHead;
8466 while( pCcb != NULL)
8470 pCcb->GrantedAccess & FILE_WRITE_DATA)
8472 RtlCopyMemory( &stAuthGroup,
8476 bFoundAuthGroup = TRUE;
8480 else if( pCcb->GrantedAccess & FILE_READ_DATA)
8483 // At least get the read-only access
8486 RtlCopyMemory( &stAuthGroup,
8490 bFoundAuthGroup = TRUE;
8493 pCcb = (AFSCcb *)pCcb->ListEntry.fLink;
8496 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
8499 if( !bFoundAuthGroup)
8502 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
8503 (ULONGLONG)PsGetCurrentThreadId(),
8506 if( RtlCompareMemory( &stZeroAuthGroup,
8508 sizeof( GUID)) == sizeof( GUID))
8511 DbgPrint("AFSRetrieveValidAuthGroup Failed to locate PAG\n");
8513 try_return( ntStatus = STATUS_ACCESS_DENIED);
8517 RtlCopyMemory( AuthGroup,