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 BOOLEAN bUninitFileLock = FALSE;
63 USHORT usFcbLength = 0;
64 ULONGLONG ullIndex = 0;
65 AFSDirEnumEntry *pDirEnumCB = NULL;
66 AFSObjectInfoCB *pObjectInfo = NULL, *pParentObjectInfo = NULL;
67 AFSVolumeCB *pVolumeCB = NULL;
72 pObjectInfo = DirEntry->ObjectInformation;
74 pParentObjectInfo = pObjectInfo->ParentObjectInformation;
76 pVolumeCB = pObjectInfo->VolumeCB;
79 // Allocate the Fcb and the nonpaged portion of the Fcb.
82 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
83 AFS_TRACE_LEVEL_VERBOSE_2,
84 "AFSInitFcb Initializing fcb for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
85 &DirEntry->NameInformation.FileName,
86 pObjectInfo->FileId.Cell,
87 pObjectInfo->FileId.Volume,
88 pObjectInfo->FileId.Vnode,
89 pObjectInfo->FileId.Unique);
91 usFcbLength = sizeof( AFSFcb);
93 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
95 AFS_FCB_ALLOCATION_TAG);
100 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
101 AFS_TRACE_LEVEL_ERROR,
102 "AFSInitFcb Failed to allocate fcb\n");
104 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
110 pFcb->Header.NodeByteSize = usFcbLength;
112 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
113 sizeof( AFSNonPagedFcb),
114 AFS_FCB_NP_ALLOCATION_TAG);
119 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
120 AFS_TRACE_LEVEL_ERROR,
121 "AFSInitFcb Failed to allocate non-paged fcb\n");
123 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
126 RtlZeroMemory( pNPFcb,
127 sizeof( AFSNonPagedFcb));
129 pNPFcb->Size = sizeof( AFSNonPagedFcb);
131 pNPFcb->Type = AFS_NON_PAGED_FCB;
134 // Initialize the advanced header
137 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
139 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
142 // OK, initialize the entry
145 ExInitializeResourceLite( &pNPFcb->Resource);
147 ExInitializeResourceLite( &pNPFcb->PagingResource);
149 ExInitializeResourceLite( &pNPFcb->CcbListLock);
151 pFcb->Header.Resource = &pNPFcb->Resource;
153 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
156 // Grab the Fcb for processing
159 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
160 AFS_TRACE_LEVEL_VERBOSE,
161 "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
163 PsGetCurrentThread());
165 AFSAcquireExcl( &pNPFcb->Resource,
168 pFcb->NPFcb = pNPFcb;
171 // Set type specific information
174 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
178 // Reset the type to a directory type
181 pFcb->Header.NodeTypeCode = AFS_DIRECTORY_FCB;
184 // Initialize enumeration information
187 KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
191 else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
194 pFcb->Header.NodeTypeCode = AFS_FILE_FCB;
197 // Initialize the file specific information
200 FsRtlInitializeFileLock( &pFcb->Specific.File.FileLock,
204 bUninitFileLock = TRUE;
207 // Initialize the header file sizes to our dir entry information
210 pFcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
211 pFcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
212 pFcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
215 // Initialize the Extents resources and so forth. The
216 // quiescent state is that no one has the extents for
217 // IO (do the extents are not busy) and there is no
218 // extents request outstanding (and hence the "last
219 // one" is complete).
221 ExInitializeResourceLite( &pNPFcb->Specific.File.ExtentsResource );
223 KeInitializeEvent( &pNPFcb->Specific.File.ExtentsRequestComplete,
227 for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
229 InitializeListHead(&pFcb->Specific.File.ExtentsLists[i]);
232 pNPFcb->Specific.File.DirtyListHead = NULL;
233 pNPFcb->Specific.File.DirtyListTail = NULL;
235 ExInitializeResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
237 KeInitializeEvent( &pNPFcb->Specific.File.FlushEvent,
238 SynchronizationEvent,
241 KeInitializeEvent( &pNPFcb->Specific.File.QueuedFlushEvent,
245 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
248 pFcb->Header.NodeTypeCode = AFS_SPECIAL_SHARE_FCB;
250 else if( pObjectInfo->FileType == AFS_FILE_TYPE_PIOCTL)
253 pFcb->Header.NodeTypeCode = AFS_IOCTL_FCB;
255 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
258 pFcb->Header.NodeTypeCode = AFS_SYMBOLIC_LINK_FCB;
260 else if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
263 pFcb->Header.NodeTypeCode = AFS_MOUNT_POINT_FCB;
265 else if( pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
267 pFcb->Header.NodeTypeCode = AFS_DFS_LINK_FCB;
271 pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
275 // Initialize some fields in the Fcb
278 if ( InterlockedCompareExchangePointer( (PVOID *)&pObjectInfo->Fcb, pFcb, NULL) != NULL)
281 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
282 AFS_TRACE_LEVEL_WARNING,
283 "AFSInitFcb Raced Fcb %08lX pFcb %08lX Name %wZ\n",
286 &DirEntry->NameInformation.FileName);
288 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
289 AFS_TRACE_LEVEL_VERBOSE,
290 "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
291 &pObjectInfo->Fcb->NPFcb->Resource,
292 PsGetCurrentThread());
294 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
297 try_return( ntStatus = STATUS_REPARSE);
300 pFcb->ObjectInformation = pObjectInfo;
302 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
303 AFS_TRACE_LEVEL_VERBOSE,
304 "AFSInitFcb Initialized Fcb %08lX Name %wZ\n",
306 &DirEntry->NameInformation.FileName);
310 if( ntStatus != STATUS_SUCCESS)
313 if ( !NT_SUCCESS( ntStatus))
316 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
317 AFS_TRACE_LEVEL_ERROR,
318 "AFSInitFcb Failed to initialize fcb Status %08lX\n",
328 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
334 AFSReleaseResource( &pNPFcb->Resource);
336 ExDeleteResourceLite( &pNPFcb->PagingResource);
338 ExDeleteResourceLite( &pNPFcb->CcbListLock);
340 ExDeleteResourceLite( &pNPFcb->Resource);
343 AFSExFreePool( pFcb);
349 AFSExFreePool( pNPFcb);
358 AFSInitVolume( IN GUID *AuthGroup,
359 IN AFSFileID *RootFid,
360 OUT AFSVolumeCB **VolumeCB)
363 NTSTATUS ntStatus = STATUS_SUCCESS;
364 IO_STATUS_BLOCK stIoStatus = {0,0};
365 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
366 AFSNonPagedVolumeCB *pNonPagedVcb = NULL;
367 AFSVolumeCB *pVolumeCB = NULL;
368 AFSNonPagedObjectInfoCB *pNonPagedObject = NULL;
369 ULONGLONG ullIndex = 0;
370 BOOLEAN bReleaseLocks = FALSE;
371 AFSVolumeInfoCB stVolumeInformation;
372 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
379 // Before grabbing any locks ask the service for the volume information
380 // This may be a waste but we need to get this information prior to
381 // taking any volume tree locks. Don't do this for any 'reserved' cell entries
384 if( RootFid->Cell != 0)
387 RtlZeroMemory( &stVolumeInformation,
388 sizeof( AFSVolumeInfoCB));
390 ntStatus = AFSRetrieveVolumeInformation( AuthGroup,
392 &stVolumeInformation);
394 if( !NT_SUCCESS( ntStatus))
397 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
398 AFS_TRACE_LEVEL_ERROR,
399 "AFSInitVolume AFSRetrieveVolumeInformation(RootFid) failure %08lX\n",
402 try_return( ntStatus);
406 // Grab our tree locks and see if we raced with someone else
409 AFSAcquireExcl( pDeviceExt->Specific.RDR.VolumeTree.TreeLock,
412 AFSAcquireExcl( &pDeviceExt->Specific.RDR.VolumeListLock,
415 bReleaseLocks = TRUE;
417 ullIndex = AFSCreateHighIndex( RootFid);
419 ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
421 (AFSBTreeEntry **)&pVolumeCB);
423 if( NT_SUCCESS( ntStatus) &&
428 // So we don't lock with an invalidation call ...
431 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
433 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
435 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
437 bReleaseLocks = FALSE;
439 AFSAcquireExcl( pVolumeCB->VolumeLock,
442 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
444 *VolumeCB = pVolumeCB;
446 try_return( ntStatus);
450 // Revert our status from the above call back to success.
453 ntStatus = STATUS_SUCCESS;
457 // For the global root we allocate out volume node and insert it
458 // into the volume tree ...
461 pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
462 sizeof( AFSVolumeCB),
463 AFS_VCB_ALLOCATION_TAG);
465 if( pVolumeCB == NULL)
468 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
469 AFS_TRACE_LEVEL_ERROR,
470 "AFSInitVolume Failed to allocate the root volume cb\n");
472 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
475 RtlZeroMemory( pVolumeCB,
476 sizeof( AFSVolumeCB));
479 // The non paged portion
482 pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
483 sizeof( AFSNonPagedVolumeCB),
484 AFS_VCB_ALLOCATION_TAG);
486 if( pNonPagedVcb == NULL)
489 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
490 AFS_TRACE_LEVEL_ERROR,
491 "AFSInitVolume Failed to allocate the root non paged volume cb\n");
493 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
496 RtlZeroMemory( pNonPagedVcb,
497 sizeof( AFSNonPagedVolumeCB));
499 ExInitializeResourceLite( &pNonPagedVcb->VolumeLock);
501 ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
503 pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
504 sizeof( AFSNonPagedObjectInfoCB),
505 AFS_VCB_ALLOCATION_TAG);
507 if( pNonPagedObject == NULL)
510 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
511 AFS_TRACE_LEVEL_ERROR,
512 "AFSInitVolume Failed to allocate the root non paged object cb\n");
514 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
517 RtlZeroMemory( pNonPagedObject,
518 sizeof( AFSNonPagedObjectInfoCB));
520 ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
522 pVolumeCB->NonPagedVcb = pNonPagedVcb;
524 pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject;
526 pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock;
528 pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock;
530 pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
533 // Bias our reference by 1
536 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
537 AFS_TRACE_LEVEL_VERBOSE,
538 "AFSInitVolume Initializing count (1) on volume %08lX\n",
541 pVolumeCB->VolumeReferenceCount = 1;
543 AFSAcquireExcl( pVolumeCB->VolumeLock,
546 pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
547 sizeof( AFSDirectoryCB) + sizeof( WCHAR),
550 if( pVolumeCB->DirectoryCB == NULL)
553 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
556 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
557 sizeof( AFSNonPagedDirectoryCB),
558 AFS_DIR_ENTRY_NP_TAG);
560 if( pNonPagedDirEntry == NULL)
563 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
566 RtlZeroMemory( pVolumeCB->DirectoryCB,
567 sizeof( AFSDirectoryCB) + sizeof( WCHAR));
569 RtlZeroMemory( pNonPagedDirEntry,
570 sizeof( AFSNonPagedDirectoryCB));
572 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
574 pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry;
577 // Initialize the non-paged portion of the directory entry
580 KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime);
581 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime);
582 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime);
584 pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY;
586 SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME);
588 pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell;
589 pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume;
590 pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode;
591 pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique;
592 pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash;
594 pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
596 pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR);
598 pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length;
600 pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB));
602 RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer,
607 // Copy in the volume information retrieved above
610 RtlCopyMemory( &pVolumeCB->VolumeInformation,
611 &stVolumeInformation,
612 sizeof( AFSVolumeInfoCB));
618 pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
620 pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
623 // Insert the volume into our volume tree. Don't insert any reserved entries
626 if( RootFid->Cell != 0)
629 pVolumeCB->TreeEntry.HashIndex = ullIndex;
631 if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL)
634 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
636 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
641 if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
642 &pVolumeCB->TreeEntry)))
645 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
649 if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
652 pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB;
657 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB;
659 pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail;
662 pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB;
665 *VolumeCB = pVolumeCB;
669 if( !NT_SUCCESS( ntStatus))
672 if( pNonPagedVcb != NULL)
675 AFSReleaseResource( pVolumeCB->VolumeLock);
677 ExDeleteResourceLite( &pNonPagedVcb->VolumeLock);
679 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
681 AFSExFreePool( pNonPagedVcb);
684 if( pNonPagedObject != NULL)
687 ExDeleteResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
689 AFSExFreePool( pNonPagedObject);
692 if( pVolumeCB != NULL)
695 if( pVolumeCB->DirectoryCB != NULL)
698 AFSExFreePool( pVolumeCB->DirectoryCB);
701 AFSExFreePool( pVolumeCB);
704 if( pNonPagedDirEntry != NULL)
707 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
709 AFSExFreePool( pNonPagedDirEntry);
716 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
718 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
726 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
729 NTSTATUS ntStatus = STATUS_SUCCESS;
730 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
736 // Remove the volume from the tree and list
737 // Don't process the list information for reserved entries
740 if( VolumeCB->ObjectInformation.FileId.Cell != 0)
743 if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE))
746 AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
747 &VolumeCB->TreeEntry);
750 if( VolumeCB->ListEntry.fLink == NULL)
753 pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink;
755 if( pDeviceExt->Specific.RDR.VolumeListTail != NULL)
758 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL;
764 ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink;
767 if( VolumeCB->ListEntry.bLink == NULL)
770 pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink;
772 if( pDeviceExt->Specific.RDR.VolumeListHead != NULL)
775 pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL;
781 ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink;
786 // Remove any PIOctl objects we have
789 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL)
792 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
795 AFSRemoveFcb( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
798 AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
800 AFSExFreePool( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB);
803 if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
807 // Release the fid in the service
810 AFSReleaseFid( &VolumeCB->ObjectInformation.FileId);
814 // Free up the memory
817 if( VolumeCB->NonPagedVcb != NULL)
820 if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
822 AFSReleaseResource( VolumeCB->VolumeLock);
825 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock);
827 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
829 AFSExFreePool( VolumeCB->NonPagedVcb);
832 if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
835 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
837 AFSExFreePool( VolumeCB->ObjectInformation.NonPagedInfo);
840 if( VolumeCB->DirectoryCB != NULL)
843 if( VolumeCB->DirectoryCB->NonPaged != NULL)
846 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
848 AFSExFreePool( VolumeCB->DirectoryCB->NonPaged);
851 AFSExFreePool( VolumeCB->DirectoryCB);
854 AFSExFreePool( VolumeCB);
862 // Function: AFSInitRootFcb
866 // This function performs Root node Fcb initialization
870 // A status is returned for the function
874 AFSInitRootFcb( IN ULONGLONG ProcessID,
875 IN AFSVolumeCB *VolumeCB)
878 NTSTATUS ntStatus = STATUS_SUCCESS;
880 AFSNonPagedFcb *pNPFcb = NULL;
881 IO_STATUS_BLOCK stIoStatus = {0,0};
882 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
888 // Initialize the root fcb
891 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
893 AFS_FCB_ALLOCATION_TAG);
898 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
899 AFS_TRACE_LEVEL_ERROR,
900 "AFSInitRootFcb Failed to allocate the root fcb\n");
902 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
908 pFcb->Header.NodeByteSize = sizeof( AFSFcb);
909 pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;
911 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
912 sizeof( AFSNonPagedFcb),
913 AFS_FCB_NP_ALLOCATION_TAG);
918 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
919 AFS_TRACE_LEVEL_ERROR,
920 "AFSInitRootFcb Failed to allocate the non-paged fcb\n");
922 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
925 RtlZeroMemory( pNPFcb,
926 sizeof( AFSNonPagedFcb));
928 pNPFcb->Size = sizeof( AFSNonPagedFcb);
929 pNPFcb->Type = AFS_NON_PAGED_FCB;
932 // OK, initialize the entry
935 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
937 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
939 ExInitializeResourceLite( &pNPFcb->Resource);
941 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
942 AFS_TRACE_LEVEL_VERBOSE,
943 "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
945 PsGetCurrentThread());
947 AFSAcquireExcl( &pNPFcb->Resource,
950 ExInitializeResourceLite( &pNPFcb->PagingResource);
952 ExInitializeResourceLite( &pNPFcb->CcbListLock);
954 pFcb->Header.Resource = &pNPFcb->Resource;
956 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
958 pFcb->NPFcb = pNPFcb;
961 // Initialize enumeration information
964 KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
969 // Save the root Fcb in the VolumeCB
972 VolumeCB->ObjectInformation.Fcb = pFcb;
974 VolumeCB->ObjectInformation.VolumeCB = VolumeCB;
976 VolumeCB->RootFcb = pFcb;
978 pFcb->ObjectInformation = &VolumeCB->ObjectInformation;
982 if( !NT_SUCCESS( ntStatus))
988 AFSRemoveRootFcb( pFcb);
997 // Function: AFSRemoveRootFcb
1001 // This function performs root Fcb removal/deallocation
1005 // A status is returned for the function
1009 AFSRemoveRootFcb( IN AFSFcb *RootFcb)
1012 AFSDirectoryCB *pCurrentDirEntry = NULL;
1013 AFSVolumeCB *pVolumeCB = RootFcb->ObjectInformation->VolumeCB;
1015 if( RootFcb->NPFcb != NULL)
1022 ExDeleteResourceLite( &RootFcb->NPFcb->Resource);
1024 ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
1026 ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock);
1029 // The non paged region
1032 AFSExFreePool( RootFcb->NPFcb);
1036 // And the Fcb itself
1039 AFSExFreePool( RootFcb);
1045 // Function: AFSRemoveFcb
1049 // This function performs Fcb removal/deallocation
1053 // A status is returned for the function
1057 AFSRemoveFcb( IN AFSFcb *Fcb)
1061 // Uninitialize the file lock if it is a file
1064 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1065 AFS_TRACE_LEVEL_VERBOSE,
1066 "AFSRemoveFcb Removing Fcb %08lX\n",
1069 if( Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
1072 FsRtlUninitializeFileLock( &Fcb->Specific.File.FileLock);
1075 // The resource we allocated
1078 ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.ExtentsResource );
1080 ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.DirtyExtentsListLock);
1083 else if( Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1090 // Tear down the FM specific contexts
1093 FsRtlTeardownPerStreamContexts( &Fcb->Header);
1096 // Delete the resources
1099 ExDeleteResourceLite( &Fcb->NPFcb->Resource);
1101 ExDeleteResourceLite( &Fcb->NPFcb->PagingResource);
1103 ExDeleteResourceLite( &Fcb->NPFcb->CcbListLock);
1106 // The non paged region
1109 AFSExFreePool( Fcb->NPFcb);
1112 // And the Fcb itself, which includes the name
1115 AFSExFreePool( Fcb);
1121 AFSInitCcb( IN OUT AFSCcb **Ccb)
1124 NTSTATUS Status = STATUS_SUCCESS;
1125 AFSCcb *pCcb = NULL;
1131 // Allocate our context control block
1134 pCcb = (AFSCcb *)AFSExAllocatePoolWithTag( PagedPool,
1136 AFS_CCB_ALLOCATION_TAG);
1141 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1142 AFS_TRACE_LEVEL_ERROR,
1143 "AFSInitCcb Failed to allocate Ccb\n");
1145 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1148 RtlZeroMemory( pCcb,
1151 pCcb->Size = sizeof( AFSCcb);
1152 pCcb->Type = AFS_CCB;
1162 if( !NT_SUCCESS( Status))
1168 AFSExFreePool( pCcb);
1179 // Function: AFSRemoveCcb
1183 // This function performs Ccb removal/deallocation
1187 // A status is returned for the function
1191 AFSRemoveCcb( IN AFSFcb *Fcb,
1195 NTSTATUS ntStatus = STATUS_SUCCESS;
1198 BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST))
1201 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1204 if( Ccb->ListEntry.fLink == NULL)
1207 Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink;
1209 if( Fcb->CcbListTail != NULL)
1211 Fcb->CcbListTail->ListEntry.fLink = NULL;
1216 ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink;
1219 if( Ccb->ListEntry.bLink == NULL)
1222 Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink;
1224 if( Fcb->CcbListHead != NULL)
1226 Fcb->CcbListHead->ListEntry.bLink = NULL;
1231 ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink;
1234 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
1237 if( Ccb->MaskName.Buffer != NULL)
1240 AFSExFreePool( Ccb->MaskName.Buffer);
1243 if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
1246 AFSExFreePool( Ccb->FullFileName.Buffer);
1250 // If we have a name array then delete it
1253 if( Ccb->NameArray != NULL)
1256 AFSFreeNameArray( Ccb->NameArray);
1258 Ccb->NameArray = NULL;
1261 if( Ccb->DirectorySnapshot != NULL)
1264 AFSExFreePool( Ccb->DirectorySnapshot);
1266 Ccb->DirectorySnapshot = NULL;
1269 if( Ccb->NotifyMask.Buffer != NULL)
1272 AFSExFreePool( Ccb->NotifyMask.Buffer);
1279 AFSExFreePool( Ccb);
1285 AFSInsertCcb( IN AFSFcb *Fcb,
1289 NTSTATUS ntStatus = STATUS_SUCCESS;
1291 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1294 if( Fcb->CcbListHead == NULL)
1296 Fcb->CcbListHead = Ccb;
1300 Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb;
1302 Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail;
1305 Fcb->CcbListTail = Ccb;
1307 SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST);
1309 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);