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 // Return Fcb->NPFcb->Resource held exclusive
54 AFSInitFcb( IN AFSDirectoryCB *DirEntry)
57 NTSTATUS ntStatus = STATUS_SUCCESS;
58 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
60 AFSNonPagedFcb *pNPFcb = NULL;
61 IO_STATUS_BLOCK stIoSb = {0,0};
62 USHORT usFcbLength = 0;
63 ULONGLONG ullIndex = 0;
64 AFSDirEnumEntry *pDirEnumCB = NULL;
65 AFSObjectInfoCB *pObjectInfo = NULL, *pParentObjectInfo = NULL;
66 AFSVolumeCB *pVolumeCB = NULL;
71 pObjectInfo = DirEntry->ObjectInformation;
73 pParentObjectInfo = pObjectInfo->ParentObjectInformation;
75 pVolumeCB = pObjectInfo->VolumeCB;
77 if ( pObjectInfo->Fcb != NULL)
80 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
83 try_return( ntStatus = STATUS_SUCCESS);
87 // Allocate the Fcb and the nonpaged portion of the Fcb.
90 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
91 AFS_TRACE_LEVEL_VERBOSE_2,
92 "AFSInitFcb Initializing fcb for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
93 &DirEntry->NameInformation.FileName,
94 pObjectInfo->FileId.Cell,
95 pObjectInfo->FileId.Volume,
96 pObjectInfo->FileId.Vnode,
97 pObjectInfo->FileId.Unique);
99 usFcbLength = sizeof( AFSFcb);
101 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
103 AFS_FCB_ALLOCATION_TAG);
108 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
109 AFS_TRACE_LEVEL_ERROR,
110 "AFSInitFcb Failed to allocate fcb\n");
112 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
118 pFcb->Header.NodeByteSize = usFcbLength;
120 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
121 sizeof( AFSNonPagedFcb),
122 AFS_FCB_NP_ALLOCATION_TAG);
127 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
128 AFS_TRACE_LEVEL_ERROR,
129 "AFSInitFcb Failed to allocate non-paged fcb\n");
131 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
134 RtlZeroMemory( pNPFcb,
135 sizeof( AFSNonPagedFcb));
137 pNPFcb->Size = sizeof( AFSNonPagedFcb);
139 pNPFcb->Type = AFS_NON_PAGED_FCB;
142 // Initialize the advanced header
145 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
147 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
150 // OK, initialize the entry
153 ExInitializeResourceLite( &pNPFcb->Resource);
155 ExInitializeResourceLite( &pNPFcb->PagingResource);
157 ExInitializeResourceLite( &pNPFcb->CcbListLock);
159 pFcb->Header.Resource = &pNPFcb->Resource;
161 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
164 // Grab the Fcb for processing
167 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
168 AFS_TRACE_LEVEL_VERBOSE,
169 "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
171 PsGetCurrentThread());
173 AFSAcquireExcl( &pNPFcb->Resource,
176 pFcb->NPFcb = pNPFcb;
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;
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,
205 // Initialize the header file sizes to our dir entry information
208 pFcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
209 pFcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
210 pFcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
213 // Initialize the Extents resources and so forth. The
214 // quiescent state is that no one has the extents for
215 // IO (do the extents are not busy) and there is no
216 // extents request outstanding (and hence the "last
217 // one" is complete).
219 ExInitializeResourceLite( &pNPFcb->Specific.File.ExtentsResource );
221 KeInitializeEvent( &pNPFcb->Specific.File.ExtentsRequestComplete,
225 for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
227 InitializeListHead(&pFcb->Specific.File.ExtentsLists[i]);
230 pNPFcb->Specific.File.DirtyListHead = NULL;
231 pNPFcb->Specific.File.DirtyListTail = NULL;
233 ExInitializeResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
235 KeInitializeEvent( &pNPFcb->Specific.File.FlushEvent,
236 SynchronizationEvent,
239 KeInitializeEvent( &pNPFcb->Specific.File.QueuedFlushEvent,
243 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
246 pFcb->Header.NodeTypeCode = AFS_SPECIAL_SHARE_FCB;
248 else if( pObjectInfo->FileType == AFS_FILE_TYPE_PIOCTL)
251 pFcb->Header.NodeTypeCode = AFS_IOCTL_FCB;
253 else if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
256 pFcb->Header.NodeTypeCode = AFS_SYMBOLIC_LINK_FCB;
258 else if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
261 pFcb->Header.NodeTypeCode = AFS_MOUNT_POINT_FCB;
263 else if( pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
265 pFcb->Header.NodeTypeCode = AFS_DFS_LINK_FCB;
269 pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
272 pFcb->ObjectInformation = pObjectInfo;
274 AFSAcquireShared( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
277 // Swap the allocated FCB into the ObjectInformation structure if it
278 // does not already have one.
281 if ( InterlockedCompareExchangePointer( (PVOID *)&pObjectInfo->Fcb, pFcb, NULL) != NULL)
284 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
285 AFS_TRACE_LEVEL_WARNING,
286 "AFSInitFcb Raced Fcb %08lX pFcb %08lX Name %wZ\n",
289 &DirEntry->NameInformation.FileName);
291 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
292 AFS_TRACE_LEVEL_VERBOSE,
293 "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
294 &pObjectInfo->Fcb->NPFcb->Resource,
295 PsGetCurrentThread());
297 AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
299 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
302 try_return( ntStatus = STATUS_REPARSE);
305 AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
307 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
308 AFS_TRACE_LEVEL_VERBOSE,
309 "AFSInitFcb Initialized Fcb %08lX Name %wZ\n",
311 &DirEntry->NameInformation.FileName);
315 if( ntStatus != STATUS_SUCCESS)
318 if ( !NT_SUCCESS( ntStatus))
321 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
322 AFS_TRACE_LEVEL_ERROR,
323 "AFSInitFcb Failed to initialize fcb Status %08lX\n",
333 AFSReleaseResource( &pNPFcb->Resource);
335 FsRtlTeardownPerStreamContexts( &pFcb->Header);
337 if ( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
340 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
342 ExDeleteResourceLite( &pNPFcb->Specific.File.ExtentsResource);
344 ExDeleteResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
347 ExDeleteResourceLite( &pNPFcb->PagingResource);
349 ExDeleteResourceLite( &pNPFcb->CcbListLock);
351 ExDeleteResourceLite( &pNPFcb->Resource);
353 AFSExFreePoolWithTag( pNPFcb, AFS_FCB_NP_ALLOCATION_TAG);
356 AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
365 AFSInitVolume( IN GUID *AuthGroup,
366 IN AFSFileID *RootFid,
367 OUT AFSVolumeCB **VolumeCB)
370 NTSTATUS ntStatus = STATUS_SUCCESS;
371 IO_STATUS_BLOCK stIoStatus = {0,0};
372 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
373 AFSNonPagedVolumeCB *pNonPagedVcb = NULL;
374 AFSVolumeCB *pVolumeCB = NULL;
375 AFSNonPagedObjectInfoCB *pNonPagedObject = NULL;
376 ULONGLONG ullIndex = 0;
377 BOOLEAN bReleaseLocks = FALSE;
378 AFSVolumeInfoCB stVolumeInformation;
379 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
386 // Before grabbing any locks ask the service for the volume information
387 // This may be a waste but we need to get this information prior to
388 // taking any volume tree locks. Don't do this for any 'reserved' cell entries
391 if( RootFid->Cell != 0)
394 RtlZeroMemory( &stVolumeInformation,
395 sizeof( AFSVolumeInfoCB));
397 ntStatus = AFSRetrieveVolumeInformation( AuthGroup,
399 &stVolumeInformation);
401 if( !NT_SUCCESS( ntStatus))
404 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
405 AFS_TRACE_LEVEL_ERROR,
406 "AFSInitVolume AFSRetrieveVolumeInformation(RootFid) failure %08lX\n",
409 try_return( ntStatus);
413 // Grab our tree locks and see if we raced with someone else
416 AFSAcquireExcl( pDeviceExt->Specific.RDR.VolumeTree.TreeLock,
419 AFSAcquireExcl( &pDeviceExt->Specific.RDR.VolumeListLock,
422 bReleaseLocks = TRUE;
424 ullIndex = AFSCreateHighIndex( RootFid);
426 ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
428 (AFSBTreeEntry **)&pVolumeCB);
430 if( NT_SUCCESS( ntStatus) &&
435 // So we don't lock with an invalidation call ...
438 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
440 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
441 AFS_TRACE_LEVEL_VERBOSE,
442 "AFSInitVolume Increment count on volume %08lX Cnt %d\n",
446 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
448 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
450 bReleaseLocks = FALSE;
452 AFSAcquireExcl( pVolumeCB->VolumeLock,
455 *VolumeCB = pVolumeCB;
457 try_return( ntStatus);
461 // Revert our status from the above call back to success.
464 ntStatus = STATUS_SUCCESS;
468 // For the global root we allocate out volume node and insert it
469 // into the volume tree ...
472 pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
473 sizeof( AFSVolumeCB),
474 AFS_VCB_ALLOCATION_TAG);
476 if( pVolumeCB == NULL)
479 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
480 AFS_TRACE_LEVEL_ERROR,
481 "AFSInitVolume Failed to allocate the root volume cb\n");
483 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
486 RtlZeroMemory( pVolumeCB,
487 sizeof( AFSVolumeCB));
490 // The non paged portion
493 pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
494 sizeof( AFSNonPagedVolumeCB),
495 AFS_VCB_NP_ALLOCATION_TAG);
497 if( pNonPagedVcb == NULL)
500 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
501 AFS_TRACE_LEVEL_ERROR,
502 "AFSInitVolume Failed to allocate the root non paged volume cb\n");
504 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
507 RtlZeroMemory( pNonPagedVcb,
508 sizeof( AFSNonPagedVolumeCB));
510 ExInitializeResourceLite( &pNonPagedVcb->VolumeLock);
512 ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
514 pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
515 sizeof( AFSNonPagedObjectInfoCB),
516 AFS_NP_OBJECT_INFO_TAG);
518 if( pNonPagedObject == NULL)
521 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
522 AFS_TRACE_LEVEL_ERROR,
523 "AFSInitVolume Failed to allocate the root non paged object cb\n");
525 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
528 RtlZeroMemory( pNonPagedObject,
529 sizeof( AFSNonPagedObjectInfoCB));
531 ExInitializeResourceLite( &pNonPagedObject->ObjectInfoLock);
533 ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
535 pVolumeCB->NonPagedVcb = pNonPagedVcb;
537 pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject;
539 pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock;
541 pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock;
543 pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
546 // Bias our reference by 1
549 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
550 AFS_TRACE_LEVEL_VERBOSE,
551 "AFSInitVolume Initializing count (2) on volume %08lX\n",
554 pVolumeCB->VolumeReferenceCount = 2;
556 AFSAcquireExcl( pVolumeCB->VolumeLock,
559 pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
560 sizeof( AFSDirectoryCB) + sizeof( WCHAR),
563 if( pVolumeCB->DirectoryCB == NULL)
566 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
569 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
570 sizeof( AFSNonPagedDirectoryCB),
571 AFS_DIR_ENTRY_NP_TAG);
573 if( pNonPagedDirEntry == NULL)
576 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
579 RtlZeroMemory( pVolumeCB->DirectoryCB,
580 sizeof( AFSDirectoryCB) + sizeof( WCHAR));
582 RtlZeroMemory( pNonPagedDirEntry,
583 sizeof( AFSNonPagedDirectoryCB));
585 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
587 pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry;
590 // Initialize the non-paged portion of the directory entry
593 KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime);
594 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime);
595 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime);
597 pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY;
599 SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME);
601 pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell;
602 pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume;
603 pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode;
604 pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique;
605 pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash;
607 pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
609 pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR);
611 pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length;
613 pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB));
615 RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer,
620 // Copy in the volume information retrieved above
623 RtlCopyMemory( &pVolumeCB->VolumeInformation,
624 &stVolumeInformation,
625 sizeof( AFSVolumeInfoCB));
631 pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
633 pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
636 // Insert the volume into our volume tree. Don't insert any reserved entries
639 if( RootFid->Cell != 0)
642 pVolumeCB->TreeEntry.HashIndex = ullIndex;
644 if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL)
647 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
649 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
654 if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
655 &pVolumeCB->TreeEntry)))
658 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
662 if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
665 pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB;
670 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB;
672 pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail;
675 pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB;
678 *VolumeCB = pVolumeCB;
682 if( !NT_SUCCESS( ntStatus))
685 if( pNonPagedVcb != NULL)
688 AFSReleaseResource( pVolumeCB->VolumeLock);
690 ExDeleteResourceLite( &pNonPagedVcb->VolumeLock);
692 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
694 AFSExFreePoolWithTag( pNonPagedVcb, AFS_VCB_NP_ALLOCATION_TAG);
697 if( pNonPagedObject != NULL)
700 ExDeleteResourceLite( &pNonPagedObject->ObjectInfoLock);
702 AFSExFreePoolWithTag( pNonPagedObject, AFS_NP_OBJECT_INFO_TAG);
705 if( pVolumeCB != NULL)
708 if( pVolumeCB->DirectoryCB != NULL)
711 AFSExFreePoolWithTag( pVolumeCB->DirectoryCB, AFS_DIR_ENTRY_TAG);
714 AFSExFreePoolWithTag( pVolumeCB, AFS_VCB_ALLOCATION_TAG);
717 if( pNonPagedDirEntry != NULL)
720 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
722 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
729 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
731 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
739 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
742 NTSTATUS ntStatus = STATUS_SUCCESS;
743 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
749 // Remove the volume from the tree and list
750 // Don't process the list information for reserved entries
753 if( VolumeCB->ObjectInformation.FileId.Cell != 0)
756 if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE))
759 AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
760 &VolumeCB->TreeEntry);
763 if( VolumeCB->ListEntry.fLink == NULL)
766 pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink;
768 if( pDeviceExt->Specific.RDR.VolumeListTail != NULL)
771 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL;
777 ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink;
780 if( VolumeCB->ListEntry.bLink == NULL)
783 pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink;
785 if( pDeviceExt->Specific.RDR.VolumeListHead != NULL)
788 pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL;
794 ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink;
799 // Remove any PIOctl objects we have
802 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL)
805 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
808 AFSAcquireExcl( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
811 AFSRemoveFcb( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
813 AFSReleaseResource( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
816 AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
818 ExDeleteResourceLite( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
820 AFSExFreePoolWithTag( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
822 AFSExFreePoolWithTag( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
825 if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
829 // Release the fid in the service
832 AFSReleaseFid( &VolumeCB->ObjectInformation.FileId);
836 // Free up the memory
839 if( VolumeCB->NonPagedVcb != NULL)
842 if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
844 AFSReleaseResource( VolumeCB->VolumeLock);
847 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock);
849 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
851 AFSExFreePoolWithTag( VolumeCB->NonPagedVcb, AFS_VCB_NP_ALLOCATION_TAG);
854 if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
857 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
859 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
861 AFSExFreePoolWithTag( VolumeCB->ObjectInformation.NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
864 if( VolumeCB->DirectoryCB != NULL)
867 if( VolumeCB->DirectoryCB->NonPaged != NULL)
870 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
872 AFSExFreePoolWithTag( VolumeCB->DirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
875 AFSExFreePoolWithTag( VolumeCB->DirectoryCB, AFS_DIR_ENTRY_TAG);
878 AFSExFreePoolWithTag( VolumeCB, AFS_VCB_ALLOCATION_TAG);
886 // Function: AFSInitRootFcb
890 // This function performs Root node Fcb initialization
894 // A status is returned for the function
898 AFSInitRootFcb( IN ULONGLONG ProcessID,
899 IN AFSVolumeCB *VolumeCB)
902 NTSTATUS ntStatus = STATUS_SUCCESS;
904 AFSNonPagedFcb *pNPFcb = NULL;
905 IO_STATUS_BLOCK stIoStatus = {0,0};
906 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
912 // Initialize the root fcb
915 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
917 AFS_FCB_ALLOCATION_TAG);
922 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
923 AFS_TRACE_LEVEL_ERROR,
924 "AFSInitRootFcb Failed to allocate the root fcb\n");
926 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
932 pFcb->Header.NodeByteSize = sizeof( AFSFcb);
933 pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;
935 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
936 sizeof( AFSNonPagedFcb),
937 AFS_FCB_NP_ALLOCATION_TAG);
942 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
943 AFS_TRACE_LEVEL_ERROR,
944 "AFSInitRootFcb Failed to allocate the non-paged fcb\n");
946 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
949 RtlZeroMemory( pNPFcb,
950 sizeof( AFSNonPagedFcb));
952 pNPFcb->Size = sizeof( AFSNonPagedFcb);
953 pNPFcb->Type = AFS_NON_PAGED_FCB;
956 // OK, initialize the entry
959 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
961 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
963 ExInitializeResourceLite( &pNPFcb->Resource);
965 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
966 AFS_TRACE_LEVEL_VERBOSE,
967 "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
969 PsGetCurrentThread());
971 AFSAcquireExcl( &pNPFcb->Resource,
974 ExInitializeResourceLite( &pNPFcb->PagingResource);
976 ExInitializeResourceLite( &pNPFcb->CcbListLock);
978 pFcb->Header.Resource = &pNPFcb->Resource;
980 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
982 pFcb->NPFcb = pNPFcb;
985 // Save the root Fcb in the VolumeCB
988 VolumeCB->ObjectInformation.Fcb = pFcb;
990 VolumeCB->ObjectInformation.VolumeCB = VolumeCB;
992 VolumeCB->RootFcb = pFcb;
994 pFcb->ObjectInformation = &VolumeCB->ObjectInformation;
998 if( !NT_SUCCESS( ntStatus))
1004 AFSRemoveRootFcb( pFcb);
1013 // Function: AFSRemoveRootFcb
1017 // This function performs root Fcb removal/deallocation
1021 // A status is returned for the function
1025 AFSRemoveRootFcb( IN AFSFcb *RootFcb)
1028 AFSDirectoryCB *pCurrentDirEntry = NULL;
1029 AFSVolumeCB *pVolumeCB = RootFcb->ObjectInformation->VolumeCB;
1031 if( RootFcb->NPFcb != NULL)
1038 ExDeleteResourceLite( &RootFcb->NPFcb->Resource);
1040 ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
1042 ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock);
1045 // The non paged region
1048 AFSExFreePoolWithTag( RootFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
1052 // And the Fcb itself
1055 AFSExFreePoolWithTag( RootFcb, AFS_FCB_ALLOCATION_TAG);
1061 // Function: AFSRemoveFcb
1065 // This function performs Fcb removal/deallocation
1069 // A status is returned for the function
1073 AFSRemoveFcb( IN AFSFcb **ppFcb)
1078 pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)ppFcb, NULL, (PVOID)(*ppFcb));
1087 // Uninitialize the file lock if it is a file
1090 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1091 AFS_TRACE_LEVEL_VERBOSE,
1092 "AFSRemoveFcb Removing Fcb %08lX\n",
1095 if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
1098 FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
1101 // The resource we allocated
1104 ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.ExtentsResource );
1106 ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.DirtyExtentsListLock);
1109 else if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1116 // Tear down the FM specific contexts
1119 FsRtlTeardownPerStreamContexts( &pFcb->Header);
1122 // Delete the resources
1125 ExDeleteResourceLite( &pFcb->NPFcb->Resource);
1127 ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
1129 ExDeleteResourceLite( &pFcb->NPFcb->CcbListLock);
1132 // The non paged region
1135 AFSExFreePoolWithTag( pFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
1138 // And the Fcb itself, which includes the name
1141 AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
1147 AFSInitCcb( IN OUT AFSCcb **Ccb)
1150 NTSTATUS Status = STATUS_SUCCESS;
1151 AFSCcb *pCcb = NULL;
1157 // Allocate our context control block
1160 pCcb = (AFSCcb *)AFSExAllocatePoolWithTag( PagedPool,
1162 AFS_CCB_ALLOCATION_TAG);
1167 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1168 AFS_TRACE_LEVEL_ERROR,
1169 "AFSInitCcb Failed to allocate Ccb\n");
1171 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1174 RtlZeroMemory( pCcb,
1177 pCcb->Size = sizeof( AFSCcb);
1179 pCcb->Type = AFS_CCB;
1181 pCcb->NPCcb = (AFSNonPagedCcb *)AFSExAllocatePoolWithTag( NonPagedPool,
1182 sizeof( AFSNonPagedCcb),
1183 AFS_CCB_NP_ALLOCATION_TAG);
1185 if( pCcb->NPCcb == NULL)
1188 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1189 AFS_TRACE_LEVEL_ERROR,
1190 "AFSInitCcb Failed to allocate NPCcb\n");
1192 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1195 ExInitializeResourceLite( &pCcb->NPCcb->CcbLock);
1205 if( !NT_SUCCESS( Status))
1211 if ( pCcb->NPCcb != NULL)
1214 AFSExFreePoolWithTag( pCcb->NPCcb, AFS_CCB_NP_ALLOCATION_TAG);
1217 AFSExFreePoolWithTag( pCcb, AFS_CCB_ALLOCATION_TAG);
1228 // Function: AFSRemoveCcb
1232 // This function performs Ccb removal/deallocation
1236 // A status is returned for the function
1240 AFSRemoveCcb( IN AFSFcb *Fcb,
1244 NTSTATUS ntStatus = STATUS_SUCCESS;
1246 AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
1250 BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST))
1253 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1256 if( Ccb->ListEntry.fLink == NULL)
1259 Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink;
1261 if( Fcb->CcbListTail != NULL)
1263 Fcb->CcbListTail->ListEntry.fLink = NULL;
1268 ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink;
1271 if( Ccb->ListEntry.bLink == NULL)
1274 Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink;
1276 if( Fcb->CcbListHead != NULL)
1278 Fcb->CcbListHead->ListEntry.bLink = NULL;
1283 ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink;
1286 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
1289 if( Ccb->MaskName.Buffer != NULL)
1292 AFSExFreePoolWithTag( Ccb->MaskName.Buffer, AFS_GENERIC_MEMORY_6_TAG);
1295 if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
1298 AFSExFreePoolWithTag( Ccb->FullFileName.Buffer, 0);
1302 // If we have a name array then delete it
1305 if( Ccb->NameArray != NULL)
1308 AFSFreeNameArray( Ccb->NameArray);
1310 Ccb->NameArray = NULL;
1313 if( Ccb->DirectorySnapshot != NULL)
1316 AFSExFreePoolWithTag( Ccb->DirectorySnapshot, AFS_DIR_SNAPSHOT_TAG);
1318 Ccb->DirectorySnapshot = NULL;
1321 if( Ccb->NotifyMask.Buffer != NULL)
1324 AFSExFreePoolWithTag( Ccb->NotifyMask.Buffer, AFS_GENERIC_MEMORY_7_TAG);
1327 AFSReleaseResource( &Ccb->NPCcb->CcbLock);
1333 ExDeleteResourceLite( &Ccb->NPCcb->CcbLock);
1335 AFSExFreePoolWithTag( Ccb->NPCcb, AFS_CCB_NP_ALLOCATION_TAG);
1337 AFSExFreePoolWithTag( Ccb, AFS_CCB_ALLOCATION_TAG);
1343 AFSInsertCcb( IN AFSFcb *Fcb,
1347 NTSTATUS ntStatus = STATUS_SUCCESS;
1349 AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1352 AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
1355 if( Fcb->CcbListHead == NULL)
1357 Fcb->CcbListHead = Ccb;
1361 Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb;
1363 Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail;
1366 Fcb->CcbListTail = Ccb;
1368 SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST);
1370 AFSReleaseResource( &Ccb->NPCcb->CcbLock);
1372 AFSReleaseResource( &Fcb->NPFcb->CcbListLock);