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 // A status is returned for the function
54 AFSInitFcb( IN AFSDirectoryCB *DirEntry)
57 NTSTATUS ntStatus = STATUS_SUCCESS;
58 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
60 AFSNonPagedFcb *pNPFcb = NULL;
61 IO_STATUS_BLOCK stIoSb = {0,0};
62 USHORT usFcbLength = 0;
63 ULONGLONG ullIndex = 0;
64 AFSDirEnumEntry *pDirEnumCB = NULL;
65 AFSObjectInfoCB *pObjectInfo = NULL, *pParentObjectInfo = NULL;
66 AFSVolumeCB *pVolumeCB = NULL;
71 pObjectInfo = DirEntry->ObjectInformation;
73 pParentObjectInfo = pObjectInfo->ParentObjectInformation;
75 pVolumeCB = pObjectInfo->VolumeCB;
78 // Allocate the Fcb and the nonpaged portion of the Fcb.
81 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
82 AFS_TRACE_LEVEL_VERBOSE_2,
83 "AFSInitFcb Initializing fcb for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
84 &DirEntry->NameInformation.FileName,
85 pObjectInfo->FileId.Cell,
86 pObjectInfo->FileId.Volume,
87 pObjectInfo->FileId.Vnode,
88 pObjectInfo->FileId.Unique);
90 usFcbLength = sizeof( AFSFcb);
92 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
94 AFS_FCB_ALLOCATION_TAG);
99 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
100 AFS_TRACE_LEVEL_ERROR,
101 "AFSInitFcb Failed to allocate fcb\n");
103 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
109 pFcb->Header.NodeByteSize = usFcbLength;
111 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
112 sizeof( AFSNonPagedFcb),
113 AFS_FCB_NP_ALLOCATION_TAG);
118 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
119 AFS_TRACE_LEVEL_ERROR,
120 "AFSInitFcb Failed to allocate non-paged fcb\n");
122 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
125 RtlZeroMemory( pNPFcb,
126 sizeof( AFSNonPagedFcb));
128 pNPFcb->Size = sizeof( AFSNonPagedFcb);
130 pNPFcb->Type = AFS_NON_PAGED_FCB;
133 // Initialize the advanced header
136 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
138 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
141 // OK, initialize the entry
144 ExInitializeResourceLite( &pNPFcb->Resource);
146 ExInitializeResourceLite( &pNPFcb->PagingResource);
148 ExInitializeResourceLite( &pNPFcb->CcbListLock);
150 pFcb->Header.Resource = &pNPFcb->Resource;
152 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
155 // Grab the Fcb for processing
158 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
159 AFS_TRACE_LEVEL_VERBOSE,
160 "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
162 PsGetCurrentThread());
164 AFSAcquireExcl( &pNPFcb->Resource,
167 pFcb->NPFcb = pNPFcb;
170 // Set type specific information
173 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
177 // Reset the type to a directory type
180 pFcb->Header.NodeTypeCode = AFS_DIRECTORY_FCB;
182 else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
185 pFcb->Header.NodeTypeCode = AFS_FILE_FCB;
188 // Initialize the file specific information
191 FsRtlInitializeFileLock( &pFcb->Specific.File.FileLock,
196 // Initialize the header file sizes to our dir entry information
199 pFcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
200 pFcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
201 pFcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
204 // Initialize the Extents resources and so forth. The
205 // quiescent state is that no one has the extents for
206 // IO (do the extents are not busy) and there is no
207 // extents request outstanding (and hence the "last
208 // one" is complete).
210 ExInitializeResourceLite( &pNPFcb->Specific.File.ExtentsResource );
212 KeInitializeEvent( &pNPFcb->Specific.File.ExtentsRequestComplete,
216 for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
218 InitializeListHead(&pFcb->Specific.File.ExtentsLists[i]);
221 pNPFcb->Specific.File.DirtyListHead = NULL;
222 pNPFcb->Specific.File.DirtyListTail = NULL;
224 ExInitializeResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
226 KeInitializeEvent( &pNPFcb->Specific.File.FlushEvent,
227 SynchronizationEvent,
230 KeInitializeEvent( &pNPFcb->Specific.File.QueuedFlushEvent,
234 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
237 pFcb->Header.NodeTypeCode = AFS_SPECIAL_SHARE_FCB;
239 else if( pObjectInfo->FileType == AFS_FILE_TYPE_PIOCTL)
242 pFcb->Header.NodeTypeCode = AFS_IOCTL_FCB;
244 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
247 pFcb->Header.NodeTypeCode = AFS_SYMBOLIC_LINK_FCB;
249 else if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
252 pFcb->Header.NodeTypeCode = AFS_MOUNT_POINT_FCB;
254 else if( pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
256 pFcb->Header.NodeTypeCode = AFS_DFS_LINK_FCB;
260 pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
264 // Initialize some fields in the Fcb
267 if ( InterlockedCompareExchangePointer( (PVOID *)&pObjectInfo->Fcb, pFcb, NULL) != NULL)
270 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
271 AFS_TRACE_LEVEL_WARNING,
272 "AFSInitFcb Raced Fcb %08lX pFcb %08lX Name %wZ\n",
275 &DirEntry->NameInformation.FileName);
277 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
278 AFS_TRACE_LEVEL_VERBOSE,
279 "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
280 &pObjectInfo->Fcb->NPFcb->Resource,
281 PsGetCurrentThread());
283 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
286 try_return( ntStatus = STATUS_REPARSE);
289 pFcb->ObjectInformation = pObjectInfo;
291 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
292 AFS_TRACE_LEVEL_VERBOSE,
293 "AFSInitFcb Initialized Fcb %08lX Name %wZ\n",
295 &DirEntry->NameInformation.FileName);
299 if( ntStatus != STATUS_SUCCESS)
302 if ( !NT_SUCCESS( ntStatus))
305 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
306 AFS_TRACE_LEVEL_ERROR,
307 "AFSInitFcb Failed to initialize fcb Status %08lX\n",
317 AFSReleaseResource( &pNPFcb->Resource);
319 FsRtlTeardownPerStreamContexts( &pFcb->Header);
321 if ( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
324 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
326 ExDeleteResourceLite( &pNPFcb->Specific.File.ExtentsResource);
328 ExDeleteResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
331 ExDeleteResourceLite( &pNPFcb->PagingResource);
333 ExDeleteResourceLite( &pNPFcb->CcbListLock);
335 ExDeleteResourceLite( &pNPFcb->Resource);
337 AFSExFreePool( pNPFcb);
340 AFSExFreePool( pFcb);
349 AFSInitVolume( IN GUID *AuthGroup,
350 IN AFSFileID *RootFid,
351 OUT AFSVolumeCB **VolumeCB)
354 NTSTATUS ntStatus = STATUS_SUCCESS;
355 IO_STATUS_BLOCK stIoStatus = {0,0};
356 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
357 AFSNonPagedVolumeCB *pNonPagedVcb = NULL;
358 AFSVolumeCB *pVolumeCB = NULL;
359 AFSNonPagedObjectInfoCB *pNonPagedObject = NULL;
360 ULONGLONG ullIndex = 0;
361 BOOLEAN bReleaseLocks = FALSE;
362 AFSVolumeInfoCB stVolumeInformation;
363 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
370 // Before grabbing any locks ask the service for the volume information
371 // This may be a waste but we need to get this information prior to
372 // taking any volume tree locks. Don't do this for any 'reserved' cell entries
375 if( RootFid->Cell != 0)
378 RtlZeroMemory( &stVolumeInformation,
379 sizeof( AFSVolumeInfoCB));
381 ntStatus = AFSRetrieveVolumeInformation( AuthGroup,
383 &stVolumeInformation);
385 if( !NT_SUCCESS( ntStatus))
388 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
389 AFS_TRACE_LEVEL_ERROR,
390 "AFSInitVolume AFSRetrieveVolumeInformation(RootFid) failure %08lX\n",
393 try_return( ntStatus);
397 // Grab our tree locks and see if we raced with someone else
400 AFSAcquireExcl( pDeviceExt->Specific.RDR.VolumeTree.TreeLock,
403 AFSAcquireExcl( &pDeviceExt->Specific.RDR.VolumeListLock,
406 bReleaseLocks = TRUE;
408 ullIndex = AFSCreateHighIndex( RootFid);
410 ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
412 (AFSBTreeEntry **)&pVolumeCB);
414 if( NT_SUCCESS( ntStatus) &&
419 // So we don't lock with an invalidation call ...
422 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
424 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
426 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
428 bReleaseLocks = FALSE;
430 AFSAcquireExcl( pVolumeCB->VolumeLock,
433 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
435 *VolumeCB = pVolumeCB;
437 try_return( ntStatus);
441 // Revert our status from the above call back to success.
444 ntStatus = STATUS_SUCCESS;
448 // For the global root we allocate out volume node and insert it
449 // into the volume tree ...
452 pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
453 sizeof( AFSVolumeCB),
454 AFS_VCB_ALLOCATION_TAG);
456 if( pVolumeCB == NULL)
459 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
460 AFS_TRACE_LEVEL_ERROR,
461 "AFSInitVolume Failed to allocate the root volume cb\n");
463 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
466 RtlZeroMemory( pVolumeCB,
467 sizeof( AFSVolumeCB));
470 // The non paged portion
473 pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
474 sizeof( AFSNonPagedVolumeCB),
475 AFS_VCB_ALLOCATION_TAG);
477 if( pNonPagedVcb == NULL)
480 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
481 AFS_TRACE_LEVEL_ERROR,
482 "AFSInitVolume Failed to allocate the root non paged volume cb\n");
484 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
487 RtlZeroMemory( pNonPagedVcb,
488 sizeof( AFSNonPagedVolumeCB));
490 ExInitializeResourceLite( &pNonPagedVcb->VolumeLock);
492 ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
494 pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
495 sizeof( AFSNonPagedObjectInfoCB),
496 AFS_VCB_ALLOCATION_TAG);
498 if( pNonPagedObject == NULL)
501 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
502 AFS_TRACE_LEVEL_ERROR,
503 "AFSInitVolume Failed to allocate the root non paged object cb\n");
505 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
508 RtlZeroMemory( pNonPagedObject,
509 sizeof( AFSNonPagedObjectInfoCB));
511 ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
513 pVolumeCB->NonPagedVcb = pNonPagedVcb;
515 pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject;
517 pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock;
519 pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock;
521 pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
524 // Bias our reference by 1
527 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
528 AFS_TRACE_LEVEL_VERBOSE,
529 "AFSInitVolume Initializing count (1) on volume %08lX\n",
532 pVolumeCB->VolumeReferenceCount = 1;
534 AFSAcquireExcl( pVolumeCB->VolumeLock,
537 pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
538 sizeof( AFSDirectoryCB) + sizeof( WCHAR),
541 if( pVolumeCB->DirectoryCB == NULL)
544 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
547 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
548 sizeof( AFSNonPagedDirectoryCB),
549 AFS_DIR_ENTRY_NP_TAG);
551 if( pNonPagedDirEntry == NULL)
554 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
557 RtlZeroMemory( pVolumeCB->DirectoryCB,
558 sizeof( AFSDirectoryCB) + sizeof( WCHAR));
560 RtlZeroMemory( pNonPagedDirEntry,
561 sizeof( AFSNonPagedDirectoryCB));
563 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
565 pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry;
568 // Initialize the non-paged portion of the directory entry
571 KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime);
572 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime);
573 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime);
575 pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY;
577 SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME);
579 pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell;
580 pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume;
581 pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode;
582 pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique;
583 pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash;
585 pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
587 pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR);
589 pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length;
591 pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB));
593 RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer,
598 // Copy in the volume information retrieved above
601 RtlCopyMemory( &pVolumeCB->VolumeInformation,
602 &stVolumeInformation,
603 sizeof( AFSVolumeInfoCB));
609 pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
611 pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
614 // Insert the volume into our volume tree. Don't insert any reserved entries
617 if( RootFid->Cell != 0)
620 pVolumeCB->TreeEntry.HashIndex = ullIndex;
622 if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL)
625 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
627 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
632 if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
633 &pVolumeCB->TreeEntry)))
636 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
640 if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
643 pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB;
648 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB;
650 pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail;
653 pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB;
656 *VolumeCB = pVolumeCB;
660 if( !NT_SUCCESS( ntStatus))
663 if( pNonPagedVcb != NULL)
666 AFSReleaseResource( pVolumeCB->VolumeLock);
668 ExDeleteResourceLite( &pNonPagedVcb->VolumeLock);
670 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
672 AFSExFreePool( pNonPagedVcb);
675 if( pNonPagedObject != NULL)
678 ExDeleteResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
680 AFSExFreePool( pNonPagedObject);
683 if( pVolumeCB != NULL)
686 if( pVolumeCB->DirectoryCB != NULL)
689 AFSExFreePool( pVolumeCB->DirectoryCB);
692 AFSExFreePool( pVolumeCB);
695 if( pNonPagedDirEntry != NULL)
698 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
700 AFSExFreePool( pNonPagedDirEntry);
707 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
709 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
717 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
720 NTSTATUS ntStatus = STATUS_SUCCESS;
721 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
727 // Remove the volume from the tree and list
728 // Don't process the list information for reserved entries
731 if( VolumeCB->ObjectInformation.FileId.Cell != 0)
734 if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE))
737 AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
738 &VolumeCB->TreeEntry);
741 if( VolumeCB->ListEntry.fLink == NULL)
744 pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink;
746 if( pDeviceExt->Specific.RDR.VolumeListTail != NULL)
749 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL;
755 ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink;
758 if( VolumeCB->ListEntry.bLink == NULL)
761 pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink;
763 if( pDeviceExt->Specific.RDR.VolumeListHead != NULL)
766 pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL;
772 ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink;
777 // Remove any PIOctl objects we have
780 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL)
783 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
786 AFSRemoveFcb( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
789 AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
791 AFSExFreePool( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB);
794 if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
798 // Release the fid in the service
801 AFSReleaseFid( &VolumeCB->ObjectInformation.FileId);
805 // Free up the memory
808 if( VolumeCB->NonPagedVcb != NULL)
811 if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
813 AFSReleaseResource( VolumeCB->VolumeLock);
816 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock);
818 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
820 AFSExFreePool( VolumeCB->NonPagedVcb);
823 if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
826 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
828 AFSExFreePool( VolumeCB->ObjectInformation.NonPagedInfo);
831 if( VolumeCB->DirectoryCB != NULL)
834 if( VolumeCB->DirectoryCB->NonPaged != NULL)
837 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
839 AFSExFreePool( VolumeCB->DirectoryCB->NonPaged);
842 AFSExFreePool( VolumeCB->DirectoryCB);
845 AFSExFreePool( VolumeCB);
853 // Function: AFSInitRootFcb
857 // This function performs Root node Fcb initialization
861 // A status is returned for the function
865 AFSInitRootFcb( IN ULONGLONG ProcessID,
866 IN AFSVolumeCB *VolumeCB)
869 NTSTATUS ntStatus = STATUS_SUCCESS;
871 AFSNonPagedFcb *pNPFcb = NULL;
872 IO_STATUS_BLOCK stIoStatus = {0,0};
873 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
879 // Initialize the root fcb
882 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
884 AFS_FCB_ALLOCATION_TAG);
889 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
890 AFS_TRACE_LEVEL_ERROR,
891 "AFSInitRootFcb Failed to allocate the root fcb\n");
893 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
899 pFcb->Header.NodeByteSize = sizeof( AFSFcb);
900 pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;
902 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
903 sizeof( AFSNonPagedFcb),
904 AFS_FCB_NP_ALLOCATION_TAG);
909 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
910 AFS_TRACE_LEVEL_ERROR,
911 "AFSInitRootFcb Failed to allocate the non-paged fcb\n");
913 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
916 RtlZeroMemory( pNPFcb,
917 sizeof( AFSNonPagedFcb));
919 pNPFcb->Size = sizeof( AFSNonPagedFcb);
920 pNPFcb->Type = AFS_NON_PAGED_FCB;
923 // OK, initialize the entry
926 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
928 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
930 ExInitializeResourceLite( &pNPFcb->Resource);
932 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
933 AFS_TRACE_LEVEL_VERBOSE,
934 "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
936 PsGetCurrentThread());
938 AFSAcquireExcl( &pNPFcb->Resource,
941 ExInitializeResourceLite( &pNPFcb->PagingResource);
943 ExInitializeResourceLite( &pNPFcb->CcbListLock);
945 pFcb->Header.Resource = &pNPFcb->Resource;
947 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
949 pFcb->NPFcb = pNPFcb;
952 // Save the root Fcb in the VolumeCB
955 VolumeCB->ObjectInformation.Fcb = pFcb;
957 VolumeCB->ObjectInformation.VolumeCB = VolumeCB;
959 VolumeCB->RootFcb = pFcb;
961 pFcb->ObjectInformation = &VolumeCB->ObjectInformation;
965 if( !NT_SUCCESS( ntStatus))
971 AFSRemoveRootFcb( pFcb);
980 // Function: AFSRemoveRootFcb
984 // This function performs root Fcb removal/deallocation
988 // A status is returned for the function
992 AFSRemoveRootFcb( IN AFSFcb *RootFcb)
995 AFSDirectoryCB *pCurrentDirEntry = NULL;
996 AFSVolumeCB *pVolumeCB = RootFcb->ObjectInformation->VolumeCB;
998 if( RootFcb->NPFcb != NULL)
1005 ExDeleteResourceLite( &RootFcb->NPFcb->Resource);
1007 ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
1009 ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock);
1012 // The non paged region
1015 AFSExFreePool( RootFcb->NPFcb);
1019 // And the Fcb itself
1022 AFSExFreePool( RootFcb);
1028 // Function: AFSRemoveFcb
1032 // This function performs Fcb removal/deallocation
1036 // A status is returned for the function
1040 AFSRemoveFcb( IN AFSFcb **ppFcb)
1045 pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)ppFcb, NULL, (PVOID)(*ppFcb));
1054 // Uninitialize the file lock if it is a file
1057 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1058 AFS_TRACE_LEVEL_VERBOSE,
1059 "AFSRemoveFcb Removing Fcb %08lX\n",
1062 if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
1065 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
1068 // The resource we allocated
1071 ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.ExtentsResource );
1073 ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.DirtyExtentsListLock);
1076 else if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1083 // Tear down the FM specific contexts
1086 FsRtlTeardownPerStreamContexts( &pFcb->Header);
1089 // Delete the resources
1092 ExDeleteResourceLite( &pFcb->NPFcb->Resource);
1094 ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
1096 ExDeleteResourceLite( &pFcb->NPFcb->CcbListLock);
1099 // The non paged region
1102 AFSExFreePool( pFcb->NPFcb);
1105 // And the Fcb itself, which includes the name
1108 AFSExFreePool( pFcb);
1114 AFSInitCcb( IN OUT AFSCcb **Ccb)
1117 NTSTATUS Status = STATUS_SUCCESS;
1118 AFSCcb *pCcb = NULL;
1124 // Allocate our context control block
1127 pCcb = (AFSCcb *)AFSExAllocatePoolWithTag( PagedPool,
1129 AFS_CCB_ALLOCATION_TAG);
1134 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1135 AFS_TRACE_LEVEL_ERROR,
1136 "AFSInitCcb Failed to allocate Ccb\n");
1138 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1141 RtlZeroMemory( pCcb,
1144 pCcb->Size = sizeof( AFSCcb);
1145 pCcb->Type = AFS_CCB;
1155 if( !NT_SUCCESS( Status))
1161 AFSExFreePool( pCcb);
1172 // Function: AFSRemoveCcb
1176 // This function performs Ccb removal/deallocation
1180 // A status is returned for the function
1184 AFSRemoveCcb( IN AFSFcb *Fcb,
1188 NTSTATUS ntStatus = STATUS_SUCCESS;
1191 BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST))
1194 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1197 if( Ccb->ListEntry.fLink == NULL)
1200 Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink;
1202 if( Fcb->CcbListTail != NULL)
1204 Fcb->CcbListTail->ListEntry.fLink = NULL;
1209 ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink;
1212 if( Ccb->ListEntry.bLink == NULL)
1215 Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink;
1217 if( Fcb->CcbListHead != NULL)
1219 Fcb->CcbListHead->ListEntry.bLink = NULL;
1224 ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink;
1227 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
1230 if( Ccb->MaskName.Buffer != NULL)
1233 AFSExFreePool( Ccb->MaskName.Buffer);
1236 if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
1239 AFSExFreePool( Ccb->FullFileName.Buffer);
1243 // If we have a name array then delete it
1246 if( Ccb->NameArray != NULL)
1249 AFSFreeNameArray( Ccb->NameArray);
1251 Ccb->NameArray = NULL;
1254 if( Ccb->DirectorySnapshot != NULL)
1257 AFSExFreePool( Ccb->DirectorySnapshot);
1259 Ccb->DirectorySnapshot = NULL;
1262 if( Ccb->NotifyMask.Buffer != NULL)
1265 AFSExFreePool( Ccb->NotifyMask.Buffer);
1272 AFSExFreePool( Ccb);
1278 AFSInsertCcb( IN AFSFcb *Fcb,
1282 NTSTATUS ntStatus = STATUS_SUCCESS;
1284 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1287 if( Fcb->CcbListHead == NULL)
1289 Fcb->CcbListHead = Ccb;
1293 Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb;
1295 Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail;
1298 Fcb->CcbListTail = Ccb;
1300 SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST);
1302 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);