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, *pParentObjectInfo = NULL;
62 AFSVolumeCB *pVolumeCB = NULL;
67 pObjectInfo = DirEntry->ObjectInformation;
69 pParentObjectInfo = pObjectInfo->ParentObjectInformation;
71 pVolumeCB = pObjectInfo->VolumeCB;
73 if ( pObjectInfo->Fcb != NULL)
76 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
79 try_return( ntStatus = STATUS_SUCCESS);
83 // Allocate the Fcb and the nonpaged portion of the Fcb.
86 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
87 AFS_TRACE_LEVEL_VERBOSE_2,
88 "AFSInitFcb Initializing fcb for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
89 &DirEntry->NameInformation.FileName,
90 pObjectInfo->FileId.Cell,
91 pObjectInfo->FileId.Volume,
92 pObjectInfo->FileId.Vnode,
93 pObjectInfo->FileId.Unique);
95 usFcbLength = sizeof( AFSFcb);
97 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
99 AFS_FCB_ALLOCATION_TAG);
104 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
105 AFS_TRACE_LEVEL_ERROR,
106 "AFSInitFcb Failed to allocate fcb\n");
108 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
114 pFcb->Header.NodeByteSize = usFcbLength;
116 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
117 sizeof( AFSNonPagedFcb),
118 AFS_FCB_NP_ALLOCATION_TAG);
123 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
124 AFS_TRACE_LEVEL_ERROR,
125 "AFSInitFcb Failed to allocate non-paged fcb\n");
127 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
130 RtlZeroMemory( pNPFcb,
131 sizeof( AFSNonPagedFcb));
133 pNPFcb->Size = sizeof( AFSNonPagedFcb);
135 pNPFcb->Type = AFS_NON_PAGED_FCB;
138 // Initialize the advanced header
141 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
143 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
146 // OK, initialize the entry
149 ExInitializeResourceLite( &pNPFcb->Resource);
151 ExInitializeResourceLite( &pNPFcb->PagingResource);
153 ExInitializeResourceLite( &pNPFcb->SectionObjectResource);
155 ExInitializeResourceLite( &pNPFcb->CcbListLock);
157 pFcb->Header.Resource = &pNPFcb->Resource;
159 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
162 // Grab the Fcb for processing
165 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
166 AFS_TRACE_LEVEL_VERBOSE,
167 "AFSInitFcb Acquiring Fcb lock %p EXCL %08lX\n",
169 PsGetCurrentThread());
171 AFSAcquireExcl( &pNPFcb->Resource,
174 pFcb->NPFcb = pNPFcb;
177 // Set type specific information
180 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
184 // Reset the type to a directory type
187 pFcb->Header.NodeTypeCode = AFS_DIRECTORY_FCB;
189 else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
192 pFcb->Header.NodeTypeCode = AFS_FILE_FCB;
195 // Initialize the file specific information
198 FsRtlInitializeFileLock( &pFcb->Specific.File.FileLock,
203 // Initialize the header file sizes to our dir entry information
206 pFcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
207 pFcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
208 pFcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
211 // Initialize the Extents resources and so forth. The
212 // quiescent state is that no one has the extents for
213 // IO (do the extents are not busy) and there is no
214 // extents request outstanding (and hence the "last
215 // one" is complete).
217 ExInitializeResourceLite( &pNPFcb->Specific.File.ExtentsResource );
219 KeInitializeEvent( &pNPFcb->Specific.File.ExtentsRequestComplete,
223 for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
225 InitializeListHead(&pFcb->Specific.File.ExtentsLists[i]);
228 pNPFcb->Specific.File.DirtyListHead = NULL;
229 pNPFcb->Specific.File.DirtyListTail = NULL;
231 ExInitializeResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
233 KeInitializeEvent( &pNPFcb->Specific.File.FlushEvent,
234 SynchronizationEvent,
237 KeInitializeEvent( &pNPFcb->Specific.File.QueuedFlushEvent,
241 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
244 pFcb->Header.NodeTypeCode = AFS_SPECIAL_SHARE_FCB;
246 else if( pObjectInfo->FileType == AFS_FILE_TYPE_PIOCTL)
249 pFcb->Header.NodeTypeCode = AFS_IOCTL_FCB;
251 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
254 pFcb->Header.NodeTypeCode = AFS_SYMBOLIC_LINK_FCB;
256 else if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
259 pFcb->Header.NodeTypeCode = AFS_MOUNT_POINT_FCB;
261 else if( pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
263 pFcb->Header.NodeTypeCode = AFS_DFS_LINK_FCB;
267 pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
270 pFcb->ObjectInformation = pObjectInfo;
272 AFSAcquireShared( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
275 // Swap the allocated FCB into the ObjectInformation structure if it
276 // does not already have one.
279 if ( InterlockedCompareExchangePointer( (PVOID *)&pObjectInfo->Fcb, pFcb, NULL) != NULL)
282 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
283 AFS_TRACE_LEVEL_WARNING,
284 "AFSInitFcb Raced Fcb %p pFcb %p Name %wZ\n",
287 &DirEntry->NameInformation.FileName);
289 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
290 AFS_TRACE_LEVEL_VERBOSE,
291 "AFSInitFcb Acquiring Fcb lock %p EXCL %08lX\n",
292 &pObjectInfo->Fcb->NPFcb->Resource,
293 PsGetCurrentThread());
295 AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
297 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
300 try_return( ntStatus = STATUS_REPARSE);
303 AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
305 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
306 AFS_TRACE_LEVEL_VERBOSE,
307 "AFSInitFcb Initialized Fcb %p Name %wZ\n",
309 &DirEntry->NameInformation.FileName);
313 if( ntStatus != STATUS_SUCCESS)
316 if ( !NT_SUCCESS( ntStatus))
319 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
320 AFS_TRACE_LEVEL_ERROR,
321 "AFSInitFcb Failed to initialize fcb Status %08lX\n",
331 AFSReleaseResource( &pNPFcb->Resource);
333 FsRtlTeardownPerStreamContexts( &pFcb->Header);
335 if ( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
338 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
340 ExDeleteResourceLite( &pNPFcb->Specific.File.ExtentsResource);
342 ExDeleteResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
345 ExDeleteResourceLite( &pNPFcb->SectionObjectResource);
347 ExDeleteResourceLite( &pNPFcb->PagingResource);
349 ExDeleteResourceLite( &pNPFcb->CcbListLock);
351 ExDeleteResourceLite( &pNPFcb->Resource);
353 AFSExFreePoolWithTag( pNPFcb, AFS_FCB_NP_ALLOCATION_TAG);
356 AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
365 AFSInitVolume( IN GUID *AuthGroup,
366 IN AFSFileID *RootFid,
367 OUT AFSVolumeCB **VolumeCB)
370 NTSTATUS ntStatus = STATUS_SUCCESS;
371 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
372 AFSNonPagedVolumeCB *pNonPagedVcb = NULL;
373 AFSVolumeCB *pVolumeCB = NULL;
374 AFSNonPagedObjectInfoCB *pNonPagedObject = NULL;
375 ULONGLONG ullIndex = 0;
376 BOOLEAN bReleaseLocks = FALSE;
377 AFSVolumeInfoCB stVolumeInformation = {0};
378 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
385 // Before grabbing any locks ask the service for the volume information
386 // This may be a waste but we need to get this information prior to
387 // taking any volume tree locks. Don't do this for any 'reserved' cell entries
390 if( RootFid->Cell != 0)
393 RtlZeroMemory( &stVolumeInformation,
394 sizeof( AFSVolumeInfoCB));
396 ntStatus = AFSRetrieveVolumeInformation( AuthGroup,
398 &stVolumeInformation);
400 if( !NT_SUCCESS( ntStatus))
403 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
404 AFS_TRACE_LEVEL_ERROR,
405 "AFSInitVolume AFSRetrieveVolumeInformation(RootFid) failure %08lX\n",
408 try_return( ntStatus);
412 // Grab our tree locks and see if we raced with someone else
415 AFSAcquireExcl( pDeviceExt->Specific.RDR.VolumeTree.TreeLock,
418 AFSAcquireExcl( &pDeviceExt->Specific.RDR.VolumeListLock,
421 bReleaseLocks = TRUE;
423 ullIndex = AFSCreateHighIndex( RootFid);
425 ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
427 (AFSBTreeEntry **)&pVolumeCB);
429 if( NT_SUCCESS( ntStatus) &&
434 // So we don't lock with an invalidation call ...
437 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
439 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
440 AFS_TRACE_LEVEL_VERBOSE,
441 "AFSInitVolume Increment count on volume %p Cnt %d\n",
445 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
447 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
449 bReleaseLocks = FALSE;
451 AFSAcquireExcl( pVolumeCB->VolumeLock,
454 *VolumeCB = pVolumeCB;
456 try_return( ntStatus);
460 // Revert our status from the above call back to success.
463 ntStatus = STATUS_SUCCESS;
467 // For the global root we allocate out volume node and insert it
468 // into the volume tree ...
471 pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
472 sizeof( AFSVolumeCB),
473 AFS_VCB_ALLOCATION_TAG);
475 if( pVolumeCB == NULL)
478 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
479 AFS_TRACE_LEVEL_ERROR,
480 "AFSInitVolume Failed to allocate the root volume cb\n");
482 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
485 RtlZeroMemory( pVolumeCB,
486 sizeof( AFSVolumeCB));
489 // The non paged portion
492 pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
493 sizeof( AFSNonPagedVolumeCB),
494 AFS_VCB_NP_ALLOCATION_TAG);
496 if( pNonPagedVcb == NULL)
499 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
500 AFS_TRACE_LEVEL_ERROR,
501 "AFSInitVolume Failed to allocate the root non paged volume cb\n");
503 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
506 RtlZeroMemory( pNonPagedVcb,
507 sizeof( AFSNonPagedVolumeCB));
509 ExInitializeResourceLite( &pNonPagedVcb->VolumeLock);
511 ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
513 pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
514 sizeof( AFSNonPagedObjectInfoCB),
515 AFS_NP_OBJECT_INFO_TAG);
517 if( pNonPagedObject == NULL)
520 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
521 AFS_TRACE_LEVEL_ERROR,
522 "AFSInitVolume Failed to allocate the root non paged object cb\n");
524 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
527 RtlZeroMemory( pNonPagedObject,
528 sizeof( AFSNonPagedObjectInfoCB));
530 ExInitializeResourceLite( &pNonPagedObject->ObjectInfoLock);
532 ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
534 pVolumeCB->NonPagedVcb = pNonPagedVcb;
536 pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject;
538 pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock;
540 pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock;
542 pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
545 // Bias our reference by 1
548 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
549 AFS_TRACE_LEVEL_VERBOSE,
550 "AFSInitVolume Initializing count (2) on volume %p\n",
553 pVolumeCB->VolumeReferenceCount = 2;
555 AFSAcquireExcl( pVolumeCB->VolumeLock,
558 pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
559 sizeof( AFSDirectoryCB) + sizeof( WCHAR),
562 if( pVolumeCB->DirectoryCB == NULL)
565 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
568 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
569 sizeof( AFSNonPagedDirectoryCB),
570 AFS_DIR_ENTRY_NP_TAG);
572 if( pNonPagedDirEntry == NULL)
575 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
578 RtlZeroMemory( pVolumeCB->DirectoryCB,
579 sizeof( AFSDirectoryCB) + sizeof( WCHAR));
581 RtlZeroMemory( pNonPagedDirEntry,
582 sizeof( AFSNonPagedDirectoryCB));
584 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
586 pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry;
589 // Initialize the non-paged portion of the directory entry
592 KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime);
593 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime);
594 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime);
596 pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY;
598 SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME);
600 pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell;
601 pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume;
602 pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode;
603 pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique;
604 pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash;
606 pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
608 pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR);
610 pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length;
612 pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB));
614 RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer,
619 // Copy in the volume information retrieved above
622 RtlCopyMemory( &pVolumeCB->VolumeInformation,
623 &stVolumeInformation,
624 sizeof( AFSVolumeInfoCB));
630 pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
632 pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
635 // Insert the volume into our volume tree. Don't insert any reserved entries
638 if( RootFid->Cell != 0)
641 pVolumeCB->TreeEntry.HashIndex = ullIndex;
643 if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL)
646 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
648 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
653 if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
654 &pVolumeCB->TreeEntry)))
657 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
661 if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
664 pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB;
669 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB;
671 pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail;
674 pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB;
677 *VolumeCB = pVolumeCB;
681 if( !NT_SUCCESS( ntStatus))
684 if( pNonPagedVcb != NULL)
687 AFSReleaseResource( pVolumeCB->VolumeLock);
689 ExDeleteResourceLite( &pNonPagedVcb->VolumeLock);
691 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
693 AFSExFreePoolWithTag( pNonPagedVcb, AFS_VCB_NP_ALLOCATION_TAG);
696 if( pNonPagedObject != NULL)
699 ExDeleteResourceLite( &pNonPagedObject->ObjectInfoLock);
701 AFSExFreePoolWithTag( pNonPagedObject, AFS_NP_OBJECT_INFO_TAG);
704 if( pVolumeCB != NULL)
707 if( pVolumeCB->DirectoryCB != NULL)
710 AFSExFreePoolWithTag( pVolumeCB->DirectoryCB, AFS_DIR_ENTRY_TAG);
713 AFSExFreePoolWithTag( pVolumeCB, AFS_VCB_ALLOCATION_TAG);
716 if( pNonPagedDirEntry != NULL)
719 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
721 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
728 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
730 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
738 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
741 NTSTATUS ntStatus = STATUS_SUCCESS;
742 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
748 // Remove the volume from the tree and list
749 // Don't process the list information for reserved entries
752 if( VolumeCB->ObjectInformation.FileId.Cell != 0)
755 if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE))
758 AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
759 &VolumeCB->TreeEntry);
762 if( VolumeCB->ListEntry.fLink == NULL)
765 pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink;
767 if( pDeviceExt->Specific.RDR.VolumeListTail != NULL)
770 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL;
776 ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink;
779 if( VolumeCB->ListEntry.bLink == NULL)
782 pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink;
784 if( pDeviceExt->Specific.RDR.VolumeListHead != NULL)
787 pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL;
793 ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink;
798 // Remove any PIOctl objects we have
801 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL)
804 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
807 AFSAcquireExcl( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
810 AFSRemoveFcb( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
812 AFSReleaseResource( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
815 AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
817 ExDeleteResourceLite( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
819 AFSExFreePoolWithTag( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
821 AFSExFreePoolWithTag( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
824 if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
828 // Release the fid in the service
831 AFSReleaseFid( &VolumeCB->ObjectInformation.FileId);
835 // Free up the memory
838 if( VolumeCB->NonPagedVcb != NULL)
841 if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
843 AFSReleaseResource( VolumeCB->VolumeLock);
846 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock);
848 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
850 AFSExFreePoolWithTag( VolumeCB->NonPagedVcb, AFS_VCB_NP_ALLOCATION_TAG);
853 if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
856 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
858 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
860 AFSExFreePoolWithTag( VolumeCB->ObjectInformation.NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
863 if( VolumeCB->DirectoryCB != NULL)
866 if( VolumeCB->DirectoryCB->NonPaged != NULL)
869 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
871 AFSExFreePoolWithTag( VolumeCB->DirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
874 AFSExFreePoolWithTag( VolumeCB->DirectoryCB, AFS_DIR_ENTRY_TAG);
877 AFSExFreePoolWithTag( VolumeCB, AFS_VCB_ALLOCATION_TAG);
885 // Function: AFSInitRootFcb
889 // This function performs Root node Fcb initialization
893 // A status is returned for the function
897 AFSInitRootFcb( IN ULONGLONG ProcessID,
898 IN AFSVolumeCB *VolumeCB)
901 UNREFERENCED_PARAMETER(ProcessID);
902 NTSTATUS ntStatus = STATUS_SUCCESS;
904 AFSNonPagedFcb *pNPFcb = NULL;
910 // Initialize the root fcb
913 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
915 AFS_FCB_ALLOCATION_TAG);
920 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
921 AFS_TRACE_LEVEL_ERROR,
922 "AFSInitRootFcb Failed to allocate the root fcb\n");
924 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
930 pFcb->Header.NodeByteSize = sizeof( AFSFcb);
931 pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;
933 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
934 sizeof( AFSNonPagedFcb),
935 AFS_FCB_NP_ALLOCATION_TAG);
940 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
941 AFS_TRACE_LEVEL_ERROR,
942 "AFSInitRootFcb Failed to allocate the non-paged fcb\n");
944 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
947 RtlZeroMemory( pNPFcb,
948 sizeof( AFSNonPagedFcb));
950 pNPFcb->Size = sizeof( AFSNonPagedFcb);
951 pNPFcb->Type = AFS_NON_PAGED_FCB;
954 // OK, initialize the entry
957 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
959 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
961 ExInitializeResourceLite( &pNPFcb->Resource);
963 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
964 AFS_TRACE_LEVEL_VERBOSE,
965 "AFSInitRootFcb Acquiring Fcb lock %p EXCL %08lX\n",
967 PsGetCurrentThread());
969 AFSAcquireExcl( &pNPFcb->Resource,
972 ExInitializeResourceLite( &pNPFcb->PagingResource);
974 ExInitializeResourceLite( &pNPFcb->CcbListLock);
976 pFcb->Header.Resource = &pNPFcb->Resource;
978 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
980 pFcb->NPFcb = pNPFcb;
983 // Save the root Fcb in the VolumeCB
986 VolumeCB->ObjectInformation.Fcb = pFcb;
988 VolumeCB->ObjectInformation.VolumeCB = VolumeCB;
990 VolumeCB->RootFcb = pFcb;
992 pFcb->ObjectInformation = &VolumeCB->ObjectInformation;
996 if( !NT_SUCCESS( ntStatus))
1002 AFSRemoveRootFcb( pFcb);
1011 // Function: AFSRemoveRootFcb
1015 // This function performs root Fcb removal/deallocation
1019 // A status is returned for the function
1023 AFSRemoveRootFcb( IN AFSFcb *RootFcb)
1026 if( RootFcb->NPFcb != NULL)
1033 ExDeleteResourceLite( &RootFcb->NPFcb->Resource);
1035 ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
1037 ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock);
1040 // The non paged region
1043 AFSExFreePoolWithTag( RootFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
1047 // And the Fcb itself
1050 AFSExFreePoolWithTag( RootFcb, AFS_FCB_ALLOCATION_TAG);
1056 // Function: AFSRemoveFcb
1060 // This function performs Fcb removal/deallocation
1064 // A status is returned for the function
1068 AFSRemoveFcb( IN AFSFcb **ppFcb)
1073 pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)ppFcb, NULL, (PVOID)(*ppFcb));
1082 // Uninitialize the file lock if it is a file
1085 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1086 AFS_TRACE_LEVEL_VERBOSE,
1087 "AFSRemoveFcb Removing Fcb %p\n",
1090 if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
1093 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
1096 // The resource we allocated
1099 ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.ExtentsResource );
1101 ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.DirtyExtentsListLock);
1104 else if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1111 // Tear down the FM specific contexts
1114 FsRtlTeardownPerStreamContexts( &pFcb->Header);
1117 // Delete the resources
1120 ExDeleteResourceLite( &pFcb->NPFcb->Resource);
1122 ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
1124 ExDeleteResourceLite( &pFcb->NPFcb->SectionObjectResource);
1126 ExDeleteResourceLite( &pFcb->NPFcb->CcbListLock);
1129 // The non paged region
1132 AFSExFreePoolWithTag( pFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
1135 // And the Fcb itself, which includes the name
1138 AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
1144 AFSInitCcb( IN OUT AFSCcb **Ccb,
1145 IN AFSDirectoryCB *DirectoryCB,
1146 IN ACCESS_MASK GrantedAccess,
1147 IN ULONG FileAccess)
1150 NTSTATUS Status = STATUS_SUCCESS;
1151 AFSCcb *pCcb = NULL;
1158 // Allocate our context control block
1161 pCcb = (AFSCcb *)AFSExAllocatePoolWithTag( PagedPool,
1163 AFS_CCB_ALLOCATION_TAG);
1168 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1169 AFS_TRACE_LEVEL_ERROR,
1170 "AFSInitCcb Failed to allocate Ccb\n");
1172 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1175 RtlZeroMemory( pCcb,
1178 pCcb->Size = sizeof( AFSCcb);
1180 pCcb->Type = AFS_CCB;
1182 pCcb->NPCcb = (AFSNonPagedCcb *)AFSExAllocatePoolWithTag( NonPagedPool,
1183 sizeof( AFSNonPagedCcb),
1184 AFS_CCB_NP_ALLOCATION_TAG);
1186 if( pCcb->NPCcb == NULL)
1189 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1190 AFS_TRACE_LEVEL_ERROR,
1191 "AFSInitCcb Failed to allocate NPCcb\n");
1193 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1196 ExInitializeResourceLite( &pCcb->NPCcb->CcbLock);
1198 pCcb->DirectoryCB = DirectoryCB;
1200 lCount = InterlockedIncrement( &pCcb->DirectoryCB->DirOpenReferenceCount);
1202 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1203 AFS_TRACE_LEVEL_VERBOSE,
1204 "AFSInitCcb Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1205 &pCcb->DirectoryCB->NameInformation.FileName,
1210 pCcb->GrantedAccess = GrantedAccess;
1212 pCcb->FileAccess = FileAccess;
1222 if( !NT_SUCCESS( Status))
1228 if ( pCcb->NPCcb != NULL)
1231 AFSExFreePoolWithTag( pCcb->NPCcb, AFS_CCB_NP_ALLOCATION_TAG);
1234 AFSExFreePoolWithTag( pCcb, AFS_CCB_ALLOCATION_TAG);
1245 // Function: AFSRemoveCcb
1249 // This function performs Ccb removal/deallocation
1257 AFSRemoveCcb( IN AFSFcb *Fcb,
1263 AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
1267 BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST))
1270 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1273 if( Ccb->ListEntry.fLink == NULL)
1276 Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink;
1278 if( Fcb->CcbListTail != NULL)
1280 Fcb->CcbListTail->ListEntry.fLink = NULL;
1285 ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink;
1288 if( Ccb->ListEntry.bLink == NULL)
1291 Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink;
1293 if( Fcb->CcbListHead != NULL)
1295 Fcb->CcbListHead->ListEntry.bLink = NULL;
1300 ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink;
1303 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
1306 if( Ccb->MaskName.Buffer != NULL)
1309 AFSExFreePoolWithTag( Ccb->MaskName.Buffer, AFS_GENERIC_MEMORY_6_TAG);
1312 if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
1315 AFSExFreePoolWithTag( Ccb->FullFileName.Buffer, 0);
1319 // If we have a name array then delete it
1322 if( Ccb->NameArray != NULL)
1325 AFSFreeNameArray( Ccb->NameArray);
1327 Ccb->NameArray = NULL;
1330 if( Ccb->DirectorySnapshot != NULL)
1333 AFSExFreePoolWithTag( Ccb->DirectorySnapshot, AFS_DIR_SNAPSHOT_TAG);
1335 Ccb->DirectorySnapshot = NULL;
1338 if( Ccb->NotifyMask.Buffer != NULL)
1341 AFSExFreePoolWithTag( Ccb->NotifyMask.Buffer, AFS_GENERIC_MEMORY_7_TAG);
1344 if ( Ccb->DirectoryCB != NULL)
1347 lCount = InterlockedDecrement( &Ccb->DirectoryCB->DirOpenReferenceCount);
1349 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1350 AFS_TRACE_LEVEL_VERBOSE,
1351 "AFSRemoveCcb Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1352 &Ccb->DirectoryCB->NameInformation.FileName,
1357 ASSERT( lCount >= 0);
1360 AFSReleaseResource( &Ccb->NPCcb->CcbLock);
1366 ExDeleteResourceLite( &Ccb->NPCcb->CcbLock);
1368 AFSExFreePoolWithTag( Ccb->NPCcb, AFS_CCB_NP_ALLOCATION_TAG);
1370 AFSExFreePoolWithTag( Ccb, AFS_CCB_ALLOCATION_TAG);
1374 AFSInsertCcb( IN AFSFcb *Fcb,
1378 NTSTATUS ntStatus = STATUS_SUCCESS;
1380 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1383 AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
1386 if( Fcb->CcbListHead == NULL)
1388 Fcb->CcbListHead = Ccb;
1392 Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb;
1394 Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail;
1397 Fcb->CcbListTail = Ccb;
1399 SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST);
1401 AFSReleaseResource( &Ccb->NPCcb->CcbLock);
1403 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);