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);
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->Resource);
323 AFSExFreePool( pFcb);
329 AFSExFreePool( pNPFcb);
344 AFSInitVolume( IN GUID *AuthGroup,
345 IN AFSFileID *RootFid,
346 OUT AFSVolumeCB **VolumeCB)
349 NTSTATUS ntStatus = STATUS_SUCCESS;
350 IO_STATUS_BLOCK stIoStatus = {0,0};
351 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
352 AFSNonPagedVolumeCB *pNonPagedVcb = NULL;
353 AFSVolumeCB *pVolumeCB = NULL;
354 AFSNonPagedObjectInfoCB *pNonPagedObject = NULL;
355 ULONGLONG ullIndex = 0;
356 BOOLEAN bReleaseLocks = FALSE;
357 AFSVolumeInfoCB stVolumeInformation;
358 AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
364 // Before grabbing any locks ask the service for the volume information
365 // This may be a waste but we need to get this information prior to
366 // taking any volume tree locks. Don't do this for any 'reserved' cell entries
369 if( RootFid->Cell != 0)
372 RtlZeroMemory( &stVolumeInformation,
373 sizeof( AFSVolumeInfoCB));
375 ntStatus = AFSRetrieveVolumeInformation( AuthGroup,
377 &stVolumeInformation);
379 if( !NT_SUCCESS( ntStatus))
382 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
383 AFS_TRACE_LEVEL_ERROR,
384 "AFSInitVolume AFSRetrieveVolumeInformation(RootFid) failure %08lX\n",
387 try_return( ntStatus);
391 // Grab our tree locks and see if we raced with someone else
394 AFSAcquireExcl( pDeviceExt->Specific.RDR.VolumeTree.TreeLock,
397 AFSAcquireExcl( &pDeviceExt->Specific.RDR.VolumeListLock,
400 bReleaseLocks = TRUE;
402 ullIndex = AFSCreateHighIndex( RootFid);
404 ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
406 (AFSBTreeEntry **)&pVolumeCB);
408 if( NT_SUCCESS( ntStatus) &&
413 // So we don't lock with an invalidation call ...
416 InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
418 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
420 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
422 bReleaseLocks = FALSE;
424 AFSAcquireExcl( pVolumeCB->VolumeLock,
427 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
429 *VolumeCB = pVolumeCB;
431 try_return( ntStatus);
435 // Revert our status from the above call back to success.
438 ntStatus = STATUS_SUCCESS;
442 // For the global root we allocate out volume node and insert it
443 // into the volume tree ...
446 pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
447 sizeof( AFSVolumeCB),
448 AFS_VCB_ALLOCATION_TAG);
450 if( pVolumeCB == NULL)
453 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
454 AFS_TRACE_LEVEL_ERROR,
455 "AFSInitVolume Failed to allocate the root volume cb\n");
457 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
460 RtlZeroMemory( pVolumeCB,
461 sizeof( AFSVolumeCB));
464 // The non paged portion
467 pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
468 sizeof( AFSNonPagedVolumeCB),
469 AFS_VCB_ALLOCATION_TAG);
471 if( pNonPagedVcb == NULL)
474 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
475 AFS_TRACE_LEVEL_ERROR,
476 "AFSInitVolume Failed to allocate the root non paged volume cb\n");
478 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
481 RtlZeroMemory( pNonPagedVcb,
482 sizeof( AFSNonPagedVolumeCB));
484 ExInitializeResourceLite( &pNonPagedVcb->VolumeLock);
486 ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
488 pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
489 sizeof( AFSNonPagedObjectInfoCB),
490 AFS_VCB_ALLOCATION_TAG);
492 if( pNonPagedObject == NULL)
495 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
496 AFS_TRACE_LEVEL_ERROR,
497 "AFSInitVolume Failed to allocate the root non paged object cb\n");
499 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
502 RtlZeroMemory( pNonPagedObject,
503 sizeof( AFSNonPagedObjectInfoCB));
505 ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
507 pVolumeCB->NonPagedVcb = pNonPagedVcb;
509 pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject;
511 pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock;
513 pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock;
515 pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
518 // Bias our reference by 1
521 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
522 AFS_TRACE_LEVEL_VERBOSE,
523 "AFSInitVolume Initializing count (1) on volume %08lX\n",
526 pVolumeCB->VolumeReferenceCount = 1;
528 AFSAcquireExcl( pVolumeCB->VolumeLock,
531 pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
532 sizeof( AFSDirectoryCB) + sizeof( WCHAR),
535 if( pVolumeCB->DirectoryCB == NULL)
538 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
541 pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
542 sizeof( AFSNonPagedDirectoryCB),
543 AFS_DIR_ENTRY_NP_TAG);
545 if( pNonPagedDirEntry == NULL)
548 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
551 RtlZeroMemory( pVolumeCB->DirectoryCB,
552 sizeof( AFSDirectoryCB) + sizeof( WCHAR));
554 RtlZeroMemory( pNonPagedDirEntry,
555 sizeof( AFSNonPagedDirectoryCB));
557 ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
559 pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry;
562 // Initialize the non-paged portion of the directory entry
565 KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime);
566 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime);
567 KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime);
569 pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY;
571 SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME);
573 pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell;
574 pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume;
575 pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode;
576 pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique;
577 pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash;
579 pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
581 pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR);
583 pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length;
585 pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB));
587 RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer,
592 // Copy in the volume information retrieved above
595 RtlCopyMemory( &pVolumeCB->VolumeInformation,
596 &stVolumeInformation,
597 sizeof( AFSVolumeInfoCB));
603 pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
605 pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
608 // Insert the volume into our volume tree. Don't insert any reserved entries
611 if( RootFid->Cell != 0)
614 pVolumeCB->TreeEntry.HashIndex = ullIndex;
616 if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL)
619 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
624 AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
625 &pVolumeCB->TreeEntry);
628 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
630 if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
633 pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB;
638 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB;
640 pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail;
643 pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB;
646 *VolumeCB = pVolumeCB;
650 if( !NT_SUCCESS( ntStatus))
653 if( pNonPagedVcb != NULL)
656 AFSReleaseResource( pVolumeCB->VolumeLock);
658 ExDeleteResourceLite( &pNonPagedVcb->VolumeLock);
660 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
662 AFSExFreePool( pNonPagedVcb);
665 if( pNonPagedObject != NULL)
668 ExDeleteResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
670 AFSExFreePool( pNonPagedObject);
673 if( pVolumeCB != NULL)
676 if( pVolumeCB->DirectoryCB != NULL)
679 AFSExFreePool( pVolumeCB->DirectoryCB);
682 AFSExFreePool( pVolumeCB);
685 if( pNonPagedDirEntry != NULL)
688 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
690 AFSExFreePool( pNonPagedDirEntry);
697 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
699 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
707 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
710 NTSTATUS ntStatus = STATUS_SUCCESS;
711 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
717 // Remove the volume from the tree and list
718 // Don't process the list information for reserved entries
721 if( VolumeCB->ObjectInformation.FileId.Cell != 0)
724 if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE))
727 AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
728 &VolumeCB->TreeEntry);
731 if( VolumeCB->ListEntry.fLink == NULL)
734 pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink;
736 if( pDeviceExt->Specific.RDR.VolumeListTail != NULL)
739 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL;
745 ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink;
748 if( VolumeCB->ListEntry.bLink == NULL)
751 pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink;
753 if( pDeviceExt->Specific.RDR.VolumeListHead != NULL)
756 pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL;
762 ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink;
767 // Remove any PIOctl objects we have
770 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL)
773 if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
776 AFSRemoveFcb( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
779 AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
781 AFSExFreePool( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB);
784 if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
788 // Release the fid in the service
791 AFSReleaseFid( &VolumeCB->ObjectInformation.FileId);
795 // Free up the memory
798 if( VolumeCB->NonPagedVcb != NULL)
801 if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
804 AFSReleaseResource( VolumeCB->VolumeLock);
807 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock);
809 ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
811 AFSExFreePool( VolumeCB->NonPagedVcb);
814 if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
817 ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
819 AFSExFreePool( VolumeCB->ObjectInformation.NonPagedInfo);
822 if( VolumeCB->DirectoryCB != NULL)
825 if( VolumeCB->DirectoryCB->NonPaged != NULL)
828 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
830 AFSExFreePool( VolumeCB->DirectoryCB->NonPaged);
833 AFSExFreePool( VolumeCB->DirectoryCB);
836 AFSExFreePool( VolumeCB);
844 // Function: AFSInitRootFcb
848 // This function performs Root node Fcb initialization
852 // A status is returned for the function
856 AFSInitRootFcb( IN ULONGLONG ProcessID,
857 IN AFSVolumeCB *VolumeCB)
860 NTSTATUS ntStatus = STATUS_SUCCESS;
862 AFSNonPagedFcb *pNPFcb = NULL;
863 IO_STATUS_BLOCK stIoStatus = {0,0};
864 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
870 // Initialize the root fcb
873 pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
875 AFS_FCB_ALLOCATION_TAG);
880 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
881 AFS_TRACE_LEVEL_ERROR,
882 "AFSInitRootFcb Failed to allocate the root fcb\n");
884 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
890 pFcb->Header.NodeByteSize = sizeof( AFSFcb);
891 pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;
893 pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
894 sizeof( AFSNonPagedFcb),
895 AFS_FCB_NP_ALLOCATION_TAG);
900 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
901 AFS_TRACE_LEVEL_ERROR,
902 "AFSInitRootFcb Failed to allocate the non-paged fcb\n");
904 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
907 RtlZeroMemory( pNPFcb,
908 sizeof( AFSNonPagedFcb));
910 pNPFcb->Size = sizeof( AFSNonPagedFcb);
911 pNPFcb->Type = AFS_NON_PAGED_FCB;
914 // OK, initialize the entry
917 ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
919 FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
921 ExInitializeResourceLite( &pNPFcb->Resource);
923 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
924 AFS_TRACE_LEVEL_VERBOSE,
925 "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
927 PsGetCurrentThread());
929 AFSAcquireExcl( &pNPFcb->Resource,
932 ExInitializeResourceLite( &pNPFcb->PagingResource);
934 pFcb->Header.Resource = &pNPFcb->Resource;
936 pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
938 pFcb->NPFcb = pNPFcb;
941 // Initialize enumeration information
944 KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
949 // Save the root Fcb in the VolumeCB
952 VolumeCB->ObjectInformation.Fcb = pFcb;
954 VolumeCB->ObjectInformation.VolumeCB = VolumeCB;
956 VolumeCB->RootFcb = pFcb;
958 pFcb->ObjectInformation = &VolumeCB->ObjectInformation;
962 if( !NT_SUCCESS( ntStatus))
968 AFSRemoveRootFcb( pFcb);
977 // Function: AFSRemoveRootFcb
981 // This function performs root Fcb removal/deallocation
985 // A status is returned for the function
989 AFSRemoveRootFcb( IN AFSFcb *RootFcb)
992 AFSDirectoryCB *pCurrentDirEntry = NULL;
993 AFSVolumeCB *pVolumeCB = RootFcb->ObjectInformation->VolumeCB;
995 if( RootFcb->NPFcb != NULL)
1002 ExDeleteResourceLite( &RootFcb->NPFcb->Resource);
1004 ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
1007 // The non paged region
1010 AFSExFreePool( RootFcb->NPFcb);
1014 // And the Fcb itself
1017 AFSExFreePool( RootFcb);
1023 // Function: AFSRemoveFcb
1027 // This function performs Fcb removal/deallocation
1031 // A status is returned for the function
1035 AFSRemoveFcb( IN AFSFcb *Fcb)
1039 // Uninitialize the file lock if it is a file
1042 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1043 AFS_TRACE_LEVEL_VERBOSE,
1044 "AFSRemoveFcb Removing Fcb %08lX\n",
1047 if( Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
1050 FsRtlUninitializeFileLock( &Fcb->Specific.File.FileLock);
1053 // The resource we allocated
1056 ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.ExtentsResource );
1058 ExDeleteResourceLite( &Fcb->NPFcb->Specific.File.DirtyExtentsListLock);
1061 else if( Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1068 // Tear down the FM specific contexts
1071 FsRtlTeardownPerStreamContexts( &Fcb->Header);
1074 // Delete the resources
1077 ExDeleteResourceLite( &Fcb->NPFcb->Resource);
1079 ExDeleteResourceLite( &Fcb->NPFcb->PagingResource);
1084 // The non paged region
1087 AFSExFreePool( Fcb->NPFcb);
1090 // And the Fcb itself, which includes the name
1093 AFSExFreePool( Fcb);
1099 AFSInitCcb( IN OUT AFSCcb **Ccb)
1102 NTSTATUS Status = STATUS_SUCCESS;
1103 AFSCcb *pCcb = NULL;
1109 // Allocate our context control block
1112 pCcb = (AFSCcb *)AFSExAllocatePoolWithTag( PagedPool,
1114 AFS_CCB_ALLOCATION_TAG);
1119 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1120 AFS_TRACE_LEVEL_ERROR,
1121 "AFSInitCcb Failed to allocate Ccb\n");
1123 try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1126 RtlZeroMemory( pCcb,
1129 pCcb->Size = sizeof( AFSCcb);
1130 pCcb->Type = AFS_CCB;
1140 if( !NT_SUCCESS( Status))
1146 AFSExFreePool( pCcb);
1157 // Function: AFSRemoveCcb
1161 // This function performs Ccb removal/deallocation
1165 // A status is returned for the function
1169 AFSRemoveCcb( IN AFSCcb *Ccb)
1172 NTSTATUS ntStatus = STATUS_SUCCESS;
1174 if( Ccb->MaskName.Buffer != NULL)
1177 AFSExFreePool( Ccb->MaskName.Buffer);
1180 if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
1183 AFSExFreePool( Ccb->FullFileName.Buffer);
1187 // If we have a name array then delete it
1190 if( Ccb->NameArray != NULL)
1193 AFSFreeNameArray( Ccb->NameArray);
1195 Ccb->NameArray = NULL;
1198 if( Ccb->DirectorySnapshot != NULL)
1201 AFSExFreePool( Ccb->DirectorySnapshot);
1203 Ccb->DirectorySnapshot = NULL;
1206 if( Ccb->NotifyMask.Buffer != NULL)
1209 AFSExFreePool( Ccb->NotifyMask.Buffer);
1216 AFSExFreePool( Ccb);