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: AFSFcbSupport.cpp
39 #include "AFSCommon.h"
42 // Function: AFSInitFcb
46 // This function performs Fcb initialization
50 // Return Fcb->NPFcb->Resource held exclusive
54 AFSInitFcb( IN AFSDirectoryCB *DirEntry)
57 NTSTATUS ntStatus = STATUS_SUCCESS;
59 AFSNonPagedFcb *pNPFcb = NULL;
60 USHORT usFcbLength = 0;
61 AFSObjectInfoCB *pObjectInfo = NULL;
62 AFSVolumeCB *pVolumeCB = NULL;
67 pObjectInfo = DirEntry->ObjectInformation;
69 if ( pObjectInfo->Fcb != NULL)
72 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
75 try_return( ntStatus = STATUS_SUCCESS);
78 pVolumeCB = pObjectInfo->VolumeCB;
81 // Allocate the Fcb and the nonpaged portion of the Fcb.
84 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
85 AFS_TRACE_LEVEL_VERBOSE_2,
86 "AFSInitFcb Initializing fcb for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
87 &DirEntry->NameInformation.FileName,
88 pObjectInfo->FileId.Cell,
89 pObjectInfo->FileId.Volume,
90 pObjectInfo->FileId.Vnode,
91 pObjectInfo->FileId.Unique);
93 usFcbLength = sizeof( AFSFcb);
95 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
97 AFS_FCB_ALLOCATION_TAG);
102 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
103 AFS_TRACE_LEVEL_ERROR,
104 "AFSInitFcb Failed to allocate fcb\n");
106 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
112 pFcb->Header.NodeByteSize = usFcbLength;
114 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
115 sizeof( AFSNonPagedFcb),
116 AFS_FCB_NP_ALLOCATION_TAG);
121 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
122 AFS_TRACE_LEVEL_ERROR,
123 "AFSInitFcb Failed to allocate non-paged fcb\n");
125 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
128 RtlZeroMemory( pNPFcb,
129 sizeof( AFSNonPagedFcb));
131 pNPFcb->Size = sizeof( AFSNonPagedFcb);
133 pNPFcb->Type = AFS_NON_PAGED_FCB;
136 // Initialize the advanced header
139 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
141 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
144 // OK, initialize the entry
147 ExInitializeResourceLite( &pNPFcb->Resource);
149 ExInitializeResourceLite( &pNPFcb->PagingResource);
151 ExInitializeResourceLite( &pNPFcb->SectionObjectResource);
153 ExInitializeResourceLite( &pNPFcb->CcbListLock);
156 // Grab the Fcb for processing
159 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
160 AFS_TRACE_LEVEL_VERBOSE,
161 "AFSInitFcb Acquiring Fcb lock %p EXCL %08lX\n",
163 PsGetCurrentThread());
165 AFSAcquireExcl( &pNPFcb->Resource,
168 pFcb->Header.Resource = &pNPFcb->Resource;
170 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
172 pFcb->NPFcb = pNPFcb;
175 // Set type specific information
178 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
182 // Reset the type to a directory type
185 pFcb->Header.NodeTypeCode = AFS_DIRECTORY_FCB;
187 else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
190 pFcb->Header.NodeTypeCode = AFS_FILE_FCB;
193 // Initialize the file specific information
196 FsRtlInitializeFileLock( &pFcb->Specific.File.FileLock,
201 // Initialize the header file sizes to our dir entry information
204 pFcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
205 pFcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
206 pFcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
209 // Initialize the Extents resources and so forth. The
210 // quiescent state is that no one has the extents for
211 // IO (do the extents are not busy) and there is no
212 // extents request outstanding (and hence the "last
213 // one" is complete).
215 ExInitializeResourceLite( &pNPFcb->Specific.File.ExtentsResource );
217 KeInitializeEvent( &pNPFcb->Specific.File.ExtentsRequestComplete,
221 for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
223 InitializeListHead(&pFcb->Specific.File.ExtentsLists[i]);
226 pNPFcb->Specific.File.DirtyListHead = NULL;
227 pNPFcb->Specific.File.DirtyListTail = NULL;
229 ExInitializeResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
231 KeInitializeEvent( &pNPFcb->Specific.File.FlushEvent,
232 SynchronizationEvent,
235 KeInitializeEvent( &pNPFcb->Specific.File.QueuedFlushEvent,
239 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
242 pFcb->Header.NodeTypeCode = AFS_SPECIAL_SHARE_FCB;
244 else if( pObjectInfo->FileType == AFS_FILE_TYPE_PIOCTL)
247 pFcb->Header.NodeTypeCode = AFS_IOCTL_FCB;
249 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
252 pFcb->Header.NodeTypeCode = AFS_SYMBOLIC_LINK_FCB;
254 else if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
257 pFcb->Header.NodeTypeCode = AFS_MOUNT_POINT_FCB;
259 else if( pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
261 pFcb->Header.NodeTypeCode = AFS_DFS_LINK_FCB;
265 pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
268 pFcb->ObjectInformation = pObjectInfo;
270 AFSAcquireShared( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
273 // Swap the allocated FCB into the ObjectInformation structure if it
274 // does not already have one.
277 if ( InterlockedCompareExchangePointer( (PVOID *)&pObjectInfo->Fcb, pFcb, NULL) != NULL)
280 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
281 AFS_TRACE_LEVEL_WARNING,
282 "AFSInitFcb Raced Fcb %p pFcb %p Name %wZ\n",
285 &DirEntry->NameInformation.FileName);
287 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
288 AFS_TRACE_LEVEL_VERBOSE,
289 "AFSInitFcb Acquiring Fcb lock %p EXCL %08lX\n",
290 &pObjectInfo->Fcb->NPFcb->Resource,
291 PsGetCurrentThread());
293 AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
295 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
298 try_return( ntStatus = STATUS_REPARSE);
301 AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
303 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
304 AFS_TRACE_LEVEL_VERBOSE,
305 "AFSInitFcb Initialized Fcb %p Name %wZ\n",
307 &DirEntry->NameInformation.FileName);
311 if( ntStatus != STATUS_SUCCESS)
314 if ( !NT_SUCCESS( ntStatus))
317 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
318 AFS_TRACE_LEVEL_ERROR,
319 "AFSInitFcb Failed to initialize fcb Status %08lX\n",
329 AFSReleaseResource( &pNPFcb->Resource);
331 FsRtlTeardownPerStreamContexts( &pFcb->Header);
333 if ( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
336 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
338 ExDeleteResourceLite( &pNPFcb->Specific.File.ExtentsResource);
340 ExDeleteResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
343 ExDeleteResourceLite( &pNPFcb->SectionObjectResource);
345 ExDeleteResourceLite( &pNPFcb->PagingResource);
347 ExDeleteResourceLite( &pNPFcb->CcbListLock);
349 ExDeleteResourceLite( &pNPFcb->Resource);
351 AFSExFreePoolWithTag( pNPFcb, AFS_FCB_NP_ALLOCATION_TAG);
354 AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
363 AFSInitVolume( IN GUID *AuthGroup,
364 IN AFSFileID *RootFid,
365 OUT AFSVolumeCB **VolumeCB)
368 NTSTATUS ntStatus = STATUS_SUCCESS;
369 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
370 AFSNonPagedVolumeCB *pNonPagedVcb = NULL;
371 AFSVolumeCB *pVolumeCB = NULL;
372 AFSNonPagedObjectInfoCB *pNonPagedObject = NULL;
373 ULONGLONG ullIndex = 0;
374 BOOLEAN bReleaseLocks = FALSE;
375 AFSVolumeInfoCB stVolumeInformation = {0};
376 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
383 // Before grabbing any locks ask the service for the volume information
384 // This may be a waste but we need to get this information prior to
385 // taking any volume tree locks. Don't do this for any 'reserved' cell entries
388 if( RootFid->Cell != 0)
391 RtlZeroMemory( &stVolumeInformation,
392 sizeof( AFSVolumeInfoCB));
394 ntStatus = AFSRetrieveVolumeInformation( AuthGroup,
396 &stVolumeInformation);
398 if( !NT_SUCCESS( ntStatus))
401 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
402 AFS_TRACE_LEVEL_ERROR,
403 "AFSInitVolume AFSRetrieveVolumeInformation(RootFid) failure %08lX\n",
406 try_return( ntStatus);
410 // Grab our tree locks and see if we raced with someone else
413 AFSAcquireExcl( pDeviceExt->Specific.RDR.VolumeTree.TreeLock,
416 AFSAcquireExcl( &pDeviceExt->Specific.RDR.VolumeListLock,
419 bReleaseLocks = TRUE;
421 ullIndex = AFSCreateHighIndex( RootFid);
423 ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
425 (AFSBTreeEntry **)&pVolumeCB);
427 if( NT_SUCCESS( ntStatus) &&
432 // So we don't lock with an invalidation call ...
435 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
437 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
438 AFS_TRACE_LEVEL_VERBOSE,
439 "AFSInitVolume Increment count on volume %p Cnt %d\n",
443 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
445 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
447 bReleaseLocks = FALSE;
449 AFSAcquireExcl( pVolumeCB->VolumeLock,
452 *VolumeCB = pVolumeCB;
454 try_return( ntStatus);
458 // Revert our status from the above call back to success.
461 ntStatus = STATUS_SUCCESS;
465 // For the global root we allocate out volume node and insert it
466 // into the volume tree ...
469 pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( PagedPool,
470 sizeof( AFSVolumeCB),
471 AFS_VCB_ALLOCATION_TAG);
473 if( pVolumeCB == NULL)
476 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
477 AFS_TRACE_LEVEL_ERROR,
478 "AFSInitVolume Failed to allocate the root volume cb\n");
480 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
483 RtlZeroMemory( pVolumeCB,
484 sizeof( AFSVolumeCB));
487 // The non paged portion
490 pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
491 sizeof( AFSNonPagedVolumeCB),
492 AFS_VCB_NP_ALLOCATION_TAG);
494 if( pNonPagedVcb == NULL)
497 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
498 AFS_TRACE_LEVEL_ERROR,
499 "AFSInitVolume Failed to allocate the root non paged volume cb\n");
501 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
504 RtlZeroMemory( pNonPagedVcb,
505 sizeof( AFSNonPagedVolumeCB));
507 ExInitializeResourceLite( &pNonPagedVcb->VolumeLock);
509 ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
511 pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
512 sizeof( AFSNonPagedObjectInfoCB),
513 AFS_NP_OBJECT_INFO_TAG);
515 if( pNonPagedObject == NULL)
518 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
519 AFS_TRACE_LEVEL_ERROR,
520 "AFSInitVolume Failed to allocate the root non paged object cb\n");
522 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
525 RtlZeroMemory( pNonPagedObject,
526 sizeof( AFSNonPagedObjectInfoCB));
528 ExInitializeResourceLite( &pNonPagedObject->ObjectInfoLock);
530 ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
532 pVolumeCB->NonPagedVcb = pNonPagedVcb;
534 pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject;
536 pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock;
538 pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock;
540 pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
543 // Bias our reference by 1
546 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
547 AFS_TRACE_LEVEL_VERBOSE,
548 "AFSInitVolume Initializing count (2) on volume %p\n",
551 pVolumeCB->VolumeReferenceCount = 2;
553 AFSAcquireExcl( pVolumeCB->VolumeLock,
556 pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
557 sizeof( AFSDirectoryCB) + sizeof( WCHAR),
560 if( pVolumeCB->DirectoryCB == NULL)
563 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
566 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
567 AFS_TRACE_LEVEL_VERBOSE,
568 "AFSInitVolume AFS_DIR_ENTRY_TAG allocated %p\n",
569 pVolumeCB->DirectoryCB);
571 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
572 sizeof( AFSNonPagedDirectoryCB),
573 AFS_DIR_ENTRY_NP_TAG);
575 if( pNonPagedDirEntry == NULL)
578 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
581 RtlZeroMemory( pVolumeCB->DirectoryCB,
582 sizeof( AFSDirectoryCB) + sizeof( WCHAR));
584 RtlZeroMemory( pNonPagedDirEntry,
585 sizeof( AFSNonPagedDirectoryCB));
587 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
589 pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry;
592 // Initialize the non-paged portion of the directory entry
595 KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime);
596 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime);
597 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime);
599 pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY;
601 SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME);
603 pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell;
604 pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume;
605 pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode;
606 pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique;
607 pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash;
609 pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
611 pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR);
613 pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length;
615 pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB));
617 RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer,
622 // Copy in the volume information retrieved above
625 RtlCopyMemory( &pVolumeCB->VolumeInformation,
626 &stVolumeInformation,
627 sizeof( AFSVolumeInfoCB));
633 pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
635 pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
638 // Insert the volume into our volume tree. Don't insert any reserved entries
641 if( RootFid->Cell != 0)
644 pVolumeCB->TreeEntry.HashIndex = ullIndex;
646 if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL)
649 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
651 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
656 if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
657 &pVolumeCB->TreeEntry)))
660 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
664 if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
667 pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB;
672 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB;
674 pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail;
677 pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB;
680 *VolumeCB = pVolumeCB;
684 if( !NT_SUCCESS( ntStatus))
687 if( pNonPagedVcb != NULL)
690 AFSReleaseResource( pVolumeCB->VolumeLock);
692 ExDeleteResourceLite( &pNonPagedVcb->VolumeLock);
694 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
696 AFSExFreePoolWithTag( pNonPagedVcb, AFS_VCB_NP_ALLOCATION_TAG);
699 if( pNonPagedObject != NULL)
702 ExDeleteResourceLite( &pNonPagedObject->ObjectInfoLock);
704 AFSExFreePoolWithTag( pNonPagedObject, AFS_NP_OBJECT_INFO_TAG);
707 if( pVolumeCB != NULL)
710 if( pVolumeCB->DirectoryCB != NULL)
713 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
714 AFS_TRACE_LEVEL_VERBOSE,
715 "AFSInitVolume AFS_DIR_ENTRY_TAG deallocating %p\n",
716 pVolumeCB->DirectoryCB);
718 AFSExFreePoolWithTag( pVolumeCB->DirectoryCB, AFS_DIR_ENTRY_TAG);
721 AFSExFreePoolWithTag( pVolumeCB, AFS_VCB_ALLOCATION_TAG);
724 if( pNonPagedDirEntry != NULL)
727 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
729 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
736 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
738 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
746 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
749 NTSTATUS ntStatus = STATUS_SUCCESS;
750 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
756 // Remove the volume from the tree and list
757 // Don't process the list information for reserved entries
760 if( VolumeCB->ObjectInformation.FileId.Cell != 0)
763 if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE))
766 AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
767 &VolumeCB->TreeEntry);
770 if( VolumeCB->ListEntry.fLink == NULL)
773 pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink;
775 if( pDeviceExt->Specific.RDR.VolumeListTail != NULL)
778 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL;
784 ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink;
787 if( VolumeCB->ListEntry.bLink == NULL)
790 pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink;
792 if( pDeviceExt->Specific.RDR.VolumeListHead != NULL)
795 pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL;
801 ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink;
806 // Remove any PIOctl objects we have
809 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL)
812 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
815 AFSAcquireExcl( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
818 AFSRemoveFcb( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
820 AFSReleaseResource( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
823 AFSDeleteObjectInfo( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
825 ExDeleteResourceLite( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
827 AFSExFreePoolWithTag( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
829 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
830 AFS_TRACE_LEVEL_VERBOSE,
831 "AFSRemoveVolume (pioctl) AFS_DIR_ENTRY_TAG deallocating %p\n",
832 VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB);
834 AFSExFreePoolWithTag( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
837 if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
841 // Release the fid in the service
844 AFSReleaseFid( &VolumeCB->ObjectInformation.FileId);
848 // Free up the memory
851 if( VolumeCB->NonPagedVcb != NULL)
854 if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
856 AFSReleaseResource( VolumeCB->VolumeLock);
859 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock);
861 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
863 AFSExFreePoolWithTag( VolumeCB->NonPagedVcb, AFS_VCB_NP_ALLOCATION_TAG);
866 if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
869 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
871 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
873 AFSExFreePoolWithTag( VolumeCB->ObjectInformation.NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
876 if( VolumeCB->DirectoryCB != NULL)
879 if( VolumeCB->DirectoryCB->NonPaged != NULL)
882 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
884 AFSExFreePoolWithTag( VolumeCB->DirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
887 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
888 AFS_TRACE_LEVEL_VERBOSE,
889 "AFSRemoveVolume AFS_DIR_ENTRY_TAG deallocating %p\n",
890 VolumeCB->DirectoryCB);
892 AFSExFreePoolWithTag( VolumeCB->DirectoryCB, AFS_DIR_ENTRY_TAG);
895 AFSExFreePoolWithTag( VolumeCB, AFS_VCB_ALLOCATION_TAG);
903 // Function: AFSInitRootFcb
907 // This function performs Root node Fcb initialization
911 // A status is returned for the function
915 AFSInitRootFcb( IN ULONGLONG ProcessID,
916 IN AFSVolumeCB *VolumeCB)
919 UNREFERENCED_PARAMETER(ProcessID);
920 NTSTATUS ntStatus = STATUS_SUCCESS;
922 AFSNonPagedFcb *pNPFcb = NULL;
928 // Initialize the root fcb
931 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
933 AFS_FCB_ALLOCATION_TAG);
938 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
939 AFS_TRACE_LEVEL_ERROR,
940 "AFSInitRootFcb Failed to allocate the root fcb\n");
942 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
948 pFcb->Header.NodeByteSize = sizeof( AFSFcb);
950 pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;
952 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
953 sizeof( AFSNonPagedFcb),
954 AFS_FCB_NP_ALLOCATION_TAG);
959 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
960 AFS_TRACE_LEVEL_ERROR,
961 "AFSInitRootFcb Failed to allocate the non-paged fcb\n");
963 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
966 RtlZeroMemory( pNPFcb,
967 sizeof( AFSNonPagedFcb));
969 pNPFcb->Size = sizeof( AFSNonPagedFcb);
971 pNPFcb->Type = AFS_NON_PAGED_FCB;
974 // OK, initialize the entry
977 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
979 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
981 ExInitializeResourceLite( &pNPFcb->Resource);
983 ExInitializeResourceLite( &pNPFcb->PagingResource);
985 ExInitializeResourceLite( &pNPFcb->SectionObjectResource);
987 ExInitializeResourceLite( &pNPFcb->CcbListLock);
989 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
990 AFS_TRACE_LEVEL_VERBOSE,
991 "AFSInitRootFcb Acquiring Fcb lock %p EXCL %08lX\n",
993 PsGetCurrentThread());
995 AFSAcquireExcl( &pNPFcb->Resource,
998 pFcb->Header.Resource = &pNPFcb->Resource;
1000 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
1002 pFcb->NPFcb = pNPFcb;
1005 // Save the root Fcb in the VolumeCB
1008 pFcb->ObjectInformation = &VolumeCB->ObjectInformation;
1010 VolumeCB->ObjectInformation.VolumeCB = VolumeCB;
1012 AFSAcquireShared( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock,
1015 // Swap the allocated FCB into the ObjectInformation structure if it
1016 // does not already have one.
1019 if ( InterlockedCompareExchangePointer( (PVOID *)&VolumeCB->ObjectInformation.Fcb, pFcb, NULL) != NULL)
1022 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1023 AFS_TRACE_LEVEL_WARNING,
1024 "AFSInitRootFcb Raced Fcb %p pFcb %p\n",
1025 VolumeCB->ObjectInformation.Fcb,
1028 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1029 AFS_TRACE_LEVEL_VERBOSE,
1030 "AFSInitRootFcb Acquiring Fcb lock %p EXCL %08lX\n",
1031 &VolumeCB->ObjectInformation.Fcb->NPFcb->Resource,
1032 PsGetCurrentThread());
1034 AFSReleaseResource( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
1036 AFSAcquireExcl( &VolumeCB->ObjectInformation.Fcb->NPFcb->Resource,
1039 try_return( ntStatus = STATUS_REPARSE);
1042 VolumeCB->RootFcb = VolumeCB->ObjectInformation.Fcb;
1044 AFSReleaseResource( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
1046 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1047 AFS_TRACE_LEVEL_VERBOSE,
1048 "AFSInitRootFcb Initialized Fcb %p\n",
1049 &VolumeCB->ObjectInformation.Fcb);
1053 if( !NT_SUCCESS( ntStatus) ||
1054 ntStatus == STATUS_REPARSE)
1063 AFSReleaseResource( &pNPFcb->Resource);
1065 FsRtlTeardownPerStreamContexts( &pFcb->Header);
1067 ExDeleteResourceLite( &pNPFcb->SectionObjectResource);
1069 ExDeleteResourceLite( &pNPFcb->PagingResource);
1071 ExDeleteResourceLite( &pNPFcb->CcbListLock);
1073 ExDeleteResourceLite( &pNPFcb->Resource);
1075 AFSExFreePoolWithTag( pNPFcb, AFS_FCB_NP_ALLOCATION_TAG);
1078 AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
1087 // Function: AFSRemoveRootFcb
1091 // This function performs root Fcb removal/deallocation from
1092 // the provided VolumeCB object.
1100 AFSRemoveRootFcb( IN AFSVolumeCB *VolumeCB)
1104 pRootFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)&VolumeCB->ObjectInformation.Fcb,
1106 (PVOID *)&VolumeCB->ObjectInformation.Fcb);
1108 if ( pRootFcb == NULL)
1115 // The Fcb has been disconnected from the ObjectInformation block.
1116 // Clear it from the RootFcb convenience pointer.
1119 VolumeCB->RootFcb = NULL;
1121 if( pRootFcb->NPFcb != NULL)
1128 ExDeleteResourceLite( &pRootFcb->NPFcb->Resource);
1130 ExDeleteResourceLite( &pRootFcb->NPFcb->PagingResource);
1132 ExDeleteResourceLite( &pRootFcb->NPFcb->SectionObjectResource);
1134 ExDeleteResourceLite( &pRootFcb->NPFcb->CcbListLock);
1136 FsRtlTeardownPerStreamContexts( &pRootFcb->Header);
1139 // The non paged region
1142 AFSExFreePoolWithTag( pRootFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
1144 pRootFcb->NPFcb = NULL;
1148 // And the Fcb itself
1151 AFSExFreePoolWithTag( pRootFcb, AFS_FCB_ALLOCATION_TAG);
1157 // Function: AFSRemoveFcb
1161 // This function performs Fcb removal/deallocation
1165 // A status is returned for the function
1169 AFSRemoveFcb( IN AFSFcb **ppFcb)
1174 pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)ppFcb, NULL, (PVOID)(*ppFcb));
1182 ASSERT( pFcb->Header.NodeTypeCode != AFS_ROOT_FCB);
1185 // Uninitialize the file lock if it is a file
1188 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1189 AFS_TRACE_LEVEL_VERBOSE,
1190 "AFSRemoveFcb Removing Fcb %p\n",
1193 if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
1196 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
1199 // The resource we allocated
1202 ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.ExtentsResource );
1204 ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.DirtyExtentsListLock);
1207 else if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1214 // Tear down the FM specific contexts
1217 FsRtlTeardownPerStreamContexts( &pFcb->Header);
1220 // Delete the resources
1223 ExDeleteResourceLite( &pFcb->NPFcb->Resource);
1225 ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
1227 ExDeleteResourceLite( &pFcb->NPFcb->SectionObjectResource);
1229 ExDeleteResourceLite( &pFcb->NPFcb->CcbListLock);
1232 // The non paged region
1235 AFSExFreePoolWithTag( pFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
1238 // And the Fcb itself, which includes the name
1241 AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
1247 AFSInitCcb( IN OUT AFSCcb **Ccb,
1248 IN AFSDirectoryCB *DirectoryCB,
1249 IN ACCESS_MASK GrantedAccess,
1250 IN ULONG FileAccess)
1253 NTSTATUS Status = STATUS_SUCCESS;
1254 AFSCcb *pCcb = NULL;
1261 // Allocate our context control block
1264 pCcb = (AFSCcb *)AFSExAllocatePoolWithTag( PagedPool,
1266 AFS_CCB_ALLOCATION_TAG);
1271 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1272 AFS_TRACE_LEVEL_ERROR,
1273 "AFSInitCcb Failed to allocate Ccb\n");
1275 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1278 RtlZeroMemory( pCcb,
1281 pCcb->Size = sizeof( AFSCcb);
1283 pCcb->Type = AFS_CCB;
1285 pCcb->NPCcb = (AFSNonPagedCcb *)AFSExAllocatePoolWithTag( NonPagedPool,
1286 sizeof( AFSNonPagedCcb),
1287 AFS_CCB_NP_ALLOCATION_TAG);
1289 if( pCcb->NPCcb == NULL)
1292 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1293 AFS_TRACE_LEVEL_ERROR,
1294 "AFSInitCcb Failed to allocate NPCcb\n");
1296 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1299 ExInitializeResourceLite( &pCcb->NPCcb->CcbLock);
1301 pCcb->DirectoryCB = DirectoryCB;
1303 lCount = InterlockedIncrement( &pCcb->DirectoryCB->DirOpenReferenceCount);
1305 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1306 AFS_TRACE_LEVEL_VERBOSE,
1307 "AFSInitCcb Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1308 &pCcb->DirectoryCB->NameInformation.FileName,
1313 pCcb->GrantedAccess = GrantedAccess;
1315 pCcb->FileAccess = FileAccess;
1325 if( !NT_SUCCESS( Status))
1331 if ( pCcb->NPCcb != NULL)
1334 AFSExFreePoolWithTag( pCcb->NPCcb, AFS_CCB_NP_ALLOCATION_TAG);
1337 AFSExFreePoolWithTag( pCcb, AFS_CCB_ALLOCATION_TAG);
1348 // Function: AFSRemoveCcb
1352 // This function performs Ccb removal/deallocation
1360 AFSRemoveCcb( IN AFSFcb *Fcb,
1366 AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
1370 BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST))
1373 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1376 if( Ccb->ListEntry.fLink == NULL)
1379 Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink;
1381 if( Fcb->CcbListTail != NULL)
1383 Fcb->CcbListTail->ListEntry.fLink = NULL;
1388 ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink;
1391 if( Ccb->ListEntry.bLink == NULL)
1394 Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink;
1396 if( Fcb->CcbListHead != NULL)
1398 Fcb->CcbListHead->ListEntry.bLink = NULL;
1403 ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink;
1406 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
1409 if( Ccb->MaskName.Buffer != NULL)
1412 AFSExFreePoolWithTag( Ccb->MaskName.Buffer, AFS_GENERIC_MEMORY_6_TAG);
1415 if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
1418 AFSExFreePoolWithTag( Ccb->FullFileName.Buffer, 0);
1422 // If we have a name array then delete it
1425 if( Ccb->NameArray != NULL)
1428 AFSFreeNameArray( Ccb->NameArray);
1430 Ccb->NameArray = NULL;
1433 if( Ccb->DirectorySnapshot != NULL)
1436 AFSExFreePoolWithTag( Ccb->DirectorySnapshot, AFS_DIR_SNAPSHOT_TAG);
1438 Ccb->DirectorySnapshot = NULL;
1441 if( Ccb->NotifyMask.Buffer != NULL)
1444 AFSExFreePoolWithTag( Ccb->NotifyMask.Buffer, AFS_GENERIC_MEMORY_7_TAG);
1447 if ( Ccb->DirectoryCB != NULL)
1450 lCount = InterlockedDecrement( &Ccb->DirectoryCB->DirOpenReferenceCount);
1452 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1453 AFS_TRACE_LEVEL_VERBOSE,
1454 "AFSRemoveCcb Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1455 &Ccb->DirectoryCB->NameInformation.FileName,
1460 ASSERT( lCount >= 0);
1463 AFSReleaseResource( &Ccb->NPCcb->CcbLock);
1469 ExDeleteResourceLite( &Ccb->NPCcb->CcbLock);
1471 AFSExFreePoolWithTag( Ccb->NPCcb, AFS_CCB_NP_ALLOCATION_TAG);
1473 AFSExFreePoolWithTag( Ccb, AFS_CCB_ALLOCATION_TAG);
1477 AFSInsertCcb( IN AFSFcb *Fcb,
1481 NTSTATUS ntStatus = STATUS_SUCCESS;
1483 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1486 AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
1489 if( Fcb->CcbListHead == NULL)
1491 Fcb->CcbListHead = Ccb;
1495 Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb;
1497 Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail;
1500 Fcb->CcbListTail = Ccb;
1502 SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST);
1504 AFSReleaseResource( &Ccb->NPCcb->CcbLock);
1506 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);