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 *VolumeCB = pVolumeCB;
435 try_return( ntStatus);
439 // Revert our status from the above call back to success.
442 ntStatus = STATUS_SUCCESS;
446 // For the global root we allocate out volume node and insert it
447 // into the volume tree ...
450 pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
451 sizeof( AFSVolumeCB),
452 AFS_VCB_ALLOCATION_TAG);
454 if( pVolumeCB == NULL)
457 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
458 AFS_TRACE_LEVEL_ERROR,
459 "AFSInitVolume Failed to allocate the root volume cb\n");
461 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
464 RtlZeroMemory( pVolumeCB,
465 sizeof( AFSVolumeCB));
468 // The non paged portion
471 pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
472 sizeof( AFSNonPagedVolumeCB),
473 AFS_VCB_ALLOCATION_TAG);
475 if( pNonPagedVcb == NULL)
478 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
479 AFS_TRACE_LEVEL_ERROR,
480 "AFSInitVolume Failed to allocate the root non paged volume cb\n");
482 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
485 RtlZeroMemory( pNonPagedVcb,
486 sizeof( AFSNonPagedVolumeCB));
488 ExInitializeResourceLite( &pNonPagedVcb->VolumeLock);
490 ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
492 pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
493 sizeof( AFSNonPagedObjectInfoCB),
494 AFS_VCB_ALLOCATION_TAG);
496 if( pNonPagedObject == NULL)
499 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
500 AFS_TRACE_LEVEL_ERROR,
501 "AFSInitVolume Failed to allocate the root non paged object cb\n");
503 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
506 RtlZeroMemory( pNonPagedObject,
507 sizeof( AFSNonPagedObjectInfoCB));
509 ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
511 pVolumeCB->NonPagedVcb = pNonPagedVcb;
513 pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject;
515 pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock;
517 pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock;
519 pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
522 // Bias our reference by 1
525 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
526 AFS_TRACE_LEVEL_VERBOSE,
527 "AFSInitVolume Initializing count (2) on volume %08lX\n",
530 pVolumeCB->VolumeReferenceCount = 2;
532 AFSAcquireExcl( pVolumeCB->VolumeLock,
535 pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
536 sizeof( AFSDirectoryCB) + sizeof( WCHAR),
539 if( pVolumeCB->DirectoryCB == NULL)
542 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
545 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
546 sizeof( AFSNonPagedDirectoryCB),
547 AFS_DIR_ENTRY_NP_TAG);
549 if( pNonPagedDirEntry == NULL)
552 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
555 RtlZeroMemory( pVolumeCB->DirectoryCB,
556 sizeof( AFSDirectoryCB) + sizeof( WCHAR));
558 RtlZeroMemory( pNonPagedDirEntry,
559 sizeof( AFSNonPagedDirectoryCB));
561 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
563 pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry;
566 // Initialize the non-paged portion of the directory entry
569 KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime);
570 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime);
571 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime);
573 pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY;
575 SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME);
577 pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell;
578 pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume;
579 pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode;
580 pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique;
581 pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash;
583 pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
585 pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR);
587 pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length;
589 pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB));
591 RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer,
596 // Copy in the volume information retrieved above
599 RtlCopyMemory( &pVolumeCB->VolumeInformation,
600 &stVolumeInformation,
601 sizeof( AFSVolumeInfoCB));
607 pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
609 pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
612 // Insert the volume into our volume tree. Don't insert any reserved entries
615 if( RootFid->Cell != 0)
618 pVolumeCB->TreeEntry.HashIndex = ullIndex;
620 if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL)
623 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
625 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
630 if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
631 &pVolumeCB->TreeEntry)))
634 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
638 if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
641 pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB;
646 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB;
648 pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail;
651 pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB;
654 *VolumeCB = pVolumeCB;
658 if( !NT_SUCCESS( ntStatus))
661 if( pNonPagedVcb != NULL)
664 AFSReleaseResource( pVolumeCB->VolumeLock);
666 ExDeleteResourceLite( &pNonPagedVcb->VolumeLock);
668 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
670 AFSExFreePool( pNonPagedVcb);
673 if( pNonPagedObject != NULL)
676 ExDeleteResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
678 AFSExFreePool( pNonPagedObject);
681 if( pVolumeCB != NULL)
684 if( pVolumeCB->DirectoryCB != NULL)
687 AFSExFreePool( pVolumeCB->DirectoryCB);
690 AFSExFreePool( pVolumeCB);
693 if( pNonPagedDirEntry != NULL)
696 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
698 AFSExFreePool( pNonPagedDirEntry);
705 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
707 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
715 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
718 NTSTATUS ntStatus = STATUS_SUCCESS;
719 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
725 // Remove the volume from the tree and list
726 // Don't process the list information for reserved entries
729 if( VolumeCB->ObjectInformation.FileId.Cell != 0)
732 if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE))
735 AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
736 &VolumeCB->TreeEntry);
739 if( VolumeCB->ListEntry.fLink == NULL)
742 pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink;
744 if( pDeviceExt->Specific.RDR.VolumeListTail != NULL)
747 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL;
753 ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink;
756 if( VolumeCB->ListEntry.bLink == NULL)
759 pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink;
761 if( pDeviceExt->Specific.RDR.VolumeListHead != NULL)
764 pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL;
770 ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink;
775 // Remove any PIOctl objects we have
778 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL)
781 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
784 AFSRemoveFcb( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
787 AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
789 AFSExFreePool( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB);
792 if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
796 // Release the fid in the service
799 AFSReleaseFid( &VolumeCB->ObjectInformation.FileId);
803 // Free up the memory
806 if( VolumeCB->NonPagedVcb != NULL)
809 if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
811 AFSReleaseResource( VolumeCB->VolumeLock);
814 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock);
816 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
818 AFSExFreePool( VolumeCB->NonPagedVcb);
821 if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
824 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
826 AFSExFreePool( VolumeCB->ObjectInformation.NonPagedInfo);
829 if( VolumeCB->DirectoryCB != NULL)
832 if( VolumeCB->DirectoryCB->NonPaged != NULL)
835 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
837 AFSExFreePool( VolumeCB->DirectoryCB->NonPaged);
840 AFSExFreePool( VolumeCB->DirectoryCB);
843 AFSExFreePool( VolumeCB);
851 // Function: AFSInitRootFcb
855 // This function performs Root node Fcb initialization
859 // A status is returned for the function
863 AFSInitRootFcb( IN ULONGLONG ProcessID,
864 IN AFSVolumeCB *VolumeCB)
867 NTSTATUS ntStatus = STATUS_SUCCESS;
869 AFSNonPagedFcb *pNPFcb = NULL;
870 IO_STATUS_BLOCK stIoStatus = {0,0};
871 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
877 // Initialize the root fcb
880 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
882 AFS_FCB_ALLOCATION_TAG);
887 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
888 AFS_TRACE_LEVEL_ERROR,
889 "AFSInitRootFcb Failed to allocate the root fcb\n");
891 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
897 pFcb->Header.NodeByteSize = sizeof( AFSFcb);
898 pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;
900 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
901 sizeof( AFSNonPagedFcb),
902 AFS_FCB_NP_ALLOCATION_TAG);
907 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
908 AFS_TRACE_LEVEL_ERROR,
909 "AFSInitRootFcb Failed to allocate the non-paged fcb\n");
911 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
914 RtlZeroMemory( pNPFcb,
915 sizeof( AFSNonPagedFcb));
917 pNPFcb->Size = sizeof( AFSNonPagedFcb);
918 pNPFcb->Type = AFS_NON_PAGED_FCB;
921 // OK, initialize the entry
924 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
926 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
928 ExInitializeResourceLite( &pNPFcb->Resource);
930 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
931 AFS_TRACE_LEVEL_VERBOSE,
932 "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
934 PsGetCurrentThread());
936 AFSAcquireExcl( &pNPFcb->Resource,
939 ExInitializeResourceLite( &pNPFcb->PagingResource);
941 ExInitializeResourceLite( &pNPFcb->CcbListLock);
943 pFcb->Header.Resource = &pNPFcb->Resource;
945 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
947 pFcb->NPFcb = pNPFcb;
950 // Save the root Fcb in the VolumeCB
953 VolumeCB->ObjectInformation.Fcb = pFcb;
955 VolumeCB->ObjectInformation.VolumeCB = VolumeCB;
957 VolumeCB->RootFcb = pFcb;
959 pFcb->ObjectInformation = &VolumeCB->ObjectInformation;
963 if( !NT_SUCCESS( ntStatus))
969 AFSRemoveRootFcb( pFcb);
978 // Function: AFSRemoveRootFcb
982 // This function performs root Fcb removal/deallocation
986 // A status is returned for the function
990 AFSRemoveRootFcb( IN AFSFcb *RootFcb)
993 AFSDirectoryCB *pCurrentDirEntry = NULL;
994 AFSVolumeCB *pVolumeCB = RootFcb->ObjectInformation->VolumeCB;
996 if( RootFcb->NPFcb != NULL)
1003 ExDeleteResourceLite( &RootFcb->NPFcb->Resource);
1005 ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
1007 ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock);
1010 // The non paged region
1013 AFSExFreePool( RootFcb->NPFcb);
1017 // And the Fcb itself
1020 AFSExFreePool( RootFcb);
1026 // Function: AFSRemoveFcb
1030 // This function performs Fcb removal/deallocation
1034 // A status is returned for the function
1038 AFSRemoveFcb( IN AFSFcb **ppFcb)
1043 pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)ppFcb, NULL, (PVOID)(*ppFcb));
1052 // Uninitialize the file lock if it is a file
1055 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1056 AFS_TRACE_LEVEL_VERBOSE,
1057 "AFSRemoveFcb Removing Fcb %08lX\n",
1060 if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
1063 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
1066 // The resource we allocated
1069 ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.ExtentsResource );
1071 ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.DirtyExtentsListLock);
1074 else if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1081 // Tear down the FM specific contexts
1084 FsRtlTeardownPerStreamContexts( &pFcb->Header);
1087 // Delete the resources
1090 ExDeleteResourceLite( &pFcb->NPFcb->Resource);
1092 ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
1094 ExDeleteResourceLite( &pFcb->NPFcb->CcbListLock);
1097 // The non paged region
1100 AFSExFreePool( pFcb->NPFcb);
1103 // And the Fcb itself, which includes the name
1106 AFSExFreePool( pFcb);
1112 AFSInitCcb( IN OUT AFSCcb **Ccb)
1115 NTSTATUS Status = STATUS_SUCCESS;
1116 AFSCcb *pCcb = NULL;
1122 // Allocate our context control block
1125 pCcb = (AFSCcb *)AFSExAllocatePoolWithTag( PagedPool,
1127 AFS_CCB_ALLOCATION_TAG);
1132 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1133 AFS_TRACE_LEVEL_ERROR,
1134 "AFSInitCcb Failed to allocate Ccb\n");
1136 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1139 RtlZeroMemory( pCcb,
1142 pCcb->Size = sizeof( AFSCcb);
1144 pCcb->Type = AFS_CCB;
1146 pCcb->NPCcb = (AFSNonPagedCcb *)AFSExAllocatePoolWithTag( NonPagedPool,
1147 sizeof( AFSNonPagedCcb),
1148 AFS_CCB_NP_ALLOCATION_TAG);
1150 if( pCcb->NPCcb == NULL)
1153 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1154 AFS_TRACE_LEVEL_ERROR,
1155 "AFSInitCcb Failed to allocate NPCcb\n");
1157 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1160 ExInitializeResourceLite( &pCcb->NPCcb->CcbLock);
1170 if( !NT_SUCCESS( Status))
1176 if ( pCcb->NPCcb != NULL)
1179 AFSExFreePool( pCcb->NPCcb);
1182 AFSExFreePool( pCcb);
1193 // Function: AFSRemoveCcb
1197 // This function performs Ccb removal/deallocation
1201 // A status is returned for the function
1205 AFSRemoveCcb( IN AFSFcb *Fcb,
1209 NTSTATUS ntStatus = STATUS_SUCCESS;
1211 AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
1215 BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST))
1218 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1221 if( Ccb->ListEntry.fLink == NULL)
1224 Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink;
1226 if( Fcb->CcbListTail != NULL)
1228 Fcb->CcbListTail->ListEntry.fLink = NULL;
1233 ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink;
1236 if( Ccb->ListEntry.bLink == NULL)
1239 Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink;
1241 if( Fcb->CcbListHead != NULL)
1243 Fcb->CcbListHead->ListEntry.bLink = NULL;
1248 ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink;
1251 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
1254 if( Ccb->MaskName.Buffer != NULL)
1257 AFSExFreePool( Ccb->MaskName.Buffer);
1260 if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
1263 AFSExFreePool( Ccb->FullFileName.Buffer);
1267 // If we have a name array then delete it
1270 if( Ccb->NameArray != NULL)
1273 AFSFreeNameArray( Ccb->NameArray);
1275 Ccb->NameArray = NULL;
1278 if( Ccb->DirectorySnapshot != NULL)
1281 AFSExFreePool( Ccb->DirectorySnapshot);
1283 Ccb->DirectorySnapshot = NULL;
1286 if( Ccb->NotifyMask.Buffer != NULL)
1289 AFSExFreePool( Ccb->NotifyMask.Buffer);
1292 AFSReleaseResource( &Ccb->NPCcb->CcbLock);
1298 ExDeleteResourceLite( &Ccb->NPCcb->CcbLock);
1300 AFSExFreePool( Ccb->NPCcb);
1302 AFSExFreePool( Ccb);
1308 AFSInsertCcb( IN AFSFcb *Fcb,
1312 NTSTATUS ntStatus = STATUS_SUCCESS;
1314 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1317 AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
1320 if( Fcb->CcbListHead == NULL)
1322 Fcb->CcbListHead = Ccb;
1326 Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb;
1328 Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail;
1331 Fcb->CcbListTail = Ccb;
1333 SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST);
1335 AFSReleaseResource( &Ccb->NPCcb->CcbLock);
1337 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);