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;
183 else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
186 pFcb->Header.NodeTypeCode = AFS_FILE_FCB;
189 // Initialize the file specific information
192 FsRtlInitializeFileLock( &pFcb->Specific.File.FileLock,
196 bUninitFileLock = TRUE;
199 // Initialize the header file sizes to our dir entry information
202 pFcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
203 pFcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
204 pFcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
207 // Initialize the Extents resources and so forth. The
208 // quiescent state is that no one has the extents for
209 // IO (do the extents are not busy) and there is no
210 // extents request outstanding (and hence the "last
211 // one" is complete).
213 ExInitializeResourceLite( &pNPFcb->Specific.File.ExtentsResource );
215 KeInitializeEvent( &pNPFcb->Specific.File.ExtentsRequestComplete,
219 for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
221 InitializeListHead(&pFcb->Specific.File.ExtentsLists[i]);
224 pNPFcb->Specific.File.DirtyListHead = NULL;
225 pNPFcb->Specific.File.DirtyListTail = NULL;
227 ExInitializeResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
229 KeInitializeEvent( &pNPFcb->Specific.File.FlushEvent,
230 SynchronizationEvent,
233 KeInitializeEvent( &pNPFcb->Specific.File.QueuedFlushEvent,
237 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
240 pFcb->Header.NodeTypeCode = AFS_SPECIAL_SHARE_FCB;
242 else if( pObjectInfo->FileType == AFS_FILE_TYPE_PIOCTL)
245 pFcb->Header.NodeTypeCode = AFS_IOCTL_FCB;
247 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
250 pFcb->Header.NodeTypeCode = AFS_SYMBOLIC_LINK_FCB;
252 else if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
255 pFcb->Header.NodeTypeCode = AFS_MOUNT_POINT_FCB;
257 else if( pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
259 pFcb->Header.NodeTypeCode = AFS_DFS_LINK_FCB;
263 pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
267 // Initialize some fields in the Fcb
270 if ( InterlockedCompareExchangePointer( (PVOID *)&pObjectInfo->Fcb, pFcb, NULL) != NULL)
273 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
274 AFS_TRACE_LEVEL_WARNING,
275 "AFSInitFcb Raced Fcb %08lX pFcb %08lX Name %wZ\n",
278 &DirEntry->NameInformation.FileName);
280 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
281 AFS_TRACE_LEVEL_VERBOSE,
282 "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
283 &pObjectInfo->Fcb->NPFcb->Resource,
284 PsGetCurrentThread());
286 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
289 try_return( ntStatus = STATUS_REPARSE);
292 pFcb->ObjectInformation = pObjectInfo;
294 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
295 AFS_TRACE_LEVEL_VERBOSE,
296 "AFSInitFcb Initialized Fcb %08lX Name %wZ\n",
298 &DirEntry->NameInformation.FileName);
302 if( ntStatus != STATUS_SUCCESS)
305 if ( !NT_SUCCESS( ntStatus))
308 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
309 AFS_TRACE_LEVEL_ERROR,
310 "AFSInitFcb Failed to initialize fcb Status %08lX\n",
320 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
326 AFSReleaseResource( &pNPFcb->Resource);
328 ExDeleteResourceLite( &pNPFcb->PagingResource);
330 ExDeleteResourceLite( &pNPFcb->CcbListLock);
332 ExDeleteResourceLite( &pNPFcb->Resource);
335 AFSExFreePool( pFcb);
341 AFSExFreePool( pNPFcb);
350 AFSInitVolume( IN GUID *AuthGroup,
351 IN AFSFileID *RootFid,
352 OUT AFSVolumeCB **VolumeCB)
355 NTSTATUS ntStatus = STATUS_SUCCESS;
356 IO_STATUS_BLOCK stIoStatus = {0,0};
357 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
358 AFSNonPagedVolumeCB *pNonPagedVcb = NULL;
359 AFSVolumeCB *pVolumeCB = NULL;
360 AFSNonPagedObjectInfoCB *pNonPagedObject = NULL;
361 ULONGLONG ullIndex = 0;
362 BOOLEAN bReleaseLocks = FALSE;
363 AFSVolumeInfoCB stVolumeInformation;
364 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
371 // Before grabbing any locks ask the service for the volume information
372 // This may be a waste but we need to get this information prior to
373 // taking any volume tree locks. Don't do this for any 'reserved' cell entries
376 if( RootFid->Cell != 0)
379 RtlZeroMemory( &stVolumeInformation,
380 sizeof( AFSVolumeInfoCB));
382 ntStatus = AFSRetrieveVolumeInformation( AuthGroup,
384 &stVolumeInformation);
386 if( !NT_SUCCESS( ntStatus))
389 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
390 AFS_TRACE_LEVEL_ERROR,
391 "AFSInitVolume AFSRetrieveVolumeInformation(RootFid) failure %08lX\n",
394 try_return( ntStatus);
398 // Grab our tree locks and see if we raced with someone else
401 AFSAcquireExcl( pDeviceExt->Specific.RDR.VolumeTree.TreeLock,
404 AFSAcquireExcl( &pDeviceExt->Specific.RDR.VolumeListLock,
407 bReleaseLocks = TRUE;
409 ullIndex = AFSCreateHighIndex( RootFid);
411 ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
413 (AFSBTreeEntry **)&pVolumeCB);
415 if( NT_SUCCESS( ntStatus) &&
420 // So we don't lock with an invalidation call ...
423 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
425 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
427 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
429 bReleaseLocks = FALSE;
431 AFSAcquireExcl( pVolumeCB->VolumeLock,
434 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
436 *VolumeCB = pVolumeCB;
438 try_return( ntStatus);
442 // Revert our status from the above call back to success.
445 ntStatus = STATUS_SUCCESS;
449 // For the global root we allocate out volume node and insert it
450 // into the volume tree ...
453 pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
454 sizeof( AFSVolumeCB),
455 AFS_VCB_ALLOCATION_TAG);
457 if( pVolumeCB == NULL)
460 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
461 AFS_TRACE_LEVEL_ERROR,
462 "AFSInitVolume Failed to allocate the root volume cb\n");
464 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
467 RtlZeroMemory( pVolumeCB,
468 sizeof( AFSVolumeCB));
471 // The non paged portion
474 pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
475 sizeof( AFSNonPagedVolumeCB),
476 AFS_VCB_ALLOCATION_TAG);
478 if( pNonPagedVcb == NULL)
481 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
482 AFS_TRACE_LEVEL_ERROR,
483 "AFSInitVolume Failed to allocate the root non paged volume cb\n");
485 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
488 RtlZeroMemory( pNonPagedVcb,
489 sizeof( AFSNonPagedVolumeCB));
491 ExInitializeResourceLite( &pNonPagedVcb->VolumeLock);
493 ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
495 pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
496 sizeof( AFSNonPagedObjectInfoCB),
497 AFS_VCB_ALLOCATION_TAG);
499 if( pNonPagedObject == NULL)
502 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
503 AFS_TRACE_LEVEL_ERROR,
504 "AFSInitVolume Failed to allocate the root non paged object cb\n");
506 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
509 RtlZeroMemory( pNonPagedObject,
510 sizeof( AFSNonPagedObjectInfoCB));
512 ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
514 pVolumeCB->NonPagedVcb = pNonPagedVcb;
516 pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject;
518 pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock;
520 pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock;
522 pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
525 // Bias our reference by 1
528 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
529 AFS_TRACE_LEVEL_VERBOSE,
530 "AFSInitVolume Initializing count (1) on volume %08lX\n",
533 pVolumeCB->VolumeReferenceCount = 1;
535 AFSAcquireExcl( pVolumeCB->VolumeLock,
538 pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
539 sizeof( AFSDirectoryCB) + sizeof( WCHAR),
542 if( pVolumeCB->DirectoryCB == NULL)
545 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
548 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
549 sizeof( AFSNonPagedDirectoryCB),
550 AFS_DIR_ENTRY_NP_TAG);
552 if( pNonPagedDirEntry == NULL)
555 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
558 RtlZeroMemory( pVolumeCB->DirectoryCB,
559 sizeof( AFSDirectoryCB) + sizeof( WCHAR));
561 RtlZeroMemory( pNonPagedDirEntry,
562 sizeof( AFSNonPagedDirectoryCB));
564 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
566 pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry;
569 // Initialize the non-paged portion of the directory entry
572 KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime);
573 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime);
574 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime);
576 pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY;
578 SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME);
580 pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell;
581 pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume;
582 pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode;
583 pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique;
584 pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash;
586 pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
588 pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR);
590 pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length;
592 pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB));
594 RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer,
599 // Copy in the volume information retrieved above
602 RtlCopyMemory( &pVolumeCB->VolumeInformation,
603 &stVolumeInformation,
604 sizeof( AFSVolumeInfoCB));
610 pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
612 pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
615 // Insert the volume into our volume tree. Don't insert any reserved entries
618 if( RootFid->Cell != 0)
621 pVolumeCB->TreeEntry.HashIndex = ullIndex;
623 if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL)
626 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
628 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
633 if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
634 &pVolumeCB->TreeEntry)))
637 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
641 if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
644 pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB;
649 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB;
651 pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail;
654 pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB;
657 *VolumeCB = pVolumeCB;
661 if( !NT_SUCCESS( ntStatus))
664 if( pNonPagedVcb != NULL)
667 AFSReleaseResource( pVolumeCB->VolumeLock);
669 ExDeleteResourceLite( &pNonPagedVcb->VolumeLock);
671 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
673 AFSExFreePool( pNonPagedVcb);
676 if( pNonPagedObject != NULL)
679 ExDeleteResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
681 AFSExFreePool( pNonPagedObject);
684 if( pVolumeCB != NULL)
687 if( pVolumeCB->DirectoryCB != NULL)
690 AFSExFreePool( pVolumeCB->DirectoryCB);
693 AFSExFreePool( pVolumeCB);
696 if( pNonPagedDirEntry != NULL)
699 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
701 AFSExFreePool( pNonPagedDirEntry);
708 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
710 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
718 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
721 NTSTATUS ntStatus = STATUS_SUCCESS;
722 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
728 // Remove the volume from the tree and list
729 // Don't process the list information for reserved entries
732 if( VolumeCB->ObjectInformation.FileId.Cell != 0)
735 if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE))
738 AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
739 &VolumeCB->TreeEntry);
742 if( VolumeCB->ListEntry.fLink == NULL)
745 pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink;
747 if( pDeviceExt->Specific.RDR.VolumeListTail != NULL)
750 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL;
756 ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink;
759 if( VolumeCB->ListEntry.bLink == NULL)
762 pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink;
764 if( pDeviceExt->Specific.RDR.VolumeListHead != NULL)
767 pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL;
773 ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink;
778 // Remove any PIOctl objects we have
781 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL)
784 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
787 AFSRemoveFcb( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
790 AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
792 AFSExFreePool( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB);
795 if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
799 // Release the fid in the service
802 AFSReleaseFid( &VolumeCB->ObjectInformation.FileId);
806 // Free up the memory
809 if( VolumeCB->NonPagedVcb != NULL)
812 if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
814 AFSReleaseResource( VolumeCB->VolumeLock);
817 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock);
819 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
821 AFSExFreePool( VolumeCB->NonPagedVcb);
824 if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
827 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
829 AFSExFreePool( VolumeCB->ObjectInformation.NonPagedInfo);
832 if( VolumeCB->DirectoryCB != NULL)
835 if( VolumeCB->DirectoryCB->NonPaged != NULL)
838 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
840 AFSExFreePool( VolumeCB->DirectoryCB->NonPaged);
843 AFSExFreePool( VolumeCB->DirectoryCB);
846 AFSExFreePool( VolumeCB);
854 // Function: AFSInitRootFcb
858 // This function performs Root node Fcb initialization
862 // A status is returned for the function
866 AFSInitRootFcb( IN ULONGLONG ProcessID,
867 IN AFSVolumeCB *VolumeCB)
870 NTSTATUS ntStatus = STATUS_SUCCESS;
872 AFSNonPagedFcb *pNPFcb = NULL;
873 IO_STATUS_BLOCK stIoStatus = {0,0};
874 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
880 // Initialize the root fcb
883 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
885 AFS_FCB_ALLOCATION_TAG);
890 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
891 AFS_TRACE_LEVEL_ERROR,
892 "AFSInitRootFcb Failed to allocate the root fcb\n");
894 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
900 pFcb->Header.NodeByteSize = sizeof( AFSFcb);
901 pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;
903 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
904 sizeof( AFSNonPagedFcb),
905 AFS_FCB_NP_ALLOCATION_TAG);
910 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
911 AFS_TRACE_LEVEL_ERROR,
912 "AFSInitRootFcb Failed to allocate the non-paged fcb\n");
914 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
917 RtlZeroMemory( pNPFcb,
918 sizeof( AFSNonPagedFcb));
920 pNPFcb->Size = sizeof( AFSNonPagedFcb);
921 pNPFcb->Type = AFS_NON_PAGED_FCB;
924 // OK, initialize the entry
927 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
929 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
931 ExInitializeResourceLite( &pNPFcb->Resource);
933 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
934 AFS_TRACE_LEVEL_VERBOSE,
935 "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
937 PsGetCurrentThread());
939 AFSAcquireExcl( &pNPFcb->Resource,
942 ExInitializeResourceLite( &pNPFcb->PagingResource);
944 ExInitializeResourceLite( &pNPFcb->CcbListLock);
946 pFcb->Header.Resource = &pNPFcb->Resource;
948 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
950 pFcb->NPFcb = pNPFcb;
953 // Save the root Fcb in the VolumeCB
956 VolumeCB->ObjectInformation.Fcb = pFcb;
958 VolumeCB->ObjectInformation.VolumeCB = VolumeCB;
960 VolumeCB->RootFcb = pFcb;
962 pFcb->ObjectInformation = &VolumeCB->ObjectInformation;
966 if( !NT_SUCCESS( ntStatus))
972 AFSRemoveRootFcb( pFcb);
981 // Function: AFSRemoveRootFcb
985 // This function performs root Fcb removal/deallocation
989 // A status is returned for the function
993 AFSRemoveRootFcb( IN AFSFcb *RootFcb)
996 AFSDirectoryCB *pCurrentDirEntry = NULL;
997 AFSVolumeCB *pVolumeCB = RootFcb->ObjectInformation->VolumeCB;
999 if( RootFcb->NPFcb != NULL)
1006 ExDeleteResourceLite( &RootFcb->NPFcb->Resource);
1008 ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
1010 ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock);
1013 // The non paged region
1016 AFSExFreePool( RootFcb->NPFcb);
1020 // And the Fcb itself
1023 AFSExFreePool( RootFcb);
1029 // Function: AFSRemoveFcb
1033 // This function performs Fcb removal/deallocation
1037 // A status is returned for the function
1041 AFSRemoveFcb( IN AFSFcb **ppFcb)
1046 pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)ppFcb, NULL, (PVOID)(*ppFcb));
1055 // Uninitialize the file lock if it is a file
1058 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1059 AFS_TRACE_LEVEL_VERBOSE,
1060 "AFSRemoveFcb Removing Fcb %08lX\n",
1063 if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
1066 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
1069 // The resource we allocated
1072 ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.ExtentsResource );
1074 ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.DirtyExtentsListLock);
1077 else if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1084 // Tear down the FM specific contexts
1087 FsRtlTeardownPerStreamContexts( &pFcb->Header);
1090 // Delete the resources
1093 ExDeleteResourceLite( &pFcb->NPFcb->Resource);
1095 ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
1097 ExDeleteResourceLite( &pFcb->NPFcb->CcbListLock);
1100 // The non paged region
1103 AFSExFreePool( pFcb->NPFcb);
1106 // And the Fcb itself, which includes the name
1109 AFSExFreePool( pFcb);
1115 AFSInitCcb( IN OUT AFSCcb **Ccb)
1118 NTSTATUS Status = STATUS_SUCCESS;
1119 AFSCcb *pCcb = NULL;
1125 // Allocate our context control block
1128 pCcb = (AFSCcb *)AFSExAllocatePoolWithTag( PagedPool,
1130 AFS_CCB_ALLOCATION_TAG);
1135 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1136 AFS_TRACE_LEVEL_ERROR,
1137 "AFSInitCcb Failed to allocate Ccb\n");
1139 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1142 RtlZeroMemory( pCcb,
1145 pCcb->Size = sizeof( AFSCcb);
1146 pCcb->Type = AFS_CCB;
1156 if( !NT_SUCCESS( Status))
1162 AFSExFreePool( pCcb);
1173 // Function: AFSRemoveCcb
1177 // This function performs Ccb removal/deallocation
1181 // A status is returned for the function
1185 AFSRemoveCcb( IN AFSFcb *Fcb,
1189 NTSTATUS ntStatus = STATUS_SUCCESS;
1192 BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST))
1195 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1198 if( Ccb->ListEntry.fLink == NULL)
1201 Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink;
1203 if( Fcb->CcbListTail != NULL)
1205 Fcb->CcbListTail->ListEntry.fLink = NULL;
1210 ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink;
1213 if( Ccb->ListEntry.bLink == NULL)
1216 Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink;
1218 if( Fcb->CcbListHead != NULL)
1220 Fcb->CcbListHead->ListEntry.bLink = NULL;
1225 ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink;
1228 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
1231 if( Ccb->MaskName.Buffer != NULL)
1234 AFSExFreePool( Ccb->MaskName.Buffer);
1237 if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
1240 AFSExFreePool( Ccb->FullFileName.Buffer);
1244 // If we have a name array then delete it
1247 if( Ccb->NameArray != NULL)
1250 AFSFreeNameArray( Ccb->NameArray);
1252 Ccb->NameArray = NULL;
1255 if( Ccb->DirectorySnapshot != NULL)
1258 AFSExFreePool( Ccb->DirectorySnapshot);
1260 Ccb->DirectorySnapshot = NULL;
1263 if( Ccb->NotifyMask.Buffer != NULL)
1266 AFSExFreePool( Ccb->NotifyMask.Buffer);
1273 AFSExFreePool( Ccb);
1279 AFSInsertCcb( IN AFSFcb *Fcb,
1283 NTSTATUS ntStatus = STATUS_SUCCESS;
1285 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1288 if( Fcb->CcbListHead == NULL)
1290 Fcb->CcbListHead = Ccb;
1294 Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb;
1296 Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail;
1299 Fcb->CcbListTail = Ccb;
1301 SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST);
1303 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);