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