Windows: Replace ParentObjectInformation pointer
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFcbSupport.cpp
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3  * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
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
13  *   notice,
14  *   this list of conditions and the following disclaimer in the
15  *   documentation
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.
21  *
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.
33  */
34
35 //
36 // File: AFSFcbSupport.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 //
42 // Function: AFSInitFcb
43 //
44 // Description:
45 //
46 //      This function performs Fcb initialization
47 //
48 // Return:
49 //
50 //      Return Fcb->NPFcb->Resource held exclusive
51 //
52
53 NTSTATUS
54 AFSInitFcb( IN AFSDirectoryCB  *DirEntry)
55 {
56
57     NTSTATUS ntStatus = STATUS_SUCCESS;
58     AFSFcb *pFcb = NULL;
59     AFSNonPagedFcb *pNPFcb = NULL;
60     USHORT  usFcbLength = 0;
61     AFSObjectInfoCB *pObjectInfo = NULL;
62     AFSVolumeCB *pVolumeCB = NULL;
63
64     __Enter
65     {
66
67         pObjectInfo = DirEntry->ObjectInformation;
68
69         if ( pObjectInfo->Fcb != NULL)
70         {
71
72             AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
73                             TRUE);
74
75             try_return( ntStatus = STATUS_SUCCESS);
76         }
77
78         pVolumeCB = pObjectInfo->VolumeCB;
79
80         //
81         // Allocate the Fcb and the nonpaged portion of the Fcb.
82         //
83
84         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
85                       AFS_TRACE_LEVEL_VERBOSE_2,
86                       "AFSInitFcb Initializing fcb for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
87                       &DirEntry->NameInformation.FileName,
88                       pObjectInfo->FileId.Cell,
89                       pObjectInfo->FileId.Volume,
90                       pObjectInfo->FileId.Vnode,
91                       pObjectInfo->FileId.Unique);
92
93         usFcbLength = sizeof( AFSFcb);
94
95         pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
96                                                    usFcbLength,
97                                                    AFS_FCB_ALLOCATION_TAG);
98
99         if( pFcb == NULL)
100         {
101
102             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
103                           AFS_TRACE_LEVEL_ERROR,
104                           "AFSInitFcb Failed to allocate fcb\n");
105
106             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
107         }
108
109         RtlZeroMemory( pFcb,
110                        usFcbLength);
111
112         pFcb->Header.NodeByteSize = usFcbLength;
113
114         pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
115                                                              sizeof( AFSNonPagedFcb),
116                                                              AFS_FCB_NP_ALLOCATION_TAG);
117
118         if( pNPFcb == NULL)
119         {
120
121             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
122                           AFS_TRACE_LEVEL_ERROR,
123                           "AFSInitFcb Failed to allocate non-paged fcb\n");
124
125             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
126         }
127
128         RtlZeroMemory( pNPFcb,
129                        sizeof( AFSNonPagedFcb));
130
131         pNPFcb->Size = sizeof( AFSNonPagedFcb);
132
133         pNPFcb->Type = AFS_NON_PAGED_FCB;
134
135         //
136         // Initialize the advanced header
137         //
138
139         ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
140
141         FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
142
143         //
144         // OK, initialize the entry
145         //
146
147         ExInitializeResourceLite( &pNPFcb->Resource);
148
149         ExInitializeResourceLite( &pNPFcb->PagingResource);
150
151         ExInitializeResourceLite( &pNPFcb->SectionObjectResource);
152
153         ExInitializeResourceLite( &pNPFcb->CcbListLock);
154
155         pFcb->Header.Resource = &pNPFcb->Resource;
156
157         pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
158
159         //
160         // Grab the Fcb for processing
161         //
162
163         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
164                       AFS_TRACE_LEVEL_VERBOSE,
165                       "AFSInitFcb Acquiring Fcb lock %p EXCL %08lX\n",
166                       &pNPFcb->Resource,
167                       PsGetCurrentThread());
168
169         AFSAcquireExcl( &pNPFcb->Resource,
170                         TRUE);
171
172         pFcb->NPFcb = pNPFcb;
173
174         //
175         // Set type specific information
176         //
177
178         if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
179         {
180
181             //
182             // Reset the type to a directory type
183             //
184
185             pFcb->Header.NodeTypeCode = AFS_DIRECTORY_FCB;
186         }
187         else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
188         {
189
190             pFcb->Header.NodeTypeCode = AFS_FILE_FCB;
191
192             //
193             // Initialize the file specific information
194             //
195
196             FsRtlInitializeFileLock( &pFcb->Specific.File.FileLock,
197                                      NULL,
198                                      NULL);
199
200             //
201             // Initialize the header file sizes to our dir entry information
202             //
203
204             pFcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
205             pFcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
206             pFcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
207
208             //
209             // Initialize the Extents resources and so forth.  The
210             // quiescent state is that no one has the extents for
211             // IO (do the extents are not busy) and there is no
212             // extents request outstanding (and hence the "last
213             // one" is complete).
214             //
215             ExInitializeResourceLite( &pNPFcb->Specific.File.ExtentsResource );
216
217             KeInitializeEvent( &pNPFcb->Specific.File.ExtentsRequestComplete,
218                                NotificationEvent,
219                                TRUE );
220
221             for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
222             {
223                 InitializeListHead(&pFcb->Specific.File.ExtentsLists[i]);
224             }
225
226             pNPFcb->Specific.File.DirtyListHead = NULL;
227             pNPFcb->Specific.File.DirtyListTail = NULL;
228
229             ExInitializeResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
230
231             KeInitializeEvent( &pNPFcb->Specific.File.FlushEvent,
232                                SynchronizationEvent,
233                                TRUE);
234
235             KeInitializeEvent( &pNPFcb->Specific.File.QueuedFlushEvent,
236                                NotificationEvent,
237                                TRUE);
238         }
239         else if( pObjectInfo->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
240         {
241
242             pFcb->Header.NodeTypeCode = AFS_SPECIAL_SHARE_FCB;
243         }
244         else if( pObjectInfo->FileType == AFS_FILE_TYPE_PIOCTL)
245         {
246
247             pFcb->Header.NodeTypeCode = AFS_IOCTL_FCB;
248         }
249         else if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
250         {
251
252             pFcb->Header.NodeTypeCode = AFS_SYMBOLIC_LINK_FCB;
253         }
254         else if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
255         {
256
257             pFcb->Header.NodeTypeCode = AFS_MOUNT_POINT_FCB;
258         }
259         else if( pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
260         {
261             pFcb->Header.NodeTypeCode = AFS_DFS_LINK_FCB;
262         }
263         else
264         {
265             pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
266         }
267
268         pFcb->ObjectInformation = pObjectInfo;
269
270         AFSAcquireShared( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
271                           TRUE);
272         //
273         // Swap the allocated FCB into the ObjectInformation structure if it
274         // does not already have one.
275         //
276
277         if ( InterlockedCompareExchangePointer( (PVOID *)&pObjectInfo->Fcb, pFcb, NULL) != NULL)
278         {
279
280             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
281                           AFS_TRACE_LEVEL_WARNING,
282                           "AFSInitFcb Raced Fcb %p pFcb %p Name %wZ\n",
283                           pObjectInfo->Fcb,
284                           pFcb,
285                           &DirEntry->NameInformation.FileName);
286
287             AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
288                           AFS_TRACE_LEVEL_VERBOSE,
289                           "AFSInitFcb Acquiring Fcb lock %p EXCL %08lX\n",
290                           &pObjectInfo->Fcb->NPFcb->Resource,
291                           PsGetCurrentThread());
292
293             AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
294
295             AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->Resource,
296                             TRUE);
297
298             try_return( ntStatus = STATUS_REPARSE);
299         }
300
301         AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
302
303         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
304                       AFS_TRACE_LEVEL_VERBOSE,
305                       "AFSInitFcb Initialized Fcb %p Name %wZ\n",
306                       &pObjectInfo->Fcb,
307                       &DirEntry->NameInformation.FileName);
308
309 try_exit:
310
311         if( ntStatus != STATUS_SUCCESS)
312         {
313
314             if ( !NT_SUCCESS( ntStatus))
315             {
316
317                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
318                               AFS_TRACE_LEVEL_ERROR,
319                               "AFSInitFcb Failed to initialize fcb Status %08lX\n",
320                               ntStatus);
321             }
322
323             if( pFcb != NULL)
324             {
325
326                 if( pNPFcb != NULL)
327                 {
328
329                     AFSReleaseResource( &pNPFcb->Resource);
330
331                     FsRtlTeardownPerStreamContexts( &pFcb->Header);
332
333                     if ( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
334                     {
335
336                         FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
337
338                         ExDeleteResourceLite( &pNPFcb->Specific.File.ExtentsResource);
339
340                         ExDeleteResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);
341                     }
342
343                     ExDeleteResourceLite( &pNPFcb->SectionObjectResource);
344
345                     ExDeleteResourceLite( &pNPFcb->PagingResource);
346
347                     ExDeleteResourceLite( &pNPFcb->CcbListLock);
348
349                     ExDeleteResourceLite( &pNPFcb->Resource);
350
351                     AFSExFreePoolWithTag( pNPFcb, AFS_FCB_NP_ALLOCATION_TAG);
352                 }
353
354                 AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
355             }
356         }
357     }
358
359     return ntStatus;
360 }
361
362 NTSTATUS
363 AFSInitVolume( IN GUID *AuthGroup,
364                IN AFSFileID *RootFid,
365                OUT AFSVolumeCB **VolumeCB)
366 {
367
368     NTSTATUS ntStatus = STATUS_SUCCESS;
369     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
370     AFSNonPagedVolumeCB *pNonPagedVcb = NULL;
371     AFSVolumeCB *pVolumeCB = NULL;
372     AFSNonPagedObjectInfoCB *pNonPagedObject = NULL;
373     ULONGLONG ullIndex = 0;
374     BOOLEAN bReleaseLocks = FALSE;
375     AFSVolumeInfoCB stVolumeInformation = {0};
376     AFSNonPagedDirectoryCB *pNonPagedDirEntry = NULL;
377     LONG lCount;
378
379     __Enter
380     {
381
382         //
383         // Before grabbing any locks ask the service for the volume information
384         // This may be a waste but we need to get this information prior to
385         // taking any volume tree locks. Don't do this for any 'reserved' cell entries
386         //
387
388         if( RootFid->Cell != 0)
389         {
390
391             RtlZeroMemory( &stVolumeInformation,
392                            sizeof( AFSVolumeInfoCB));
393
394             ntStatus = AFSRetrieveVolumeInformation( AuthGroup,
395                                                      RootFid,
396                                                      &stVolumeInformation);
397
398             if( !NT_SUCCESS( ntStatus))
399             {
400
401                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
402                               AFS_TRACE_LEVEL_ERROR,
403                               "AFSInitVolume AFSRetrieveVolumeInformation(RootFid) failure %08lX\n",
404                               ntStatus);
405
406                 try_return( ntStatus);
407             }
408
409             //
410             // Grab our tree locks and see if we raced with someone else
411             //
412
413             AFSAcquireExcl( pDeviceExt->Specific.RDR.VolumeTree.TreeLock,
414                             TRUE);
415
416             AFSAcquireExcl( &pDeviceExt->Specific.RDR.VolumeListLock,
417                             TRUE);
418
419             bReleaseLocks = TRUE;
420
421             ullIndex = AFSCreateHighIndex( RootFid);
422
423             ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
424                                            ullIndex,
425                                            (AFSBTreeEntry **)&pVolumeCB);
426
427             if( NT_SUCCESS( ntStatus) &&
428                 pVolumeCB != NULL)
429             {
430
431                 //
432                 // So we don't lock with an invalidation call ...
433                 //
434
435                 lCount = InterlockedIncrement( &pVolumeCB->VolumeReferenceCount);
436
437                 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
438                               AFS_TRACE_LEVEL_VERBOSE,
439                               "AFSInitVolume Increment count on volume %p Cnt %d\n",
440                               pVolumeCB,
441                               lCount);
442
443                 AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
444
445                 AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
446
447                 bReleaseLocks = FALSE;
448
449                 AFSAcquireExcl( pVolumeCB->VolumeLock,
450                                 TRUE);
451
452                 *VolumeCB = pVolumeCB;
453
454                 try_return( ntStatus);
455             }
456
457             //
458             // Revert our status from the above call back to success.
459             //
460
461             ntStatus = STATUS_SUCCESS;
462         }
463
464         //
465         // For the global root we allocate out volume node and insert it
466         // into the volume tree ...
467         //
468
469         pVolumeCB = (AFSVolumeCB *)AFSExAllocatePoolWithTag( PagedPool,
470                                                              sizeof( AFSVolumeCB),
471                                                              AFS_VCB_ALLOCATION_TAG);
472
473         if( pVolumeCB == NULL)
474         {
475
476             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
477                           AFS_TRACE_LEVEL_ERROR,
478                           "AFSInitVolume Failed to allocate the root volume cb\n");
479
480             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
481         }
482
483         RtlZeroMemory( pVolumeCB,
484                        sizeof( AFSVolumeCB));
485
486         //
487         // The non paged portion
488         //
489
490         pNonPagedVcb = (AFSNonPagedVolumeCB *)AFSExAllocatePoolWithTag( NonPagedPool,
491                                                                         sizeof( AFSNonPagedVolumeCB),
492                                                                         AFS_VCB_NP_ALLOCATION_TAG);
493
494         if( pNonPagedVcb == NULL)
495         {
496
497             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
498                           AFS_TRACE_LEVEL_ERROR,
499                           "AFSInitVolume Failed to allocate the root non paged volume cb\n");
500
501             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
502         }
503
504         RtlZeroMemory( pNonPagedVcb,
505                        sizeof( AFSNonPagedVolumeCB));
506
507         ExInitializeResourceLite( &pNonPagedVcb->VolumeLock);
508
509         ExInitializeResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
510
511         pNonPagedObject = (AFSNonPagedObjectInfoCB *)AFSExAllocatePoolWithTag( NonPagedPool,
512                                                                                sizeof( AFSNonPagedObjectInfoCB),
513                                                                                AFS_NP_OBJECT_INFO_TAG);
514
515         if( pNonPagedObject == NULL)
516         {
517
518             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
519                           AFS_TRACE_LEVEL_ERROR,
520                           "AFSInitVolume Failed to allocate the root non paged object cb\n");
521
522             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
523         }
524
525         RtlZeroMemory( pNonPagedObject,
526                        sizeof( AFSNonPagedObjectInfoCB));
527
528         ExInitializeResourceLite( &pNonPagedObject->ObjectInfoLock);
529
530         ExInitializeResourceLite( &pNonPagedObject->DirectoryNodeHdrLock);
531
532         pVolumeCB->NonPagedVcb = pNonPagedVcb;
533
534         pVolumeCB->ObjectInformation.NonPagedInfo = pNonPagedObject;
535
536         pVolumeCB->VolumeLock = &pNonPagedVcb->VolumeLock;
537
538         pVolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock = &pNonPagedObject->DirectoryNodeHdrLock;
539
540         pVolumeCB->ObjectInfoTree.TreeLock = &pNonPagedVcb->ObjectInfoTreeLock;
541
542         //
543         // Bias our reference by 1
544         //
545
546         AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
547                       AFS_TRACE_LEVEL_VERBOSE,
548                       "AFSInitVolume Initializing count (2) on volume %p\n",
549                       pVolumeCB);
550
551         pVolumeCB->VolumeReferenceCount = 2;
552
553         AFSAcquireExcl( pVolumeCB->VolumeLock,
554                         TRUE);
555
556         pVolumeCB->DirectoryCB = (AFSDirectoryCB *)AFSExAllocatePoolWithTag( PagedPool,
557                                                                              sizeof( AFSDirectoryCB) + sizeof( WCHAR),
558                                                                              AFS_DIR_ENTRY_TAG);
559
560         if( pVolumeCB->DirectoryCB == NULL)
561         {
562
563             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
564         }
565
566         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
567                       AFS_TRACE_LEVEL_VERBOSE,
568                       "AFSInitVolume AFS_DIR_ENTRY_TAG allocated %p\n",
569                       pVolumeCB->DirectoryCB);
570
571         pNonPagedDirEntry = (AFSNonPagedDirectoryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
572                                                                                 sizeof( AFSNonPagedDirectoryCB),
573                                                                                 AFS_DIR_ENTRY_NP_TAG);
574
575         if( pNonPagedDirEntry == NULL)
576         {
577
578             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
579         }
580
581         RtlZeroMemory( pVolumeCB->DirectoryCB,
582                        sizeof( AFSDirectoryCB) + sizeof( WCHAR));
583
584         RtlZeroMemory( pNonPagedDirEntry,
585                        sizeof( AFSNonPagedDirectoryCB));
586
587         ExInitializeResourceLite( &pNonPagedDirEntry->Lock);
588
589         pVolumeCB->DirectoryCB->NonPaged = pNonPagedDirEntry;
590
591         //
592         // Initialize the non-paged portion of the directory entry
593         //
594
595         KeQuerySystemTime( &pVolumeCB->ObjectInformation.CreationTime);
596         KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastWriteTime);
597         KeQuerySystemTime( &pVolumeCB->ObjectInformation.LastAccessTime);
598
599         pVolumeCB->ObjectInformation.FileType = AFS_FILE_TYPE_DIRECTORY;
600
601         SetFlag( pVolumeCB->ObjectInformation.Flags, AFS_OBJECT_ROOT_VOLUME);
602
603         pVolumeCB->ObjectInformation.FileId.Cell = RootFid->Cell;
604         pVolumeCB->ObjectInformation.FileId.Volume = RootFid->Volume;
605         pVolumeCB->ObjectInformation.FileId.Vnode = RootFid->Vnode;
606         pVolumeCB->ObjectInformation.FileId.Unique = RootFid->Unique;
607         pVolumeCB->ObjectInformation.FileId.Hash = RootFid->Hash;
608
609         pVolumeCB->ObjectInformation.FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
610
611         pVolumeCB->DirectoryCB->NameInformation.FileName.Length = sizeof( WCHAR);
612
613         pVolumeCB->DirectoryCB->NameInformation.FileName.MaximumLength = pVolumeCB->DirectoryCB->NameInformation.FileName.Length;
614
615         pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer = (WCHAR *)((char *)pVolumeCB->DirectoryCB + sizeof( AFSDirectoryCB));
616
617         RtlCopyMemory( pVolumeCB->DirectoryCB->NameInformation.FileName.Buffer,
618                        L"\\",
619                        sizeof( WCHAR));
620
621         //
622         // Copy in the volume information retrieved above
623         //
624
625         RtlCopyMemory( &pVolumeCB->VolumeInformation,
626                        &stVolumeInformation,
627                        sizeof( AFSVolumeInfoCB));
628
629         //
630         // Setup pointers
631         //
632
633         pVolumeCB->DirectoryCB->ObjectInformation = &pVolumeCB->ObjectInformation;
634
635         pVolumeCB->DirectoryCB->ObjectInformation->VolumeCB = pVolumeCB;
636
637         //
638         // Insert the volume into our volume tree. Don't insert any reserved entries
639         //
640
641         if( RootFid->Cell != 0)
642         {
643
644             pVolumeCB->TreeEntry.HashIndex = ullIndex;
645
646             if( pDeviceExt->Specific.RDR.VolumeTree.TreeHead == NULL)
647             {
648
649                 pDeviceExt->Specific.RDR.VolumeTree.TreeHead = &pVolumeCB->TreeEntry;
650
651                 SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
652             }
653             else
654             {
655
656                 if ( NT_SUCCESS( AFSInsertHashEntry( pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
657                                                      &pVolumeCB->TreeEntry)))
658                 {
659
660                     SetFlag( pVolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE);
661                 }
662             }
663
664             if( pDeviceExt->Specific.RDR.VolumeListHead == NULL)
665             {
666
667                 pDeviceExt->Specific.RDR.VolumeListHead = pVolumeCB;
668             }
669             else
670             {
671
672                 pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = (void *)pVolumeCB;
673
674                 pVolumeCB->ListEntry.bLink = pDeviceExt->Specific.RDR.VolumeListTail;
675             }
676
677             pDeviceExt->Specific.RDR.VolumeListTail = pVolumeCB;
678         }
679
680         *VolumeCB = pVolumeCB;
681
682 try_exit:
683
684         if( !NT_SUCCESS( ntStatus))
685         {
686
687             if( pNonPagedVcb != NULL)
688             {
689
690                 AFSReleaseResource( pVolumeCB->VolumeLock);
691
692                 ExDeleteResourceLite( &pNonPagedVcb->VolumeLock);
693
694                 ExDeleteResourceLite( &pNonPagedVcb->ObjectInfoTreeLock);
695
696                 AFSExFreePoolWithTag( pNonPagedVcb, AFS_VCB_NP_ALLOCATION_TAG);
697             }
698
699             if( pNonPagedObject != NULL)
700             {
701
702                 ExDeleteResourceLite( &pNonPagedObject->ObjectInfoLock);
703
704                 AFSExFreePoolWithTag( pNonPagedObject, AFS_NP_OBJECT_INFO_TAG);
705             }
706
707             if( pVolumeCB != NULL)
708             {
709
710                 if( pVolumeCB->DirectoryCB != NULL)
711                 {
712
713                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
714                                   AFS_TRACE_LEVEL_VERBOSE,
715                                   "AFSInitVolume AFS_DIR_ENTRY_TAG deallocating %p\n",
716                                   pVolumeCB->DirectoryCB);
717
718                     AFSExFreePoolWithTag( pVolumeCB->DirectoryCB, AFS_DIR_ENTRY_TAG);
719                 }
720
721                 AFSExFreePoolWithTag( pVolumeCB, AFS_VCB_ALLOCATION_TAG);
722             }
723
724             if( pNonPagedDirEntry != NULL)
725             {
726
727                 ExDeleteResourceLite( &pNonPagedDirEntry->Lock);
728
729                 AFSExFreePoolWithTag( pNonPagedDirEntry, AFS_DIR_ENTRY_NP_TAG);
730             }
731         }
732
733         if( bReleaseLocks)
734         {
735
736             AFSReleaseResource( pDeviceExt->Specific.RDR.VolumeTree.TreeLock);
737
738             AFSReleaseResource( &pDeviceExt->Specific.RDR.VolumeListLock);
739         }
740     }
741
742     return ntStatus;
743 }
744
745 NTSTATUS
746 AFSRemoveVolume( IN AFSVolumeCB *VolumeCB)
747 {
748
749     NTSTATUS ntStatus = STATUS_SUCCESS;
750     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
751
752     __Enter
753     {
754
755         //
756         // Remove the volume from the tree and list
757         // Don't process the list information for reserved entries
758         //
759
760         if( VolumeCB->ObjectInformation.FileId.Cell != 0)
761         {
762
763             if( BooleanFlagOn( VolumeCB->Flags, AFS_VOLUME_INSERTED_HASH_TREE))
764             {
765
766                 AFSRemoveHashEntry( &pDeviceExt->Specific.RDR.VolumeTree.TreeHead,
767                                     &VolumeCB->TreeEntry);
768             }
769
770             if( VolumeCB->ListEntry.fLink == NULL)
771             {
772
773                 pDeviceExt->Specific.RDR.VolumeListTail = (AFSVolumeCB *)VolumeCB->ListEntry.bLink;
774
775                 if( pDeviceExt->Specific.RDR.VolumeListTail != NULL)
776                 {
777
778                     pDeviceExt->Specific.RDR.VolumeListTail->ListEntry.fLink = NULL;
779                 }
780             }
781             else
782             {
783
784                 ((AFSVolumeCB *)(VolumeCB->ListEntry.fLink))->ListEntry.bLink = VolumeCB->ListEntry.bLink;
785             }
786
787             if( VolumeCB->ListEntry.bLink == NULL)
788             {
789
790                 pDeviceExt->Specific.RDR.VolumeListHead = (AFSVolumeCB *)VolumeCB->ListEntry.fLink;
791
792                 if( pDeviceExt->Specific.RDR.VolumeListHead != NULL)
793                 {
794
795                     pDeviceExt->Specific.RDR.VolumeListHead->ListEntry.bLink = NULL;
796                 }
797             }
798             else
799             {
800
801                 ((AFSVolumeCB *)(VolumeCB->ListEntry.bLink))->ListEntry.fLink = VolumeCB->ListEntry.fLink;
802             }
803         }
804
805         //
806         // Remove any PIOctl objects we have
807         //
808
809         if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB != NULL)
810         {
811
812             if( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb != NULL)
813             {
814
815                 AFSAcquireExcl( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
816                                 TRUE);
817
818                 AFSRemoveFcb( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
819
820                 AFSReleaseResource( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
821             }
822
823             AFSDeleteObjectInfo( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->ObjectInformation);
824
825             ExDeleteResourceLite( &VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged->Lock);
826
827             AFSExFreePoolWithTag( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
828
829             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
830                           AFS_TRACE_LEVEL_VERBOSE,
831                           "AFSRemoveVolume (pioctl) AFS_DIR_ENTRY_TAG deallocating %p\n",
832                           VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB);
833
834             AFSExFreePoolWithTag( VolumeCB->ObjectInformation.Specific.Directory.PIOCtlDirectoryCB, AFS_DIR_ENTRY_TAG);
835         }
836
837         if( BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE))
838         {
839
840             //
841             // Release the fid in the service
842             //
843
844             AFSReleaseFid( &VolumeCB->ObjectInformation.FileId);
845         }
846
847         //
848         // Free up the memory
849         //
850
851         if( VolumeCB->NonPagedVcb != NULL)
852         {
853
854             if( ExIsResourceAcquiredLite( VolumeCB->VolumeLock))
855             {
856                 AFSReleaseResource( VolumeCB->VolumeLock);
857             }
858
859             ExDeleteResourceLite( &VolumeCB->NonPagedVcb->VolumeLock);
860
861             ExDeleteResourceLite( &VolumeCB->NonPagedVcb->ObjectInfoTreeLock);
862
863             AFSExFreePoolWithTag( VolumeCB->NonPagedVcb, AFS_VCB_NP_ALLOCATION_TAG);
864         }
865
866         if( VolumeCB->ObjectInformation.NonPagedInfo != NULL)
867         {
868
869             ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->ObjectInfoLock);
870
871             ExDeleteResourceLite( &VolumeCB->ObjectInformation.NonPagedInfo->DirectoryNodeHdrLock);
872
873             AFSExFreePoolWithTag( VolumeCB->ObjectInformation.NonPagedInfo, AFS_NP_OBJECT_INFO_TAG);
874         }
875
876         if( VolumeCB->DirectoryCB != NULL)
877         {
878
879             if( VolumeCB->DirectoryCB->NonPaged != NULL)
880             {
881
882                 ExDeleteResourceLite( &VolumeCB->DirectoryCB->NonPaged->Lock);
883
884                 AFSExFreePoolWithTag( VolumeCB->DirectoryCB->NonPaged, AFS_DIR_ENTRY_NP_TAG);
885             }
886
887             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_ALLOCATION,
888                           AFS_TRACE_LEVEL_VERBOSE,
889                           "AFSRemoveVolume AFS_DIR_ENTRY_TAG deallocating %p\n",
890                           VolumeCB->DirectoryCB);
891
892             AFSExFreePoolWithTag( VolumeCB->DirectoryCB, AFS_DIR_ENTRY_TAG);
893         }
894
895         AFSExFreePoolWithTag( VolumeCB, AFS_VCB_ALLOCATION_TAG);
896     }
897
898     return ntStatus;
899 }
900
901
902 //
903 // Function: AFSInitRootFcb
904 //
905 // Description:
906 //
907 //      This function performs Root node Fcb initialization
908 //
909 // Return:
910 //
911 //      A status is returned for the function
912 //
913
914 NTSTATUS
915 AFSInitRootFcb( IN ULONGLONG ProcessID,
916                 IN AFSVolumeCB *VolumeCB)
917 {
918
919     UNREFERENCED_PARAMETER(ProcessID);
920     NTSTATUS ntStatus = STATUS_SUCCESS;
921     AFSFcb *pFcb = NULL;
922     AFSNonPagedFcb *pNPFcb = NULL;
923
924     __Enter
925     {
926
927         //
928         // Initialize the root fcb
929         //
930
931         pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
932                                                    sizeof( AFSFcb),
933                                                    AFS_FCB_ALLOCATION_TAG);
934
935         if( pFcb == NULL)
936         {
937
938             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
939                           AFS_TRACE_LEVEL_ERROR,
940                           "AFSInitRootFcb Failed to allocate the root fcb\n");
941
942             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
943         }
944
945         RtlZeroMemory( pFcb,
946                        sizeof( AFSFcb));
947
948         pFcb->Header.NodeByteSize = sizeof( AFSFcb);
949         pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;
950
951         pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
952                                                              sizeof( AFSNonPagedFcb),
953                                                              AFS_FCB_NP_ALLOCATION_TAG);
954
955         if( pNPFcb == NULL)
956         {
957
958             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
959                           AFS_TRACE_LEVEL_ERROR,
960                           "AFSInitRootFcb Failed to allocate the non-paged fcb\n");
961
962             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
963         }
964
965         RtlZeroMemory( pNPFcb,
966                        sizeof( AFSNonPagedFcb));
967
968         pNPFcb->Size = sizeof( AFSNonPagedFcb);
969         pNPFcb->Type = AFS_NON_PAGED_FCB;
970
971         //
972         // OK, initialize the entry
973         //
974
975         ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);
976
977         FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);
978
979         ExInitializeResourceLite( &pNPFcb->Resource);
980
981         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
982                       AFS_TRACE_LEVEL_VERBOSE,
983                       "AFSInitRootFcb Acquiring Fcb lock %p EXCL %08lX\n",
984                       &pNPFcb->Resource,
985                       PsGetCurrentThread());
986
987         AFSAcquireExcl( &pNPFcb->Resource,
988                         TRUE);
989
990         ExInitializeResourceLite( &pNPFcb->PagingResource);
991
992         ExInitializeResourceLite( &pNPFcb->CcbListLock);
993
994         pFcb->Header.Resource = &pNPFcb->Resource;
995
996         pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;
997
998         pFcb->NPFcb = pNPFcb;
999
1000         //
1001         // Save the root Fcb in the VolumeCB
1002         //
1003
1004         VolumeCB->ObjectInformation.Fcb = pFcb;
1005
1006         VolumeCB->ObjectInformation.VolumeCB = VolumeCB;
1007
1008         VolumeCB->RootFcb = pFcb;
1009
1010         pFcb->ObjectInformation = &VolumeCB->ObjectInformation;
1011
1012 try_exit:
1013
1014         if( !NT_SUCCESS( ntStatus))
1015         {
1016
1017             if( pFcb != NULL)
1018             {
1019
1020                 AFSRemoveRootFcb( pFcb);
1021             }
1022         }
1023     }
1024
1025     return ntStatus;
1026 }
1027
1028 //
1029 // Function: AFSRemoveRootFcb
1030 //
1031 // Description:
1032 //
1033 //      This function performs root Fcb removal/deallocation
1034 //
1035 // Return:
1036 //
1037 //      A status is returned for the function
1038 //
1039
1040 void
1041 AFSRemoveRootFcb( IN AFSFcb *RootFcb)
1042 {
1043
1044     if( RootFcb->NPFcb != NULL)
1045     {
1046
1047         //
1048         // Now the resource
1049         //
1050
1051         ExDeleteResourceLite( &RootFcb->NPFcb->Resource);
1052
1053         ExDeleteResourceLite( &RootFcb->NPFcb->PagingResource);
1054
1055         ExDeleteResourceLite( &RootFcb->NPFcb->CcbListLock);
1056
1057         //
1058         // The non paged region
1059         //
1060
1061         AFSExFreePoolWithTag( RootFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
1062     }
1063
1064     //
1065     // And the Fcb itself
1066     //
1067
1068     AFSExFreePoolWithTag( RootFcb, AFS_FCB_ALLOCATION_TAG);
1069
1070     return;
1071 }
1072
1073 //
1074 // Function: AFSRemoveFcb
1075 //
1076 // Description:
1077 //
1078 //      This function performs Fcb removal/deallocation
1079 //
1080 // Return:
1081 //
1082 //      A status is returned for the function
1083 //
1084
1085 void
1086 AFSRemoveFcb( IN AFSFcb **ppFcb)
1087 {
1088
1089     AFSFcb * pFcb;
1090
1091     pFcb = (AFSFcb *) InterlockedCompareExchangePointer( (PVOID *)ppFcb, NULL, (PVOID)(*ppFcb));
1092
1093     if ( pFcb == NULL)
1094     {
1095
1096         return;
1097     }
1098
1099     //
1100     // Uninitialize the file lock if it is a file
1101     //
1102
1103     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1104                   AFS_TRACE_LEVEL_VERBOSE,
1105                   "AFSRemoveFcb Removing Fcb %p\n",
1106                   pFcb);
1107
1108     if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
1109     {
1110
1111         FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
1112
1113         //
1114         // The resource we allocated
1115         //
1116
1117         ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.ExtentsResource );
1118
1119         ExDeleteResourceLite( &pFcb->NPFcb->Specific.File.DirtyExtentsListLock);
1120
1121     }
1122     else if( pFcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1123     {
1124
1125
1126     }
1127
1128     //
1129     // Tear down the FM specific contexts
1130     //
1131
1132     FsRtlTeardownPerStreamContexts( &pFcb->Header);
1133
1134     //
1135     // Delete the resources
1136     //
1137
1138     ExDeleteResourceLite( &pFcb->NPFcb->Resource);
1139
1140     ExDeleteResourceLite( &pFcb->NPFcb->PagingResource);
1141
1142     ExDeleteResourceLite( &pFcb->NPFcb->SectionObjectResource);
1143
1144     ExDeleteResourceLite( &pFcb->NPFcb->CcbListLock);
1145
1146     //
1147     // The non paged region
1148     //
1149
1150     AFSExFreePoolWithTag( pFcb->NPFcb, AFS_FCB_NP_ALLOCATION_TAG);
1151
1152     //
1153     // And the Fcb itself, which includes the name
1154     //
1155
1156     AFSExFreePoolWithTag( pFcb, AFS_FCB_ALLOCATION_TAG);
1157
1158     return;
1159 }
1160
1161 NTSTATUS
1162 AFSInitCcb( IN OUT AFSCcb **Ccb,
1163             IN     AFSDirectoryCB *DirectoryCB,
1164             IN     ACCESS_MASK     GrantedAccess,
1165             IN     ULONG           FileAccess)
1166 {
1167
1168     NTSTATUS Status = STATUS_SUCCESS;
1169     AFSCcb *pCcb = NULL;
1170     LONG lCount;
1171
1172     __Enter
1173     {
1174
1175         //
1176         // Allocate our context control block
1177         //
1178
1179         pCcb = (AFSCcb *)AFSExAllocatePoolWithTag( PagedPool,
1180                                                    sizeof( AFSCcb),
1181                                                    AFS_CCB_ALLOCATION_TAG);
1182
1183         if( pCcb == NULL)
1184         {
1185
1186             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1187                           AFS_TRACE_LEVEL_ERROR,
1188                           "AFSInitCcb Failed to allocate Ccb\n");
1189
1190             try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1191         }
1192
1193         RtlZeroMemory( pCcb,
1194                        sizeof( AFSCcb));
1195
1196         pCcb->Size = sizeof( AFSCcb);
1197
1198         pCcb->Type = AFS_CCB;
1199
1200         pCcb->NPCcb = (AFSNonPagedCcb *)AFSExAllocatePoolWithTag( NonPagedPool,
1201                                                      sizeof( AFSNonPagedCcb),
1202                                                      AFS_CCB_NP_ALLOCATION_TAG);
1203
1204         if( pCcb->NPCcb == NULL)
1205         {
1206
1207             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1208                           AFS_TRACE_LEVEL_ERROR,
1209                           "AFSInitCcb Failed to allocate NPCcb\n");
1210
1211             try_return( Status = STATUS_INSUFFICIENT_RESOURCES);
1212         }
1213
1214         ExInitializeResourceLite( &pCcb->NPCcb->CcbLock);
1215
1216         pCcb->DirectoryCB = DirectoryCB;
1217
1218         lCount = InterlockedIncrement( &pCcb->DirectoryCB->DirOpenReferenceCount);
1219
1220         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1221                       AFS_TRACE_LEVEL_VERBOSE,
1222                       "AFSInitCcb Increment count on %wZ DE %p Ccb %p Cnt %d\n",
1223                       &pCcb->DirectoryCB->NameInformation.FileName,
1224                       pCcb->DirectoryCB,
1225                       pCcb,
1226                       lCount);
1227
1228         pCcb->GrantedAccess = GrantedAccess;
1229
1230         pCcb->FileAccess = FileAccess;
1231
1232         //
1233         // Return the Ccb
1234         //
1235
1236         *Ccb = pCcb;
1237
1238 try_exit:
1239
1240         if( !NT_SUCCESS( Status))
1241         {
1242
1243             if( pCcb != NULL)
1244             {
1245
1246                 if ( pCcb->NPCcb != NULL)
1247                 {
1248
1249                     AFSExFreePoolWithTag( pCcb->NPCcb, AFS_CCB_NP_ALLOCATION_TAG);
1250                 }
1251
1252                 AFSExFreePoolWithTag( pCcb, AFS_CCB_ALLOCATION_TAG);
1253             }
1254
1255             *Ccb = NULL;
1256         }
1257     }
1258
1259     return Status;
1260 }
1261
1262 //
1263 // Function: AFSRemoveCcb
1264 //
1265 // Description:
1266 //
1267 //      This function performs Ccb removal/deallocation
1268 //
1269 // Return:
1270 //
1271 //      None
1272 //
1273
1274 void
1275 AFSRemoveCcb( IN AFSFcb *Fcb,
1276               IN AFSCcb *Ccb)
1277 {
1278
1279     LONG lCount;
1280
1281     AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
1282                     TRUE);
1283
1284     if( Fcb != NULL &&
1285         BooleanFlagOn( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST))
1286     {
1287
1288         AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1289                         TRUE);
1290
1291         if( Ccb->ListEntry.fLink == NULL)
1292         {
1293
1294             Fcb->CcbListTail = (AFSCcb *)Ccb->ListEntry.bLink;
1295
1296             if( Fcb->CcbListTail != NULL)
1297             {
1298                 Fcb->CcbListTail->ListEntry.fLink = NULL;
1299             }
1300         }
1301         else
1302         {
1303             ((AFSCcb *)(Ccb->ListEntry.fLink))->ListEntry.bLink = Ccb->ListEntry.bLink;
1304         }
1305
1306         if( Ccb->ListEntry.bLink == NULL)
1307         {
1308
1309             Fcb->CcbListHead = (AFSCcb *)Ccb->ListEntry.fLink;
1310
1311             if( Fcb->CcbListHead != NULL)
1312             {
1313                 Fcb->CcbListHead->ListEntry.bLink = NULL;
1314             }
1315         }
1316         else
1317         {
1318             ((AFSCcb *)(Ccb->ListEntry.bLink))->ListEntry.fLink = Ccb->ListEntry.fLink;
1319         }
1320
1321         AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
1322     }
1323
1324     if( Ccb->MaskName.Buffer != NULL)
1325     {
1326
1327         AFSExFreePoolWithTag( Ccb->MaskName.Buffer, AFS_GENERIC_MEMORY_6_TAG);
1328     }
1329
1330     if( BooleanFlagOn( Ccb->Flags, CCB_FLAG_FREE_FULL_PATHNAME))
1331     {
1332
1333         AFSExFreePoolWithTag( Ccb->FullFileName.Buffer, 0);
1334     }
1335
1336     //
1337     // If we have a name array then delete it
1338     //
1339
1340     if( Ccb->NameArray != NULL)
1341     {
1342
1343         AFSFreeNameArray( Ccb->NameArray);
1344
1345         Ccb->NameArray = NULL;
1346     }
1347
1348     if( Ccb->DirectorySnapshot != NULL)
1349     {
1350
1351         AFSExFreePoolWithTag( Ccb->DirectorySnapshot, AFS_DIR_SNAPSHOT_TAG);
1352
1353         Ccb->DirectorySnapshot = NULL;
1354     }
1355
1356     if( Ccb->NotifyMask.Buffer != NULL)
1357     {
1358
1359         AFSExFreePoolWithTag( Ccb->NotifyMask.Buffer, AFS_GENERIC_MEMORY_7_TAG);
1360     }
1361
1362     if ( Ccb->DirectoryCB != NULL)
1363     {
1364
1365         lCount = InterlockedDecrement( &Ccb->DirectoryCB->DirOpenReferenceCount);
1366
1367         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1368                       AFS_TRACE_LEVEL_VERBOSE,
1369                       "AFSRemoveCcb Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1370                       &Ccb->DirectoryCB->NameInformation.FileName,
1371                       Ccb->DirectoryCB,
1372                       Ccb,
1373                       lCount);
1374
1375         ASSERT( lCount >= 0);
1376     }
1377
1378     AFSReleaseResource( &Ccb->NPCcb->CcbLock);
1379
1380     //
1381     // Free up the Ccb
1382     //
1383
1384     ExDeleteResourceLite( &Ccb->NPCcb->CcbLock);
1385
1386     AFSExFreePoolWithTag( Ccb->NPCcb, AFS_CCB_NP_ALLOCATION_TAG);
1387
1388     AFSExFreePoolWithTag( Ccb, AFS_CCB_ALLOCATION_TAG);
1389 }
1390
1391 NTSTATUS
1392 AFSInsertCcb( IN AFSFcb *Fcb,
1393               IN AFSCcb *Ccb)
1394 {
1395
1396     NTSTATUS ntStatus = STATUS_SUCCESS;
1397
1398     AFSAcquireExcl( &Fcb->NPFcb->CcbListLock,
1399                     TRUE);
1400
1401     AFSAcquireExcl( &Ccb->NPCcb->CcbLock,
1402                     TRUE);
1403
1404     if( Fcb->CcbListHead == NULL)
1405     {
1406         Fcb->CcbListHead = Ccb;
1407     }
1408     else
1409     {
1410         Fcb->CcbListTail->ListEntry.fLink = (void *)Ccb;
1411
1412         Ccb->ListEntry.bLink = (void *)Fcb->CcbListTail;
1413     }
1414
1415     Fcb->CcbListTail = Ccb;
1416
1417     SetFlag( Ccb->Flags, CCB_FLAG_INSERTED_CCB_LIST);
1418
1419     AFSReleaseResource( &Ccb->NPCcb->CcbLock);
1420
1421     AFSReleaseResource( &Fcb->NPFcb->CcbListLock);
1422
1423     return ntStatus;
1424 }