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 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 // Initialize some fields in the Fcb
174 pFcb->ObjectInformation = pObjectInfo;
176 pObjectInfo->Fcb = pFcb;
179 // Set type specific information
182 if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
186 // Reset the type to a directory type
189 pFcb->Header.NodeTypeCode = AFS_DIRECTORY_FCB;
192 // Initialize enumeration information
195 KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
199 else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
202 pFcb->Header.NodeTypeCode = AFS_FILE_FCB;
205 // Initialize the file specific information
208 FsRtlInitializeFileLock( &pFcb->Specific.File.FileLock,
212 bUninitFileLock = TRUE;
215 // Initialize the header file sizes to our dir entry information
218 pFcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
219 pFcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
220 pFcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
223 // Initialize the Extents resources and so forth. The
224 // quiescent state is that no one has the extents for
225 // IO (do the extents are not busy) and there is no
226 // extents request outstanding (and hence the "last
227 // one" is complete).
229 ExInitializeResourceLite( &pNPFcb->Specific.File.ExtentsResource );
231 KeInitializeEvent( &pNPFcb->Specific.File.ExtentsRequestComplete,
235 for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
237 InitializeListHead(&pFcb->Specific.File.ExtentsLists[i]);
240 pNPFcb->Specific.File.DirtyListHead = NULL;
241 pNPFcb->Specific.File.DirtyListTail = NULL;
243 ExInitializeResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
245 KeInitializeEvent( &pNPFcb->Specific.File.FlushEvent,
246 SynchronizationEvent,
249 KeInitializeEvent( &pNPFcb->Specific.File.QueuedFlushEvent,
253 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
256 pFcb->Header.NodeTypeCode = AFS_SPECIAL_SHARE_FCB;
258 else if( pObjectInfo->FileType == AFS_FILE_TYPE_PIOCTL)
261 pFcb->Header.NodeTypeCode = AFS_IOCTL_FCB;
263 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
266 pFcb->Header.NodeTypeCode = AFS_SYMBOLIC_LINK_FCB;
268 else if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
271 pFcb->Header.NodeTypeCode = AFS_MOUNT_POINT_FCB;
273 else if( pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
275 pFcb->Header.NodeTypeCode = AFS_DFS_LINK_FCB;
279 pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
283 // And return the Fcb
288 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
289 AFS_TRACE_LEVEL_VERBOSE,
290 "AFSInitFcb Initialized Fcb %08lX Name %wZ\n",
292 &DirEntry->NameInformation.FileName);
296 if( !NT_SUCCESS( ntStatus))
299 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
300 AFS_TRACE_LEVEL_ERROR,
301 "AFSInitFcb Failed to initialize fcb Status %08lX\n",
310 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
316 AFSReleaseResource( &pNPFcb->Resource);
318 ExDeleteResourceLite( &pNPFcb->PagingResource);
320 ExDeleteResourceLite( &pNPFcb->CcbListLock);
322 ExDeleteResourceLite( &pNPFcb->Resource);
325 AFSExFreePool( pFcb);
331 AFSExFreePool( pNPFcb);
346 AFSInitVolume( IN GUID *AuthGroup,
347 IN AFSFileID *RootFid,
348 OUT AFSVolumeCB **VolumeCB)
351 NTSTATUS ntStatus = STATUS_SUCCESS;
352 IO_STATUS_BLOCK stIoStatus = {0,0};
353 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
354 AFSNonPagedVolumeCB *pNonPagedVcb = NULL;
355 AFSVolumeCB *pVolumeCB = NULL;
356 AFSNonPagedObjectInfoCB *pNonPagedObject = NULL;
357 ULONGLONG ullIndex = 0;
358 BOOLEAN bReleaseLocks = FALSE;
359 AFSVolumeInfoCB stVolumeInformation;
360 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
366 // Before grabbing any locks ask the service for the volume information
367 // This may be a waste but we need to get this information prior to
368 // taking any volume tree locks. Don't do this for any 'reserved' cell entries
371 if( RootFid->Cell != 0)
374 RtlZeroMemory( &stVolumeInformation,
375 sizeof( AFSVolumeInfoCB));
377 ntStatus = AFSRetrieveVolumeInformation( AuthGroup,
379 &stVolumeInformation);
381 if( !NT_SUCCESS( ntStatus))
384 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
385 AFS_TRACE_LEVEL_ERROR,
386 "AFSInitVolume AFSRetrieveVolumeInformation(RootFid) failure %08lX\n",
389 try_return( ntStatus);
393 // Grab our tree locks and see if we raced with someone else
396 AFSAcquireExcl( pDeviceExt->Specific.RDR.VolumeTree.TreeLock,
399 AFSAcquireExcl( &pDeviceExt->Specific.RDR.VolumeListLock,
402 bReleaseLocks = TRUE;
404 ullIndex = AFSCreateHighIndex( RootFid);
406 ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
408 (AFSBTreeEntry **)&pVolumeCB);
410 if( NT_SUCCESS( ntStatus) &&
415 // So we don't lock with an invalidation call ...
418 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
420 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
422 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
424 bReleaseLocks = FALSE;
426 AFSAcquireExcl( pVolumeCB->VolumeLock,
429 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
431 *VolumeCB = pVolumeCB;
433 try_return( ntStatus);
437 // Revert our status from the above call back to success.
440 ntStatus = STATUS_SUCCESS;
444 // For the global root we allocate out volume node and insert it
445 // into the volume tree ...
448 pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
449 sizeof( AFSVolumeCB),
450 AFS_VCB_ALLOCATION_TAG);
452 if( pVolumeCB == NULL)
455 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
456 AFS_TRACE_LEVEL_ERROR,
457 "AFSInitVolume Failed to allocate the root volume cb\n");
459 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
462 RtlZeroMemory( pVolumeCB,
463 sizeof( AFSVolumeCB));
466 // The non paged portion
469 pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
470 sizeof( AFSNonPagedVolumeCB),
471 AFS_VCB_ALLOCATION_TAG);
473 if( pNonPagedVcb == NULL)
476 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
477 AFS_TRACE_LEVEL_ERROR,
478 "AFSInitVolume Failed to allocate the root non paged volume cb\n");
480 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
483 RtlZeroMemory( pNonPagedVcb,
484 sizeof( AFSNonPagedVolumeCB));
486 ExInitializeResourceLite( &pNonPagedVcb->VolumeLock);
488 ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
490 pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
491 sizeof( AFSNonPagedObjectInfoCB),
492 AFS_VCB_ALLOCATION_TAG);
494 if( pNonPagedObject == NULL)
497 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
498 AFS_TRACE_LEVEL_ERROR,
499 "AFSInitVolume Failed to allocate the root non paged object cb\n");
501 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
504 RtlZeroMemory( pNonPagedObject,
505 sizeof( AFSNonPagedObjectInfoCB));
507 ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
509 pVolumeCB->NonPagedVcb = pNonPagedVcb;
511 pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject;
513 pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock;
515 pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock;
517 pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
520 // Bias our reference by 1
523 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
524 AFS_TRACE_LEVEL_VERBOSE,
525 "AFSInitVolume Initializing count (1) on volume %08lX\n",
528 pVolumeCB->VolumeReferenceCount = 1;
530 AFSAcquireExcl( pVolumeCB->VolumeLock,
533 pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
534 sizeof( AFSDirectoryCB) + sizeof( WCHAR),
537 if( pVolumeCB->DirectoryCB == NULL)
540 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
543 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
544 sizeof( AFSNonPagedDirectoryCB),
545 AFS_DIR_ENTRY_NP_TAG);
547 if( pNonPagedDirEntry == NULL)
550 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
553 RtlZeroMemory( pVolumeCB->DirectoryCB,
554 sizeof( AFSDirectoryCB) + sizeof( WCHAR));
556 RtlZeroMemory( pNonPagedDirEntry,
557 sizeof( AFSNonPagedDirectoryCB));
559 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
561 pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry;
564 // Initialize the non-paged portion of the directory entry
567 KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime);
568 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime);
569 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime);
571 pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY;
573 SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME);
575 pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell;
576 pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume;
577 pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode;
578 pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique;
579 pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash;
581 pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
583 pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR);
585 pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length;
587 pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB));
589 RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer,
594 // Copy in the volume information retrieved above
597 RtlCopyMemory( &pVolumeCB->VolumeInformation,
598 &stVolumeInformation,
599 sizeof( AFSVolumeInfoCB));
605 pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
607 pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
610 // Insert the volume into our volume tree. Don't insert any reserved entries
613 if( RootFid->Cell != 0)
616 pVolumeCB->TreeEntry.HashIndex = ullIndex;
618 if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL)
621 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
623 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
628 if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
629 &pVolumeCB->TreeEntry)))
632 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
636 if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
639 pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB;
644 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB;
646 pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail;
649 pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB;
652 *VolumeCB = pVolumeCB;
656 if( !NT_SUCCESS( ntStatus))
659 if( pNonPagedVcb != NULL)
662 AFSReleaseResource( pVolumeCB->VolumeLock);
664 ExDeleteResourceLite( &pNonPagedVcb->VolumeLock);
666 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
668 AFSExFreePool( pNonPagedVcb);
671 if( pNonPagedObject != NULL)
674 ExDeleteResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
676 AFSExFreePool( pNonPagedObject);
679 if( pVolumeCB != NULL)
682 if( pVolumeCB->DirectoryCB != NULL)
685 AFSExFreePool( pVolumeCB->DirectoryCB);
688 AFSExFreePool( pVolumeCB);
691 if( pNonPagedDirEntry != NULL)
694 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
696 AFSExFreePool( pNonPagedDirEntry);
703 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
705 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
713 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
716 NTSTATUS ntStatus = STATUS_SUCCESS;
717 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
723 // Remove the volume from the tree and list
724 // Don't process the list information for reserved entries
727 if( VolumeCB->ObjectInformation.FileId.Cell != 0)
730 if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE))
733 AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
734 &VolumeCB->TreeEntry);
737 if( VolumeCB->ListEntry.fLink == NULL)
740 pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink;
742 if( pDeviceExt->Specific.RDR.VolumeListTail != NULL)
745 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL;
751 ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink;
754 if( VolumeCB->ListEntry.bLink == NULL)
757 pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink;
759 if( pDeviceExt->Specific.RDR.VolumeListHead != NULL)
762 pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL;
768 ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink;
773 // Remove any PIOctl objects we have
776 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL)
779 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
782 AFSRemoveFcb( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
785 AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
787 AFSExFreePool( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB);
790 if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
794 // Release the fid in the service
797 AFSReleaseFid( &VolumeCB->ObjectInformation.FileId);
801 // Free up the memory
804 if( VolumeCB->NonPagedVcb != NULL)
807 if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
809 AFSReleaseResource( VolumeCB->VolumeLock);
812 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock);
814 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
816 AFSExFreePool( VolumeCB->NonPagedVcb);
819 if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
822 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
824 AFSExFreePool( VolumeCB->ObjectInformation.NonPagedInfo);
827 if( VolumeCB->DirectoryCB != NULL)
830 if( VolumeCB->DirectoryCB->NonPaged != NULL)
833 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
835 AFSExFreePool( VolumeCB->DirectoryCB->NonPaged);
838 AFSExFreePool( VolumeCB->DirectoryCB);
841 AFSExFreePool( VolumeCB);
849 // Function: AFSInitRootFcb
853 // This function performs Root node Fcb initialization
857 // A status is returned for the function
861 AFSInitRootFcb( IN ULONGLONG ProcessID,
862 IN AFSVolumeCB *VolumeCB)
865 NTSTATUS ntStatus = STATUS_SUCCESS;
867 AFSNonPagedFcb *pNPFcb = NULL;
868 IO_STATUS_BLOCK stIoStatus = {0,0};
869 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
875 // Initialize the root fcb
878 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
880 AFS_FCB_ALLOCATION_TAG);
885 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
886 AFS_TRACE_LEVEL_ERROR,
887 "AFSInitRootFcb Failed to allocate the root fcb\n");
889 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
895 pFcb->Header.NodeByteSize = sizeof( AFSFcb);
896 pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;
898 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
899 sizeof( AFSNonPagedFcb),
900 AFS_FCB_NP_ALLOCATION_TAG);
905 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
906 AFS_TRACE_LEVEL_ERROR,
907 "AFSInitRootFcb Failed to allocate the non-paged fcb\n");
909 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
912 RtlZeroMemory( pNPFcb,
913 sizeof( AFSNonPagedFcb));
915 pNPFcb->Size = sizeof( AFSNonPagedFcb);
916 pNPFcb->Type = AFS_NON_PAGED_FCB;
919 // OK, initialize the entry
922 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
924 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
926 ExInitializeResourceLite( &pNPFcb->Resource);
928 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
929 AFS_TRACE_LEVEL_VERBOSE,
930 "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
932 PsGetCurrentThread());
934 AFSAcquireExcl( &pNPFcb->Resource,
937 ExInitializeResourceLite( &pNPFcb->PagingResource);
939 ExInitializeResourceLite( &pNPFcb->CcbListLock);
941 pFcb->Header.Resource = &pNPFcb->Resource;
943 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
945 pFcb->NPFcb = pNPFcb;
948 // Initialize enumeration information
951 KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
956 // Save the root Fcb in the VolumeCB
959 VolumeCB->ObjectInformation.Fcb = pFcb;
961 VolumeCB->ObjectInformation.VolumeCB = VolumeCB;
963 VolumeCB->RootFcb = pFcb;
965 pFcb->ObjectInformation = &VolumeCB->ObjectInformation;
969 if( !NT_SUCCESS( ntStatus))
975 AFSRemoveRootFcb( pFcb);
984 // Function: AFSRemoveRootFcb
988 // This function performs root Fcb removal/deallocation
992 // A status is returned for the function
996 AFSRemoveRootFcb( IN AFSFcb *RootFcb)
999 AFSDirectoryCB *pCurrentDirEntry = NULL;
1000 AFSVolumeCB *pVolumeCB = RootFcb->ObjectInformation->VolumeCB;
1002 if( RootFcb->NPFcb != NULL)
1009 ExDeleteResourceLite( &RootFcb->NPFcb->Resource);
1011 ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
1013 ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock);
1016 // The non paged region
1019 AFSExFreePool( RootFcb->NPFcb);
1023 // And the Fcb itself
1026 AFSExFreePool( RootFcb);
1032 // Function: AFSRemoveFcb
1036 // This function performs Fcb removal/deallocation
1040 // A status is returned for the function
1044 AFSRemoveFcb( IN AFSFcb *Fcb)
1048 // Uninitialize the file lock if it is a file
1051 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1052 AFS_TRACE_LEVEL_VERBOSE,
1053 "AFSRemoveFcb Removing Fcb %08lX\n",
1056 if( Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
1059 FsRtlUninitializeFileLock( &Fcb->Specific.File.FileLock);
1062 // The resource we allocated
1065 ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.ExtentsResource );
1067 ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.DirtyExtentsListLock);
1070 else if( Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1077 // Tear down the FM specific contexts
1080 FsRtlTeardownPerStreamContexts( &Fcb->Header);
1083 // Delete the resources
1086 ExDeleteResourceLite( &Fcb->NPFcb->Resource);
1088 ExDeleteResourceLite( &Fcb->NPFcb->PagingResource);
1090 ExDeleteResourceLite( &Fcb->NPFcb->CcbListLock);
1093 // The non paged region
1096 AFSExFreePool( Fcb->NPFcb);
1099 // And the Fcb itself, which includes the name
1102 AFSExFreePool( Fcb);
1108 AFSInitCcb( IN OUT AFSCcb **Ccb)
1111 NTSTATUS Status = STATUS_SUCCESS;
1112 AFSCcb *pCcb = NULL;
1118 // Allocate our context control block
1121 pCcb = (AFSCcb *)AFSExAllocatePoolWithTag( PagedPool,
1123 AFS_CCB_ALLOCATION_TAG);
1128 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1129 AFS_TRACE_LEVEL_ERROR,
1130 "AFSInitCcb Failed to allocate Ccb\n");
1132 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1135 RtlZeroMemory( pCcb,
1138 pCcb->Size = sizeof( AFSCcb);
1139 pCcb->Type = AFS_CCB;
1149 if( !NT_SUCCESS( Status))
1155 AFSExFreePool( pCcb);
1166 // Function: AFSRemoveCcb
1170 // This function performs Ccb removal/deallocation
1174 // A status is returned for the function
1178 AFSRemoveCcb( IN AFSFcb *Fcb,
1182 NTSTATUS ntStatus = STATUS_SUCCESS;
1185 BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST))
1188 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1191 if( Ccb->ListEntry.fLink == NULL)
1194 Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink;
1196 if( Fcb->CcbListTail != NULL)
1198 Fcb->CcbListTail->ListEntry.fLink = NULL;
1203 ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink;
1206 if( Ccb->ListEntry.bLink == NULL)
1209 Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink;
1211 if( Fcb->CcbListHead != NULL)
1213 Fcb->CcbListHead->ListEntry.bLink = NULL;
1218 ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink;
1221 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
1224 if( Ccb->MaskName.Buffer != NULL)
1227 AFSExFreePool( Ccb->MaskName.Buffer);
1230 if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
1233 AFSExFreePool( Ccb->FullFileName.Buffer);
1237 // If we have a name array then delete it
1240 if( Ccb->NameArray != NULL)
1243 AFSFreeNameArray( Ccb->NameArray);
1245 Ccb->NameArray = NULL;
1248 if( Ccb->DirectorySnapshot != NULL)
1251 AFSExFreePool( Ccb->DirectorySnapshot);
1253 Ccb->DirectorySnapshot = NULL;
1256 if( Ccb->NotifyMask.Buffer != NULL)
1259 AFSExFreePool( Ccb->NotifyMask.Buffer);
1266 AFSExFreePool( Ccb);
1272 AFSInsertCcb( IN AFSFcb *Fcb,
1276 NTSTATUS ntStatus = STATUS_SUCCESS;
1278 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1281 if( Fcb->CcbListHead == NULL)
1283 Fcb->CcbListHead = Ccb;
1287 Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb;
1289 Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail;
1292 Fcb->CcbListTail = Ccb;
1294 SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST);
1296 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);