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,
58 NTSTATUS ntStatus = STATUS_SUCCESS;
59 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
61 AFSNonPagedFcb *pNPFcb = NULL;
62 IO_STATUS_BLOCK stIoSb = {0,0};
63 BOOLEAN bUninitFileLock = FALSE;
64 USHORT usFcbLength = 0;
65 ULONGLONG ullIndex = 0;
66 AFSDirEnumEntry *pDirEnumCB = NULL;
67 AFSObjectInfoCB *pObjectInfo = NULL, *pParentObjectInfo = NULL;
68 AFSVolumeCB *pVolumeCB = NULL;
73 pObjectInfo = DirEntry->ObjectInformation;
75 pParentObjectInfo = pObjectInfo->ParentObjectInformation;
77 pVolumeCB = pObjectInfo->VolumeCB;
80 // Allocate the Fcb and the nonpaged portion of the Fcb.
83 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
84 AFS_TRACE_LEVEL_VERBOSE_2,
85 "AFSInitFcb Initializing fcb for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
86 &DirEntry->NameInformation.FileName,
87 pObjectInfo->FileId.Cell,
88 pObjectInfo->FileId.Volume,
89 pObjectInfo->FileId.Vnode,
90 pObjectInfo->FileId.Unique);
92 usFcbLength = sizeof( AFSFcb);
94 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
96 AFS_FCB_ALLOCATION_TAG);
101 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
102 AFS_TRACE_LEVEL_ERROR,
103 "AFSInitFcb Failed to allocate fcb\n");
105 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
111 pFcb->Header.NodeByteSize = usFcbLength;
113 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
114 sizeof( AFSNonPagedFcb),
115 AFS_FCB_NP_ALLOCATION_TAG);
120 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
121 AFS_TRACE_LEVEL_ERROR,
122 "AFSInitFcb Failed to allocate non-paged fcb\n");
124 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
127 RtlZeroMemory( pNPFcb,
128 sizeof( AFSNonPagedFcb));
130 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 pFcb->Header.Resource = &pNPFcb->Resource;
151 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
154 // Grab the Fcb for processing
157 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
158 AFS_TRACE_LEVEL_VERBOSE,
159 "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
161 PsGetCurrentThread());
163 AFSAcquireExcl( &pNPFcb->Resource,
166 pFcb->NPFcb = pNPFcb;
169 // Initialize some fields in the Fcb
172 pFcb->ObjectInformation = pObjectInfo;
174 pObjectInfo->Fcb = pFcb;
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;
190 // Initialize enumeration information
193 KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
197 else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
200 pFcb->Header.NodeTypeCode = AFS_FILE_FCB;
203 // Initialize the file specific information
206 FsRtlInitializeFileLock( &pFcb->Specific.File.FileLock,
210 bUninitFileLock = TRUE;
213 // Initialize the header file sizes to our dir entry information
216 pFcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
217 pFcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
218 pFcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
221 // Initialize the Extents resources and so forth. The
222 // quiescent state is that no one has the extents for
223 // IO (do the extents are not busy) and there is no
224 // extents request outstanding (and hence the "last
225 // one" is complete).
227 ExInitializeResourceLite( &pNPFcb->Specific.File.ExtentsResource );
229 KeInitializeEvent( &pNPFcb->Specific.File.ExtentsRequestComplete,
233 for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
235 InitializeListHead(&pFcb->Specific.File.ExtentsLists[i]);
238 pNPFcb->Specific.File.DirtyListHead = NULL;
239 pNPFcb->Specific.File.DirtyListTail = NULL;
241 ExInitializeResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
243 KeInitializeEvent( &pNPFcb->Specific.File.FlushEvent,
244 SynchronizationEvent,
247 KeInitializeEvent( &pNPFcb->Specific.File.QueuedFlushEvent,
251 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
254 pFcb->Header.NodeTypeCode = AFS_SPECIAL_SHARE_FCB;
256 else if( pObjectInfo->FileType == AFS_FILE_TYPE_PIOCTL)
259 pFcb->Header.NodeTypeCode = AFS_IOCTL_FCB;
261 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
264 pFcb->Header.NodeTypeCode = AFS_SYMBOLIC_LINK_FCB;
266 else if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
269 pFcb->Header.NodeTypeCode = AFS_MOUNT_POINT_FCB;
271 else if( pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
273 pFcb->Header.NodeTypeCode = AFS_DFS_LINK_FCB;
278 try_return( ntStatus = STATUS_INVALID_PARAMETER);
282 // And return the Fcb
287 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
288 AFS_TRACE_LEVEL_VERBOSE,
289 "AFSInitFcb Initialized Fcb %08lX Name %wZ\n",
291 &DirEntry->NameInformation.FileName);
295 if( !NT_SUCCESS( ntStatus))
298 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
299 AFS_TRACE_LEVEL_ERROR,
300 "AFSInitFcb Failed to initialize fcb Status %08lX\n",
309 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
315 AFSReleaseResource( &pNPFcb->Resource);
317 ExDeleteResourceLite( &pNPFcb->PagingResource);
319 ExDeleteResourceLite( &pNPFcb->Resource);
322 AFSExFreePool( pFcb);
328 AFSExFreePool( pNPFcb);
343 AFSInitVolume( IN GUID *AuthGroup,
344 IN AFSFileID *RootFid,
345 OUT AFSVolumeCB **VolumeCB)
348 NTSTATUS ntStatus = STATUS_SUCCESS;
349 IO_STATUS_BLOCK stIoStatus = {0,0};
350 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
351 AFSNonPagedVolumeCB *pNonPagedVcb = NULL;
352 AFSVolumeCB *pVolumeCB = NULL;
353 AFSNonPagedObjectInfoCB *pNonPagedObject = NULL;
354 ULONGLONG ullIndex = 0;
355 BOOLEAN bReleaseLocks = FALSE;
356 AFSVolumeInfoCB stVolumeInformation;
357 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
363 // Before grabbing any locks ask the service for the volume information
364 // This may be a waste but we need to get this information prior to
365 // taking any volume tree locks. Don't do this for any 'reserved' cell entries
368 if( RootFid->Cell != 0)
371 RtlZeroMemory( &stVolumeInformation,
372 sizeof( AFSVolumeInfoCB));
374 ntStatus = AFSRetrieveVolumeInformation( AuthGroup,
376 &stVolumeInformation);
378 if( !NT_SUCCESS( ntStatus))
381 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
382 AFS_TRACE_LEVEL_ERROR,
383 "AFSInitVolume AFSRetrieveVolumeInformation(RootFid) failure %08lX\n",
386 try_return( ntStatus);
390 // Grab our tree locks and see if we raced with someone else
393 AFSAcquireExcl( pDeviceExt->Specific.RDR.VolumeTree.TreeLock,
396 AFSAcquireExcl( &pDeviceExt->Specific.RDR.VolumeListLock,
399 bReleaseLocks = TRUE;
401 ullIndex = AFSCreateHighIndex( RootFid);
403 ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
405 (AFSBTreeEntry **)&pVolumeCB);
407 if( NT_SUCCESS( ntStatus) &&
412 // So we don't lock with an invalidation call ...
415 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
417 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
419 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
421 bReleaseLocks = FALSE;
423 AFSAcquireExcl( pVolumeCB->VolumeLock,
426 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
428 *VolumeCB = pVolumeCB;
430 try_return( ntStatus);
434 // Revert our status from the above call back to success.
437 ntStatus = STATUS_SUCCESS;
441 // For the global root we allocate out volume node and insert it
442 // into the volume tree ...
445 pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
446 sizeof( AFSVolumeCB),
447 AFS_VCB_ALLOCATION_TAG);
449 if( pVolumeCB == NULL)
452 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
453 AFS_TRACE_LEVEL_ERROR,
454 "AFSInitVolume Failed to allocate the root volume cb\n");
456 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
459 RtlZeroMemory( pVolumeCB,
460 sizeof( AFSVolumeCB));
463 // The non paged portion
466 pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
467 sizeof( AFSNonPagedVolumeCB),
468 AFS_VCB_ALLOCATION_TAG);
470 if( pNonPagedVcb == NULL)
473 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
474 AFS_TRACE_LEVEL_ERROR,
475 "AFSInitVolume Failed to allocate the root non paged volume cb\n");
477 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
480 RtlZeroMemory( pNonPagedVcb,
481 sizeof( AFSNonPagedVolumeCB));
483 ExInitializeResourceLite( &pNonPagedVcb->VolumeLock);
485 ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
487 pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
488 sizeof( AFSNonPagedObjectInfoCB),
489 AFS_VCB_ALLOCATION_TAG);
491 if( pNonPagedObject == NULL)
494 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
495 AFS_TRACE_LEVEL_ERROR,
496 "AFSInitVolume Failed to allocate the root non paged object cb\n");
498 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
501 RtlZeroMemory( pNonPagedObject,
502 sizeof( AFSNonPagedObjectInfoCB));
504 ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
506 pVolumeCB->NonPagedVcb = pNonPagedVcb;
508 pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject;
510 pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock;
512 pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock;
514 pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
517 // Bias our reference by 1
520 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
521 AFS_TRACE_LEVEL_VERBOSE,
522 "AFSInitVolume Initializing count (1) on volume %08lX\n",
525 pVolumeCB->VolumeReferenceCount = 1;
527 AFSAcquireExcl( pVolumeCB->VolumeLock,
530 pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
531 sizeof( AFSDirectoryCB) + sizeof( WCHAR),
534 if( pVolumeCB->DirectoryCB == NULL)
537 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
540 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
541 sizeof( AFSNonPagedDirectoryCB),
542 AFS_DIR_ENTRY_NP_TAG);
544 if( pNonPagedDirEntry == NULL)
547 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
550 RtlZeroMemory( pVolumeCB->DirectoryCB,
551 sizeof( AFSDirectoryCB) + sizeof( WCHAR));
553 RtlZeroMemory( pNonPagedDirEntry,
554 sizeof( AFSNonPagedDirectoryCB));
556 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
558 pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry;
561 // Initialize the non-paged portion of the directory entry
564 KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime);
565 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime);
566 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime);
568 pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY;
570 SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME);
572 pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell;
573 pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume;
574 pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode;
575 pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique;
576 pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash;
578 pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
580 pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR);
582 pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length;
584 pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB));
586 RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer,
591 // Copy in the volume information retrieved above
594 RtlCopyMemory( &pVolumeCB->VolumeInformation,
595 &stVolumeInformation,
596 sizeof( AFSVolumeInfoCB));
602 pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
604 pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
607 // Insert the volume into our volume tree. Don't insert any reserved entries
610 if( RootFid->Cell != 0)
613 pVolumeCB->TreeEntry.HashIndex = ullIndex;
615 if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL)
618 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
623 AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
624 &pVolumeCB->TreeEntry);
627 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
629 if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
632 pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB;
637 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB;
639 pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail;
642 pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB;
645 *VolumeCB = pVolumeCB;
649 if( !NT_SUCCESS( ntStatus))
652 if( pNonPagedVcb != NULL)
655 AFSReleaseResource( pVolumeCB->VolumeLock);
657 ExDeleteResourceLite( &pNonPagedVcb->VolumeLock);
659 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
661 AFSExFreePool( pNonPagedVcb);
664 if( pNonPagedObject != NULL)
667 ExDeleteResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
669 AFSExFreePool( pNonPagedObject);
672 if( pVolumeCB != NULL)
675 if( pVolumeCB->DirectoryCB != NULL)
678 AFSExFreePool( pVolumeCB->DirectoryCB);
681 AFSExFreePool( pVolumeCB);
684 if( pNonPagedDirEntry != NULL)
687 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
689 AFSExFreePool( pNonPagedDirEntry);
696 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
698 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
706 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
709 NTSTATUS ntStatus = STATUS_SUCCESS;
710 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
716 // Remove the volume from the tree and list
717 // Don't process the list information for reserved entries
720 if( VolumeCB->ObjectInformation.FileId.Cell != 0)
723 if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE))
726 AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
727 &VolumeCB->TreeEntry);
730 if( VolumeCB->ListEntry.fLink == NULL)
733 pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink;
735 if( pDeviceExt->Specific.RDR.VolumeListTail != NULL)
738 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL;
744 ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink;
747 if( VolumeCB->ListEntry.bLink == NULL)
750 pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink;
752 if( pDeviceExt->Specific.RDR.VolumeListHead != NULL)
755 pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL;
761 ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink;
766 // Remove any PIOctl objects we have
769 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL)
772 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
775 AFSRemoveFcb( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
778 AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
780 AFSExFreePool( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB);
783 if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
787 // Release the fid in the service
790 AFSReleaseFid( &VolumeCB->ObjectInformation.FileId);
794 // Free up the memory
797 if( VolumeCB->NonPagedVcb != NULL)
800 if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
803 AFSReleaseResource( VolumeCB->VolumeLock);
806 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock);
808 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
810 AFSExFreePool( VolumeCB->NonPagedVcb);
813 if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
816 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
818 AFSExFreePool( VolumeCB->ObjectInformation.NonPagedInfo);
821 if( VolumeCB->DirectoryCB != NULL)
824 if( VolumeCB->DirectoryCB->NonPaged != NULL)
827 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
829 AFSExFreePool( VolumeCB->DirectoryCB->NonPaged);
832 AFSExFreePool( VolumeCB->DirectoryCB);
835 AFSExFreePool( VolumeCB);
843 // Function: AFSInitRootFcb
847 // This function performs Root node Fcb initialization
851 // A status is returned for the function
855 AFSInitRootFcb( IN ULONGLONG ProcessID,
856 IN AFSVolumeCB *VolumeCB)
859 NTSTATUS ntStatus = STATUS_SUCCESS;
861 AFSNonPagedFcb *pNPFcb = NULL;
862 IO_STATUS_BLOCK stIoStatus = {0,0};
863 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
869 // Initialize the root fcb
872 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
874 AFS_FCB_ALLOCATION_TAG);
879 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
880 AFS_TRACE_LEVEL_ERROR,
881 "AFSInitRootFcb Failed to allocate the root fcb\n");
883 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
889 pFcb->Header.NodeByteSize = sizeof( AFSFcb);
890 pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;
892 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
893 sizeof( AFSNonPagedFcb),
894 AFS_FCB_NP_ALLOCATION_TAG);
899 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
900 AFS_TRACE_LEVEL_ERROR,
901 "AFSInitRootFcb Failed to allocate the non-paged fcb\n");
903 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
906 RtlZeroMemory( pNPFcb,
907 sizeof( AFSNonPagedFcb));
909 pNPFcb->Size = sizeof( AFSNonPagedFcb);
910 pNPFcb->Type = AFS_NON_PAGED_FCB;
913 // OK, initialize the entry
916 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
918 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
920 ExInitializeResourceLite( &pNPFcb->Resource);
922 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
923 AFS_TRACE_LEVEL_VERBOSE,
924 "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
926 PsGetCurrentThread());
928 AFSAcquireExcl( &pNPFcb->Resource,
931 ExInitializeResourceLite( &pNPFcb->PagingResource);
933 pFcb->Header.Resource = &pNPFcb->Resource;
935 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
937 pFcb->NPFcb = pNPFcb;
940 // Initialize enumeration information
943 KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
948 // Save the root Fcb in the VolumeCB
951 VolumeCB->ObjectInformation.Fcb = pFcb;
953 VolumeCB->ObjectInformation.VolumeCB = VolumeCB;
955 VolumeCB->RootFcb = pFcb;
957 pFcb->ObjectInformation = &VolumeCB->ObjectInformation;
961 if( !NT_SUCCESS( ntStatus))
967 AFSRemoveRootFcb( pFcb);
976 // Function: AFSRemoveRootFcb
980 // This function performs root Fcb removal/deallocation
984 // A status is returned for the function
988 AFSRemoveRootFcb( IN AFSFcb *RootFcb)
991 AFSDirectoryCB *pCurrentDirEntry = NULL;
992 AFSVolumeCB *pVolumeCB = RootFcb->ObjectInformation->VolumeCB;
994 if( RootFcb->NPFcb != NULL)
1001 ExDeleteResourceLite( &RootFcb->NPFcb->Resource);
1003 ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
1006 // The non paged region
1009 AFSExFreePool( RootFcb->NPFcb);
1013 // And the Fcb itself
1016 AFSExFreePool( RootFcb);
1022 // Function: AFSRemoveFcb
1026 // This function performs Fcb removal/deallocation
1030 // A status is returned for the function
1034 AFSRemoveFcb( IN AFSFcb *Fcb)
1038 // Uninitialize the file lock if it is a file
1041 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1042 AFS_TRACE_LEVEL_VERBOSE,
1043 "AFSRemoveFcb Removing Fcb %08lX\n",
1046 if( Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
1049 FsRtlUninitializeFileLock( &Fcb->Specific.File.FileLock);
1052 // The resource we allocated
1055 ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.ExtentsResource );
1057 ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.DirtyExtentsListLock);
1060 else if( Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1067 // Tear down the FM specific contexts
1070 FsRtlTeardownPerStreamContexts( &Fcb->Header);
1073 // Delete the resources
1076 ExDeleteResourceLite( &Fcb->NPFcb->Resource);
1078 ExDeleteResourceLite( &Fcb->NPFcb->PagingResource);
1083 // The non paged region
1086 AFSExFreePool( Fcb->NPFcb);
1089 // And the Fcb itself, which includes the name
1092 AFSExFreePool( Fcb);
1098 AFSInitCcb( IN OUT AFSCcb **Ccb)
1101 NTSTATUS Status = STATUS_SUCCESS;
1102 AFSCcb *pCcb = NULL;
1108 // Allocate our context control block
1111 pCcb = (AFSCcb *)AFSExAllocatePoolWithTag( PagedPool,
1113 AFS_CCB_ALLOCATION_TAG);
1118 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1119 AFS_TRACE_LEVEL_ERROR,
1120 "AFSInitCcb Failed to allocate Ccb\n");
1122 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1125 RtlZeroMemory( pCcb,
1128 pCcb->Size = sizeof( AFSCcb);
1129 pCcb->Type = AFS_CCB;
1139 if( !NT_SUCCESS( Status))
1145 AFSExFreePool( pCcb);
1156 // Function: AFSRemoveCcb
1160 // This function performs Ccb removal/deallocation
1164 // A status is returned for the function
1168 AFSRemoveCcb( IN AFSCcb *Ccb)
1171 NTSTATUS ntStatus = STATUS_SUCCESS;
1173 if( Ccb->MaskName.Buffer != NULL)
1176 AFSExFreePool( Ccb->MaskName.Buffer);
1179 if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
1182 AFSExFreePool( Ccb->FullFileName.Buffer);
1186 // If we have a name array then delete it
1189 if( Ccb->NameArray != NULL)
1192 AFSFreeNameArray( Ccb->NameArray);
1194 Ccb->NameArray = NULL;
1197 if( Ccb->DirectorySnapshot != NULL)
1200 AFSExFreePool( Ccb->DirectorySnapshot);
1202 Ccb->DirectorySnapshot = NULL;
1205 if( Ccb->NotifyMask.Buffer != NULL)
1208 AFSExFreePool( Ccb->NotifyMask.Buffer);
1215 AFSExFreePool( Ccb);