Windows: AFSLocateNameEntry tracking DirectoryCB IN/OUT
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSCreate.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: AFSCreate.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 //
42 // Function: AFSCreate
43 //
44 // Description:
45 //
46 //      This function is the dispatch handler for the IRP_MJ_CREATE requests. It makes the determination to
47 //      which interface this request is destined.
48 //
49 // Return:
50 //
51 //      A status is returned for the function. The Irp completion processing is handled in the specific
52 //      interface handler.
53 //
54
55 NTSTATUS
56 AFSCreate( IN PDEVICE_OBJECT LibDeviceObject,
57            IN PIRP Irp)
58 {
59     UNREFERENCED_PARAMETER(LibDeviceObject);
60     NTSTATUS ntStatus = STATUS_SUCCESS;
61     IO_STACK_LOCATION  *pIrpSp;
62     FILE_OBJECT        *pFileObject = NULL;
63
64     __try
65     {
66
67         pIrpSp = IoGetCurrentIrpStackLocation( Irp);
68         pFileObject = pIrpSp->FileObject;
69
70         if( pFileObject == NULL ||
71             pFileObject->FileName.Buffer == NULL)
72         {
73
74             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
75                           AFS_TRACE_LEVEL_VERBOSE,
76                           "AFSCreate (%p) Processing control device open request\n",
77                           Irp);
78
79             ntStatus = AFSControlDeviceCreate( Irp);
80
81             try_return( ntStatus);
82         }
83
84         if( AFSRDRDeviceObject == NULL)
85         {
86
87             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
88                           AFS_TRACE_LEVEL_VERBOSE,
89                           "AFSCreate (%p) Invalid request to open before library is initialized\n",
90                           Irp);
91
92             try_return( ntStatus = STATUS_DEVICE_NOT_READY);
93         }
94
95         ntStatus = AFSCommonCreate( AFSRDRDeviceObject,
96                                     Irp);
97
98 try_exit:
99
100         NOTHING;
101     }
102     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
103     {
104
105         AFSDbgLogMsg( 0,
106                       0,
107                       "EXCEPTION - AFSCreate\n");
108
109         ntStatus = STATUS_ACCESS_DENIED;
110
111         AFSDumpTraceFilesFnc();
112     }
113
114     //
115     // Complete the request
116     //
117
118     AFSCompleteRequest( Irp,
119                           ntStatus);
120
121     return ntStatus;
122 }
123
124 NTSTATUS
125 AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
126                  IN PIRP Irp)
127 {
128
129     NTSTATUS            ntStatus = STATUS_SUCCESS;
130     UNICODE_STRING      uniFileName;
131     ULONG               ulCreateDisposition = 0;
132     ULONG               ulOptions = 0;
133     BOOLEAN             bNoIntermediateBuffering = FALSE;
134     FILE_OBJECT        *pFileObject = NULL;
135     IO_STACK_LOCATION  *pIrpSp;
136     AFSFcb             *pFcb = NULL;
137     AFSCcb             *pCcb = NULL;
138     AFSDeviceExt       *pDeviceExt = NULL;
139     BOOLEAN             bOpenTargetDirectory = FALSE, bReleaseVolume = FALSE;
140     PACCESS_MASK        pDesiredAccess = NULL;
141     UNICODE_STRING      uniComponentName, uniRootFileName, uniParsedFileName;
142     UNICODE_STRING      uniSubstitutedPathName;
143     UNICODE_STRING      uniRelativeName;
144     AFSNameArrayHdr    *pNameArray = NULL;
145     AFSVolumeCB        *pVolumeCB = NULL;
146     LONG                VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
147     AFSVolumeCB        *pNewVolumeCB = NULL;
148     LONG                NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
149     AFSDirectoryCB     *pParentDirectoryCB = NULL, *pDirectoryCB = NULL;
150     AFSDirectoryCB     *pNewParentDirectoryCB = NULL;
151     BOOLEAN             bReleaseParentDir = FALSE, bReleaseDir = FALSE;
152     ULONG               ulParseFlags = 0;
153     GUID                stAuthGroup = {0};
154     ULONG               ulNameProcessingFlags = 0;
155     BOOLEAN             bOpenedReparsePoint = FALSE;
156     LONG                lCount;
157
158     __Enter
159     {
160
161         pIrpSp = IoGetCurrentIrpStackLocation( Irp);
162         pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
163         ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
164         ulOptions = pIrpSp->Parameters.Create.Options;
165         bNoIntermediateBuffering = BooleanFlagOn( ulOptions, FILE_NO_INTERMEDIATE_BUFFERING);
166         bOpenTargetDirectory = BooleanFlagOn( pIrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
167         pFileObject = pIrpSp->FileObject;
168         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
169
170         uniFileName.Length = uniFileName.MaximumLength = 0;
171         uniFileName.Buffer = NULL;
172
173         uniRootFileName.Length = uniRootFileName.MaximumLength = 0;
174         uniRootFileName.Buffer = NULL;
175
176         uniParsedFileName.Length = uniParsedFileName.MaximumLength = 0;
177         uniParsedFileName.Buffer = NULL;
178
179         uniSubstitutedPathName.Buffer = NULL;
180         uniSubstitutedPathName.Length = 0;
181
182         uniRelativeName.Buffer = NULL;
183         uniRelativeName.Length = 0;
184
185         if( AFSGlobalRoot == NULL)
186         {
187             try_return( ntStatus = STATUS_DEVICE_NOT_READY);
188         }
189
190         RtlZeroMemory( &stAuthGroup,
191                        sizeof( GUID));
192
193         AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
194                                  (ULONGLONG)PsGetCurrentThreadId(),
195                                   &stAuthGroup);
196
197         //
198         // If we are in shutdown mode then fail the request
199         //
200
201         if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
202         {
203
204             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
205                           AFS_TRACE_LEVEL_WARNING,
206                           "AFSCommonCreate (%p) Open request after shutdown\n",
207                           Irp);
208
209             try_return( ntStatus = STATUS_TOO_LATE);
210         }
211
212         if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
213         {
214
215             ntStatus = AFSEnumerateGlobalRoot( &stAuthGroup);
216
217             if( !NT_SUCCESS( ntStatus))
218             {
219
220                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
221                               AFS_TRACE_LEVEL_ERROR,
222                               "AFSCommonCreate Failed to enumerate global root Status %08lX\n",
223                               ntStatus);
224
225                 try_return( ntStatus);
226             }
227         }
228
229         //
230         // Go and parse the name for processing.
231         // If ulParseFlags is returned with AFS_PARSE_FLAG_FREE_FILE_BUFFER set,
232         // then we are responsible for releasing the uniRootFileName.Buffer.
233         //
234
235         ntStatus = AFSParseName( Irp,
236                                  &stAuthGroup,
237                                  &uniFileName,
238                                  &uniParsedFileName,
239                                  &uniRootFileName,
240                                  &ulParseFlags,
241                                  &pVolumeCB,
242                                  &pParentDirectoryCB,
243                                  &pNameArray);
244
245         if( !NT_SUCCESS( ntStatus))
246         {
247
248             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
249                           uniFileName.Length > 0 ? AFS_TRACE_LEVEL_ERROR : AFS_TRACE_LEVEL_VERBOSE,
250                           "AFSCommonCreate (%p) Failed to parse name \"%wZ\" Status %08lX\n",
251                           Irp,
252                           &uniFileName,
253                           ntStatus);
254
255             try_return( ntStatus);
256         }
257
258         //
259         // Check for STATUS_REPARSE
260         //
261
262         if( ntStatus == STATUS_REPARSE)
263         {
264
265             //
266             // Update the information and return
267             //
268
269             Irp->IoStatus.Information = IO_REPARSE;
270
271             try_return( ntStatus);
272         }
273
274         if ( pParentDirectoryCB != NULL)
275         {
276
277             bReleaseParentDir = TRUE;
278         }
279
280         //
281         // If the returned volume cb is NULL then we are dealing with the \\Server\GlobalRoot
282         // name
283         //
284
285         if( pVolumeCB == NULL)
286         {
287
288             //
289             // Remove any leading or trailing slashes
290             //
291
292             if( uniFileName.Length >= sizeof( WCHAR) &&
293                 uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
294             {
295
296                 uniFileName.Length -= sizeof( WCHAR);
297             }
298
299             if( uniFileName.Length >= sizeof( WCHAR) &&
300                 uniFileName.Buffer[ 0] == L'\\')
301             {
302
303                 uniFileName.Buffer = &uniFileName.Buffer[ 1];
304
305                 uniFileName.Length -= sizeof( WCHAR);
306             }
307
308             //
309             // If there is a remaining portion returned for this request then
310             // check if it is for the PIOCtl interface
311             //
312
313             if( uniFileName.Length > 0)
314             {
315
316                 //
317                 // We don't accept any other opens off of the AFS Root
318                 //
319
320                 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
321
322                 //
323                 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
324                 //
325
326                 if( RtlCompareUnicodeString( &AFSPIOCtlName,
327                                              &uniFileName,
328                                              TRUE) == 0)
329                 {
330
331                     //
332                     // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
333                     // AFSGlobalRoot->DirectoryCB.
334                     //
335
336                     ntStatus = AFSOpenIOCtlFcb( Irp,
337                                                 &stAuthGroup,
338                                                 AFSGlobalRoot->DirectoryCB,
339                                                 &pFcb,
340                                                 &pCcb);
341
342                     if( !NT_SUCCESS( ntStatus))
343                     {
344
345                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
346                                       AFS_TRACE_LEVEL_ERROR,
347                                       "AFSCommonCreate Failed to open root IOCtl Fcb Status %08lX\n",
348                                       ntStatus);
349                     }
350                 }
351                 else if( pParentDirectoryCB != NULL)
352                 {
353
354                     if( pParentDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
355                     {
356
357                         ntStatus = AFSOpenSpecialShareFcb( Irp,
358                                                            &stAuthGroup,
359                                                            pParentDirectoryCB,
360                                                            &pFcb,
361                                                            &pCcb);
362
363                         if( !NT_SUCCESS( ntStatus))
364                         {
365
366                             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
367                                           AFS_TRACE_LEVEL_ERROR,
368                                           "AFSCommonCreate Failed to open special share Fcb Status %08lX\n",
369                                           ntStatus);
370                         }
371                     }
372                 }
373
374                 try_return( ntStatus);
375             }
376
377             ntStatus = AFSOpenAFSRoot( Irp,
378                                        &pFcb,
379                                        &pCcb);
380
381             if( !NT_SUCCESS( ntStatus))
382             {
383
384                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
385                               AFS_TRACE_LEVEL_ERROR,
386                               "AFSCommonCreate Failed to open root Status %08lX\n",
387                               ntStatus);
388             }
389
390             try_return( ntStatus);
391         }
392
393         //
394         // We have a reference on the root volume
395         //
396
397         VolumeReferenceReason = AFS_VOLUME_REFERENCE_PARSE_NAME;
398
399         bReleaseVolume = TRUE;
400
401         //
402         // Attempt to locate the node in the name tree if this is not a target
403         // open and the target is not the root
404         //
405
406         uniComponentName.Length = 0;
407         uniComponentName.Buffer = NULL;
408
409         if( uniFileName.Length > sizeof( WCHAR) ||
410             uniFileName.Buffer[ 0] != L'\\')
411         {
412
413             if( !AFSValidNameFormat( &uniFileName))
414             {
415
416                 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
417
418                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
419                               AFS_TRACE_LEVEL_VERBOSE,
420                               "AFSCommonCreate (%p) Invalid name %wZ Status %08lX\n",
421                               Irp,
422                               &uniFileName,
423                               ntStatus);
424
425                 try_return( ntStatus);
426             }
427
428             //
429             // Opening a reparse point directly?
430             //
431
432             ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
433
434             if( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
435             {
436                 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
437                                           AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
438                                           AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
439             }
440
441             uniSubstitutedPathName = uniRootFileName;
442
443             ntStatus = AFSLocateNameEntry( &stAuthGroup,
444                                            pFileObject,
445                                            &uniRootFileName,
446                                            &uniParsedFileName,
447                                            pNameArray,
448                                            ulNameProcessingFlags,
449                                            pVolumeCB,
450                                            pParentDirectoryCB,
451                                            &pNewVolumeCB,
452                                            &NewVolumeReferenceReason,
453                                            &pNewParentDirectoryCB,
454                                            &pDirectoryCB,
455                                            &uniComponentName);
456
457             //
458             // AFSLocateNameEntry returns pNewVolumeCB with a reference held
459             // even if pVolumeCB == pNewVolumeCB.  It is always safe to release
460             // the reference on pVolumeCB that was held prior to the call.
461             // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
462             // will be released second.
463             //
464
465             lCount = AFSVolumeDecrement( pVolumeCB,
466                                          VolumeReferenceReason);
467
468             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
469                           AFS_TRACE_LEVEL_VERBOSE,
470                           "AFSCommonCreate Decrement count on volume %p Reason %u Cnt %d\n",
471                           pVolumeCB,
472                           VolumeReferenceReason,
473                           lCount);
474
475             pVolumeCB = pNewVolumeCB;
476
477             pNewVolumeCB = NULL;
478
479             VolumeReferenceReason = NewVolumeReferenceReason;
480
481             NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
482
483             bReleaseVolume = (pVolumeCB != NULL);
484
485             //
486             // AFSLocateNameEntry does not alter the reference count of
487             // pParentDirectoryCB and it returns pNewParentDirectoryCB with
488             // a reference held.
489             //
490
491             if ( bReleaseParentDir)
492             {
493
494                 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
495
496                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
497                               AFS_TRACE_LEVEL_VERBOSE,
498                               "AFSCommonCreate DecrementX count on %wZ DE %p Ccb %p Cnt %d\n",
499                               &pParentDirectoryCB->NameInformation.FileName,
500                               pParentDirectoryCB,
501                               pCcb,
502                               lCount);
503             }
504
505             pParentDirectoryCB = pNewParentDirectoryCB;
506
507             pNewParentDirectoryCB = NULL;
508
509             bReleaseParentDir = (pParentDirectoryCB != NULL);
510
511             if ( pDirectoryCB)
512             {
513
514                 bReleaseDir = TRUE;
515             }
516
517             if( !NT_SUCCESS( ntStatus) &&
518                 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
519             {
520
521                 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
522                 {
523                     uniSubstitutedPathName.Buffer = NULL;
524                 }
525
526                 //
527                 // AFSLocateNameEntry released the Parent while walking the
528                 // branch
529                 //
530
531                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
532                               AFS_TRACE_LEVEL_VERBOSE,
533                               "AFSCommonCreate (%p) Failed to locate name entry for %wZ Status %08lX\n",
534                               Irp,
535                               &uniFileName,
536                               ntStatus);
537
538                 try_return( ntStatus);
539             }
540
541             //
542             // Check for STATUS_REPARSE
543             //
544
545             if( ntStatus == STATUS_REPARSE)
546             {
547
548                 uniSubstitutedPathName.Buffer = NULL;
549
550                 //
551                 // Update the information and return
552                 //
553
554                 Irp->IoStatus.Information = IO_REPARSE;
555
556                 try_return( ntStatus);
557             }
558
559             //
560             // If we re-allocated the name, then update our substitute name
561             //
562
563             if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
564             {
565
566                 uniSubstitutedPathName = uniRootFileName;
567             }
568             else
569             {
570
571                 uniSubstitutedPathName.Buffer = NULL;
572             }
573
574             //
575             // Check for a symlink access
576             //
577
578             if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
579                 pParentDirectoryCB != NULL)
580             {
581
582                 //
583                 // pParentDirectoryCB DirOpenReferenceCount is still held
584                 //
585
586                 UNICODE_STRING uniFinalComponent;
587
588                 uniFinalComponent.Length = 0;
589                 uniFinalComponent.MaximumLength = 0;
590                 uniFinalComponent.Buffer = NULL;
591
592                 AFSRetrieveFinalComponent( &uniFileName,
593                                            &uniFinalComponent);
594
595                 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
596                                                   &uniFinalComponent);
597
598                 if( !NT_SUCCESS( ntStatus) &&
599                     ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
600                 {
601
602                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
603                                   AFS_TRACE_LEVEL_VERBOSE,
604                                   "AFSCommonCreate (%p) Failing access to symlink %wZ Status %08lX\n",
605                                   Irp,
606                                   &uniFileName,
607                                   ntStatus);
608
609                     try_return( ntStatus);
610                 }
611             }
612         }
613
614         //
615         // If we have no parent then this is a root open, be sure there is a directory entry
616         // for the root
617         //
618
619         else if( pParentDirectoryCB == NULL &&
620                  pDirectoryCB == NULL)
621         {
622
623             pDirectoryCB = pVolumeCB->DirectoryCB;
624
625             lCount = InterlockedIncrement( &pDirectoryCB->DirOpenReferenceCount);
626
627             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
628                           AFS_TRACE_LEVEL_VERBOSE,
629                           "AFSCommonCreate Increment0 count on %wZ DE %p Ccb %p Cnt %d\n",
630                           &pDirectoryCB->NameInformation.FileName,
631                           pDirectoryCB,
632                           pCcb,
633                           lCount);
634
635             bReleaseDir = TRUE;
636         }
637
638         if( bOpenTargetDirectory)
639         {
640
641             //
642             // If we have a directory cb for the entry then dereference it and reference the parent
643             //
644
645             if( pDirectoryCB != NULL)
646             {
647
648                 if ( !bReleaseParentDir)
649                 {
650
651                     //
652                     // Perform in this order to prevent thrashing
653                     //
654
655                     lCount = InterlockedIncrement( &pParentDirectoryCB->DirOpenReferenceCount);
656
657                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
658                                   AFS_TRACE_LEVEL_VERBOSE,
659                                   "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
660                                   &pParentDirectoryCB->NameInformation.FileName,
661                                   pParentDirectoryCB,
662                                   pCcb,
663                                   lCount);
664
665                     bReleaseParentDir = TRUE;
666                 }
667
668                 //
669                 // Do NOT decrement the reference count on the pDirectoryCB yet.
670                 // The BackupEntry below might drop the count to zero leaving
671                 // the entry subject to being deleted and we need some of the
672                 // contents during later processing
673                 //
674
675                 AFSBackupEntry( pNameArray);
676             }
677
678             //
679             // OK, open the target directory
680             //
681
682             if( uniComponentName.Length == 0)
683             {
684                 AFSRetrieveFinalComponent( &uniFileName,
685                                            &uniComponentName);
686             }
687
688             ntStatus = AFSOpenTargetDirectory( Irp,
689                                                pVolumeCB,
690                                                pParentDirectoryCB,
691                                                pDirectoryCB,
692                                                &uniComponentName,
693                                                &pFcb,
694                                                &pCcb);
695
696             if( !NT_SUCCESS( ntStatus))
697             {
698
699                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
700                               AFS_TRACE_LEVEL_ERROR,
701                               "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
702                               &pParentDirectoryCB->NameInformation.FileName,
703                               ntStatus);
704             }
705
706             try_return( ntStatus);
707         }
708
709         if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
710         {
711
712             if( pDirectoryCB == NULL ||
713                 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
714             {
715                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
716                               AFS_TRACE_LEVEL_VERBOSE,
717                               "AFSCommonCreate (%p) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
718                               Irp,
719                               &uniFileName,
720                               pDirectoryCB,
721                               pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0);
722             }
723             else
724             {
725                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
726                               AFS_TRACE_LEVEL_VERBOSE,
727                               "AFSCommonCreate (%p) Opening as reparse point %wZ Type %08lX\n",
728                               Irp,
729                               &uniFileName,
730                               pDirectoryCB->ObjectInformation->FileType);
731
732                 bOpenedReparsePoint = TRUE;
733             }
734         }
735
736         //
737         // Based on the options passed in, process the file accordingly.
738         //
739
740         if( ulCreateDisposition == FILE_CREATE ||
741             ( ( ulCreateDisposition == FILE_OPEN_IF ||
742                 ulCreateDisposition == FILE_OVERWRITE_IF) &&
743               pDirectoryCB == NULL))
744         {
745
746             if( uniComponentName.Length == 0 ||
747                 pDirectoryCB != NULL)
748             {
749
750                 //
751                 // We traversed the entire path so we found each entry,
752                 // fail with collision
753                 //
754
755                 if( pDirectoryCB != NULL)
756                 {
757
758                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
759                                   AFS_TRACE_LEVEL_VERBOSE,
760                                   "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
761                                   &pDirectoryCB->NameInformation.FileName,
762                                   ntStatus);
763                 }
764                 else
765                 {
766
767                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
768                                   AFS_TRACE_LEVEL_VERBOSE,
769                                   "AFSCommonCreate Object name collision on create Status %08lX\n",
770                                   ntStatus);
771                 }
772
773                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
774             }
775
776             //
777             // OK, go and create the node
778             //
779
780             ntStatus = AFSProcessCreate( Irp,
781                                          &stAuthGroup,
782                                          pVolumeCB,
783                                          pParentDirectoryCB,
784                                          &uniFileName,
785                                          &uniComponentName,
786                                          &uniRootFileName,
787                                          &pFcb,
788                                          &pCcb);
789
790             if( !NT_SUCCESS( ntStatus))
791             {
792
793                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
794                               AFS_TRACE_LEVEL_ERROR,
795                               "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
796                               &uniComponentName,
797                               &pParentDirectoryCB->NameInformation.FileName,
798                               ntStatus);
799             }
800
801             try_return( ntStatus);
802         }
803
804         //
805         // We should not have an extra component except for PIOCtl opens
806         //
807
808         if( uniComponentName.Length > 0)
809         {
810
811             //
812             // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
813             //
814
815             if( RtlCompareUnicodeString( &AFSPIOCtlName,
816                                          &uniComponentName,
817                                          TRUE) == 0)
818             {
819
820                 //
821                 // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
822                 // pParentDirectoryCB.
823                 //
824
825                 ntStatus = AFSOpenIOCtlFcb( Irp,
826                                             &stAuthGroup,
827                                             pParentDirectoryCB,
828                                             &pFcb,
829                                             &pCcb);
830
831                 if( !NT_SUCCESS( ntStatus))
832                 {
833
834                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
835                                   AFS_TRACE_LEVEL_ERROR,
836                                   "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
837                                   &uniComponentName,
838                                   ntStatus);
839                 }
840             }
841             else
842             {
843
844                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
845                               AFS_TRACE_LEVEL_VERBOSE,
846                               "AFSCommonCreate (%p) File %wZ name not found\n",
847                               Irp,
848                               &uniFileName);
849
850                 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
851             }
852
853             try_return( ntStatus);
854         }
855
856         //
857         // For root opens the parent will be NULL
858         //
859
860         if( pParentDirectoryCB == NULL)
861         {
862
863             //
864             // Check for the delete on close flag for the root
865             //
866
867             if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
868             {
869
870                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
871                               AFS_TRACE_LEVEL_ERROR,
872                               "AFSCommonCreate (%p) Attempt to open root as delete on close\n",
873                               Irp);
874
875                 try_return( ntStatus = STATUS_CANNOT_DELETE);
876             }
877
878             //
879             // If this is the target directory, then bail
880             //
881
882             if( bOpenTargetDirectory)
883             {
884
885                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
886                               AFS_TRACE_LEVEL_ERROR,
887                               "AFSCommonCreate (%p) Attempt to open root as target directory\n",
888                               Irp);
889
890                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
891             }
892
893             //
894             // Go and open the root of the volume
895             //
896
897             ntStatus = AFSOpenRoot( Irp,
898                                     pVolumeCB,
899                                     &stAuthGroup,
900                                     &pFcb,
901                                     &pCcb);
902
903             if( !NT_SUCCESS( ntStatus))
904             {
905
906                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
907                               AFS_TRACE_LEVEL_ERROR,
908                               "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
909                               pVolumeCB->ObjectInformation.FileId.Cell,
910                               pVolumeCB->ObjectInformation.FileId.Volume,
911                               ntStatus);
912             }
913
914             try_return( ntStatus);
915         }
916
917         //
918         // At this point if we have no pDirectoryCB it was not found.
919         //
920
921         if( pDirectoryCB == NULL)
922         {
923
924             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
925                           AFS_TRACE_LEVEL_ERROR,
926                           "AFSCommonCreate Failing access to %wZ Name not found\n",
927                           &uniFileName);
928
929             try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
930         }
931
932         if( ulCreateDisposition == FILE_OVERWRITE ||
933             ulCreateDisposition == FILE_SUPERSEDE ||
934             ulCreateDisposition == FILE_OVERWRITE_IF)
935         {
936
937             //
938             // Go process a file for overwrite or supersede.
939             //
940
941             ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
942                                                      Irp,
943                                                      pVolumeCB,
944                                                      &stAuthGroup,
945                                                      pParentDirectoryCB,
946                                                      pDirectoryCB,
947                                                      &pFcb,
948                                                      &pCcb);
949
950             if( !NT_SUCCESS( ntStatus))
951             {
952
953                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
954                               AFS_TRACE_LEVEL_ERROR,
955                               "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
956                               &pDirectoryCB->NameInformation.FileName,
957                               ntStatus);
958             }
959
960             try_return( ntStatus);
961         }
962
963         //
964         // Trying to open the file
965         //
966
967         ntStatus = AFSProcessOpen( Irp,
968                                    &stAuthGroup,
969                                    pVolumeCB,
970                                    pParentDirectoryCB,
971                                    pDirectoryCB,
972                                    &pFcb,
973                                    &pCcb);
974
975         if( !NT_SUCCESS( ntStatus))
976         {
977
978             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
979                           AFS_TRACE_LEVEL_ERROR,
980                           "AFSCommonCreate Failed open on %wZ Status %08lX\n",
981                           &pDirectoryCB->NameInformation.FileName,
982                           ntStatus);
983         }
984
985 try_exit:
986
987         if( NT_SUCCESS( ntStatus) &&
988             ntStatus != STATUS_REPARSE)
989         {
990
991             if( pCcb != NULL)
992             {
993
994                 AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
995                                 TRUE);
996
997                 RtlCopyMemory( &pCcb->AuthGroup,
998                                &stAuthGroup,
999                                sizeof( GUID));
1000
1001                 //
1002                 // If we have a substitute name, then use it
1003                 //
1004
1005                 if( uniSubstitutedPathName.Buffer != NULL)
1006                 {
1007
1008                     pCcb->FullFileName = uniSubstitutedPathName;
1009
1010                     SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1011
1012                     ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1013                 }
1014                 else
1015                 {
1016
1017                     pCcb->FullFileName = uniRootFileName;
1018
1019                     if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1020                     {
1021
1022                         SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1023
1024                         ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1025                     }
1026                 }
1027
1028                 if( bOpenedReparsePoint)
1029                 {
1030                     SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1031                 }
1032
1033                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1034                               AFS_TRACE_LEVEL_VERBOSE,
1035                               "AFSCommonCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1036                               &pCcb->DirectoryCB->NameInformation.FileName,
1037                               pCcb->DirectoryCB,
1038                               pCcb,
1039                               lCount = pCcb->DirectoryCB->DirOpenReferenceCount);
1040
1041                 ASSERT( lCount >= 0);
1042
1043                 pCcb->CurrentDirIndex = 0;
1044
1045                 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1046                 {
1047
1048                     SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1049                 }
1050
1051                 //
1052                 // Save off the name array for this instance
1053                 //
1054
1055                 pCcb->NameArray = pNameArray;
1056
1057                 pNameArray = NULL;
1058
1059                 AFSReleaseResource( &pCcb->NPCcb->CcbLock);
1060             }
1061
1062             //
1063             // If we make it here then init the FO for the request.
1064             //
1065
1066             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1067                           AFS_TRACE_LEVEL_VERBOSE_2,
1068                           "AFSCommonCreate (%p) FileObject %p FsContext %p FsContext2 %p\n",
1069                           Irp,
1070                           pFileObject,
1071                           pFcb,
1072                           pCcb);
1073
1074             pFileObject->FsContext = (void *)pFcb;
1075
1076             pFileObject->FsContext2 = (void *)pCcb;
1077
1078             if( pFcb != NULL)
1079             {
1080
1081                 ASSERT( pFcb->OpenHandleCount > 0);
1082
1083                 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1084
1085                 //
1086                 // For files perform additional processing
1087                 //
1088
1089                 switch( pFcb->Header.NodeTypeCode)
1090                 {
1091
1092                     case AFS_FILE_FCB:
1093                     case AFS_IOCTL_FCB:
1094                     {
1095
1096                         pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1097                     }
1098                 }
1099
1100                 //
1101                 // If the user did not request nobuffering then mark the FO as cacheable
1102                 //
1103
1104                 if( bNoIntermediateBuffering)
1105                 {
1106
1107                     pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1108                 }
1109                 else
1110                 {
1111
1112                     pFileObject->Flags |= FO_CACHE_SUPPORTED;
1113                 }
1114
1115                 //
1116                 // If the file was opened for execution then we need to set the bit in the FO
1117                 //
1118
1119                 if( BooleanFlagOn( *pDesiredAccess,
1120                                    FILE_EXECUTE))
1121                 {
1122
1123                     SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1124                 }
1125
1126                 //
1127                 // Update the last access time
1128                 //
1129
1130                 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1131
1132                 if( pCcb != NULL)
1133                 {
1134                     AFSInsertCcb( pFcb,
1135                                   pCcb);
1136                 }
1137             }
1138             else
1139             {
1140
1141                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1142                               AFS_TRACE_LEVEL_ERROR,
1143                               "AFSCommonCreate (%p) Returning with NULL Fcb FileObject %p FsContext %p FsContext2 %p\n",
1144                               Irp,
1145                               pFileObject,
1146                               pFcb,
1147                               pCcb);
1148             }
1149         }
1150         else
1151         {
1152             if( NT_SUCCESS( ntStatus) &&
1153                 ntStatus == STATUS_REPARSE)
1154             {
1155
1156                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1157                               AFS_TRACE_LEVEL_ERROR,
1158                               "AFSCommonCreate (%p) STATUS_REPARSE FileObject %p FsContext %p FsContext2 %p\n",
1159                               Irp,
1160                               pFileObject,
1161                               pFcb,
1162                               pCcb);
1163             }
1164
1165             //
1166             // Free up the sub name if we have one
1167             //
1168
1169             if( uniSubstitutedPathName.Buffer != NULL)
1170             {
1171
1172                 AFSExFreePoolWithTag( uniSubstitutedPathName.Buffer, 0);
1173
1174                 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1175             }
1176         }
1177
1178         //
1179         // Free up the name array ...
1180         //
1181
1182         if( pNameArray != NULL)
1183         {
1184
1185             AFSFreeNameArray( pNameArray);
1186         }
1187
1188         if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1189         {
1190
1191             AFSExFreePoolWithTag( uniRootFileName.Buffer, 0);
1192         }
1193
1194         if( bReleaseVolume)
1195         {
1196
1197             lCount = AFSVolumeDecrement( pVolumeCB,
1198                                          VolumeReferenceReason);
1199
1200             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1201                           AFS_TRACE_LEVEL_VERBOSE,
1202                           "AFSCommonCreate Decrement count on Volume %08lX Reason %u Cnt %d\n",
1203                           pVolumeCB,
1204                           VolumeReferenceReason,
1205                           lCount);
1206         }
1207
1208         if ( bReleaseDir)
1209         {
1210
1211             //
1212             // Release the reference from AFSLocateNameEntry
1213             //
1214
1215             lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
1216
1217             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1218                           AFS_TRACE_LEVEL_VERBOSE,
1219                           "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1220                           &pDirectoryCB->NameInformation.FileName,
1221                           pDirectoryCB,
1222                           pCcb,
1223                           lCount);
1224
1225             ASSERT( lCount >= 0);
1226         }
1227
1228         if ( bReleaseParentDir)
1229         {
1230
1231             //
1232             // Release the reference from AFSLocateNameEntry
1233             //
1234
1235             lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
1236
1237             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1238                           AFS_TRACE_LEVEL_VERBOSE,
1239                           "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1240                           &pParentDirectoryCB->NameInformation.FileName,
1241                           pParentDirectoryCB,
1242                           pCcb,
1243                           lCount);
1244
1245             ASSERT( lCount >= 0);
1246         }
1247
1248         //
1249         // Setup the Irp for completion, the Information has been set previously
1250         //
1251
1252         Irp->IoStatus.Status = ntStatus;
1253     }
1254
1255     return ntStatus;
1256 }
1257
1258 NTSTATUS
1259 AFSOpenAFSRoot( IN PIRP Irp,
1260                 IN AFSFcb **Fcb,
1261                 IN AFSCcb **Ccb)
1262 {
1263
1264     NTSTATUS ntStatus = STATUS_SUCCESS;
1265     LONG lCount;
1266
1267     __Enter
1268     {
1269
1270         //
1271         // Initialize the Ccb for the file.
1272         //
1273
1274         ntStatus = AFSInitCcb( Ccb,
1275                                AFSGlobalRoot->DirectoryCB,
1276                                0,
1277                                0);
1278
1279         if( !NT_SUCCESS( ntStatus))
1280         {
1281
1282             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1283                           AFS_TRACE_LEVEL_ERROR,
1284                           "AFSOpenAFSRoot (%p) Failed to allocate Ccb\n",
1285                           Irp);
1286
1287             try_return( ntStatus);
1288         }
1289
1290         //
1291         // Increment the open count on this Fcb
1292         //
1293
1294         lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1295
1296         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1297                       AFS_TRACE_LEVEL_VERBOSE,
1298                       "AFSOpenAFSRoot Increment count on Fcb %p Cnt %d\n",
1299                       AFSGlobalRoot->RootFcb,
1300                       lCount);
1301
1302         lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1303
1304         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1305                       AFS_TRACE_LEVEL_VERBOSE,
1306                       "AFSOpenAFSRoot Increment handle count on Fcb %p Cnt %d\n",
1307                       AFSGlobalRoot->RootFcb,
1308                       lCount);
1309
1310         *Fcb = AFSGlobalRoot->RootFcb;
1311
1312         //
1313         // Return the open result for this file
1314         //
1315
1316         Irp->IoStatus.Information = FILE_OPENED;
1317
1318 try_exit:
1319
1320         NOTHING;
1321     }
1322
1323     return ntStatus;
1324 }
1325
1326 NTSTATUS
1327 AFSOpenRoot( IN PIRP Irp,
1328              IN AFSVolumeCB *VolumeCB,
1329              IN GUID *AuthGroup,
1330              OUT AFSFcb **RootFcb,
1331              OUT AFSCcb **Ccb)
1332 {
1333
1334     NTSTATUS ntStatus = STATUS_SUCCESS;
1335     PFILE_OBJECT pFileObject = NULL;
1336     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1337     PACCESS_MASK pDesiredAccess = NULL;
1338     USHORT usShareAccess;
1339     ULONG ulOptions;
1340     BOOLEAN bAllocatedCcb = FALSE;
1341     BOOLEAN bReleaseFcb = FALSE;
1342     AFSFileOpenCB   stOpenCB;
1343     AFSFileOpenResultCB stOpenResultCB;
1344     ULONG       ulResultLen = 0;
1345     LONG        lCount;
1346
1347     __Enter
1348     {
1349
1350         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1351         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1352         ulOptions = pIrpSp->Parameters.Create.Options;
1353
1354         pFileObject = pIrpSp->FileObject;
1355
1356         if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1357         {
1358
1359             ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1360
1361             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1362                           AFS_TRACE_LEVEL_ERROR,
1363                           "AFSOpenRoot (%p) Attempt to open root as file Status %08lX\n",
1364                           Irp,
1365                           ntStatus);
1366
1367             try_return( ntStatus);
1368         }
1369
1370         //
1371         // Check if we should go and retrieve updated information for the node
1372         //
1373
1374         ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1375                                      AuthGroup,
1376                                      FALSE,
1377                                      TRUE);
1378
1379         if( !NT_SUCCESS( ntStatus))
1380         {
1381
1382             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1383                           AFS_TRACE_LEVEL_ERROR,
1384                           "AFSOpenRoot (%p) Failed to validate root entry Status %08lX\n",
1385                           Irp,
1386                           ntStatus);
1387
1388             try_return( ntStatus);
1389         }
1390
1391         //
1392         // Check with the service that we can open the file
1393         //
1394
1395         RtlZeroMemory( &stOpenCB,
1396                        sizeof( AFSFileOpenCB));
1397
1398         stOpenCB.DesiredAccess = *pDesiredAccess;
1399
1400         stOpenCB.ShareAccess = usShareAccess;
1401
1402         stOpenResultCB.GrantedAccess = 0;
1403
1404         ulResultLen = sizeof( AFSFileOpenResultCB);
1405
1406         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1407                                       AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1408                                       AuthGroup,
1409                                       NULL,
1410                                       &VolumeCB->ObjectInformation.FileId,
1411                                       (void *)&stOpenCB,
1412                                       sizeof( AFSFileOpenCB),
1413                                       (void *)&stOpenResultCB,
1414                                       &ulResultLen);
1415
1416         if( !NT_SUCCESS( ntStatus))
1417         {
1418
1419             UNICODE_STRING uniGUID;
1420
1421             uniGUID.Length = 0;
1422             uniGUID.MaximumLength = 0;
1423             uniGUID.Buffer = NULL;
1424
1425             if( AuthGroup != NULL)
1426             {
1427                 RtlStringFromGUID( *AuthGroup,
1428                                    &uniGUID);
1429             }
1430
1431             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1432                           AFS_TRACE_LEVEL_ERROR,
1433                           "AFSOpenRoot (%p) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1434                           Irp,
1435                           VolumeCB->ObjectInformation.FileId.Cell,
1436                           VolumeCB->ObjectInformation.FileId.Volume,
1437                           &uniGUID,
1438                           ntStatus);
1439
1440             if( AuthGroup != NULL)
1441             {
1442                 RtlFreeUnicodeString( &uniGUID);
1443             }
1444
1445             try_return( ntStatus);
1446         }
1447
1448         //
1449         // If the entry is not initialized then do it now
1450         //
1451
1452         if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1453         {
1454
1455             AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1456                             TRUE);
1457
1458             if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1459             {
1460
1461                 ntStatus = AFSEnumerateDirectory( AuthGroup,
1462                                                   &VolumeCB->ObjectInformation,
1463                                                   TRUE);
1464
1465                 if( !NT_SUCCESS( ntStatus))
1466                 {
1467
1468                     AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1469
1470                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1471                                   AFS_TRACE_LEVEL_ERROR,
1472                                   "AFSOpenRoot (%p) Failed to enumerate directory Status %08lX\n",
1473                                   Irp,
1474                                   ntStatus);
1475
1476                     try_return( ntStatus);
1477                 }
1478
1479                 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1480             }
1481
1482             AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1483         }
1484
1485         //
1486         // If the root fcb has been initialized then check access otherwise
1487         // init the volume fcb
1488         //
1489
1490         ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1491                                    VolumeCB);
1492
1493         if( !NT_SUCCESS( ntStatus))
1494         {
1495
1496             try_return( ntStatus);
1497         }
1498
1499         lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1500
1501         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1502                       AFS_TRACE_LEVEL_VERBOSE,
1503                       "AFSOpenRoot Increment count on Fcb %p Cnt %d\n",
1504                       VolumeCB->RootFcb,
1505                       lCount);
1506
1507         bReleaseFcb = TRUE;
1508
1509         //
1510         // If there are current opens on the Fcb, check the access.
1511         //
1512
1513         if( VolumeCB->RootFcb->OpenHandleCount > 0)
1514         {
1515
1516             ntStatus = IoCheckShareAccess( *pDesiredAccess,
1517                                            usShareAccess,
1518                                            pFileObject,
1519                                            &VolumeCB->RootFcb->ShareAccess,
1520                                            FALSE);
1521
1522             if( !NT_SUCCESS( ntStatus))
1523             {
1524
1525                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1526                               AFS_TRACE_LEVEL_ERROR,
1527                               "AFSOpenRoot (%p) Access check failure Status %08lX\n",
1528                               Irp,
1529                               ntStatus);
1530
1531                 try_return( ntStatus);
1532             }
1533         }
1534
1535         //
1536         // Initialize the Ccb for the file.
1537         //
1538
1539         ntStatus = AFSInitCcb( Ccb,
1540                                VolumeCB->DirectoryCB,
1541                                *pDesiredAccess,
1542                                0);
1543
1544         if( !NT_SUCCESS( ntStatus))
1545         {
1546
1547             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1548                           AFS_TRACE_LEVEL_ERROR,
1549                           "AFSOpenRoot (%p) Failed to allocate Ccb Status %08lX\n",
1550                           Irp,
1551                           ntStatus);
1552
1553             try_return( ntStatus);
1554         }
1555
1556         bAllocatedCcb = TRUE;
1557
1558         //
1559         // OK, update the share access on the fileobject
1560         //
1561
1562         if( VolumeCB->RootFcb->OpenHandleCount > 0)
1563         {
1564
1565             IoUpdateShareAccess( pFileObject,
1566                                  &VolumeCB->RootFcb->ShareAccess);
1567         }
1568         else
1569         {
1570
1571             //
1572             // Set the access
1573             //
1574
1575             IoSetShareAccess( *pDesiredAccess,
1576                               usShareAccess,
1577                               pFileObject,
1578                               &VolumeCB->RootFcb->ShareAccess);
1579         }
1580
1581         //
1582         // Increment the open count on this Fcb
1583         //
1584
1585         lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1586
1587         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1588                       AFS_TRACE_LEVEL_VERBOSE,
1589                       "AFSOpenRoot Increment handle count on Fcb %p Cnt %d\n",
1590                       VolumeCB->RootFcb,
1591                       lCount);
1592
1593         //
1594         // Indicate the object is held
1595         //
1596
1597         SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1598
1599         //
1600         // Return the open result for this file
1601         //
1602
1603         Irp->IoStatus.Information = FILE_OPENED;
1604
1605         *RootFcb = VolumeCB->RootFcb;
1606
1607 try_exit:
1608
1609         if( bReleaseFcb)
1610         {
1611             if ( !NT_SUCCESS( ntStatus))
1612             {
1613
1614                 lCount = InterlockedDecrement( &VolumeCB->RootFcb->OpenReferenceCount);
1615
1616                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1617                               AFS_TRACE_LEVEL_VERBOSE,
1618                               "AFSOpenRoot Decrement count on Fcb %p Cnt %d\n",
1619                               VolumeCB->RootFcb,
1620                               lCount);
1621             }
1622
1623             AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1624         }
1625
1626         if( !NT_SUCCESS( ntStatus))
1627         {
1628
1629             if( bAllocatedCcb)
1630             {
1631
1632                 AFSRemoveCcb( NULL,
1633                               *Ccb);
1634
1635                 *Ccb = NULL;
1636             }
1637
1638             Irp->IoStatus.Information = 0;
1639         }
1640     }
1641
1642     return ntStatus;
1643 }
1644
1645 NTSTATUS
1646 AFSProcessCreate( IN PIRP               Irp,
1647                   IN GUID              *AuthGroup,
1648                   IN AFSVolumeCB       *VolumeCB,
1649                   IN AFSDirectoryCB    *ParentDirCB,
1650                   IN PUNICODE_STRING    FileName,
1651                   IN PUNICODE_STRING    ComponentName,
1652                   IN PUNICODE_STRING    FullFileName,
1653                   OUT AFSFcb          **Fcb,
1654                   OUT AFSCcb          **Ccb)
1655 {
1656
1657     NTSTATUS ntStatus = STATUS_SUCCESS;
1658     PFILE_OBJECT pFileObject = NULL;
1659     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1660     ULONG ulOptions = 0;
1661     ULONG ulAttributes = 0;
1662     BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1663     PACCESS_MASK pDesiredAccess = NULL;
1664     USHORT usShareAccess;
1665     AFSDirectoryCB *pDirEntry = NULL;
1666     AFSObjectInfoCB *pParentObjectInfo = NULL;
1667     AFSObjectInfoCB *pObjectInfo = NULL;
1668     LONG lCount;
1669
1670     __Enter
1671     {
1672
1673         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1674         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1675
1676         pFileObject = pIrpSp->FileObject;
1677
1678         //
1679         // Extract out the options
1680         //
1681
1682         ulOptions = pIrpSp->Parameters.Create.Options;
1683
1684         //
1685         // We pass all attributes they want to apply to the file to the create
1686         //
1687
1688         ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1689
1690         //
1691         // If this is a directory create then set the attribute correctly
1692         //
1693
1694         if( ulOptions & FILE_DIRECTORY_FILE)
1695         {
1696
1697             ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1698         }
1699
1700         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1701                       AFS_TRACE_LEVEL_VERBOSE,
1702                       "AFSProcessCreate (%p) Creating file %wZ Attributes %08lX\n",
1703                       Irp,
1704                       FullFileName,
1705                       ulAttributes);
1706
1707         if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1708         {
1709
1710             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1711                           AFS_TRACE_LEVEL_ERROR,
1712                           "AFSProcessCreate Request failed due to read only volume %wZ\n",
1713                           FullFileName);
1714
1715             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
1716         }
1717
1718         pParentObjectInfo = ParentDirCB->ObjectInformation;
1719
1720         //
1721         // Allocate and insert the direntry into the parent node
1722         //
1723
1724         ntStatus = AFSCreateDirEntry( AuthGroup,
1725                                       pParentObjectInfo,
1726                                       ParentDirCB,
1727                                       FileName,
1728                                       ComponentName,
1729                                       ulAttributes,
1730                                       &pDirEntry);
1731
1732         if( !NT_SUCCESS( ntStatus))
1733         {
1734
1735             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1736                           AFS_TRACE_LEVEL_ERROR,
1737                           "AFSProcessCreate (%p) Failed to create directory entry %wZ Status %08lX\n",
1738                           Irp,
1739                           FullFileName,
1740                           ntStatus);
1741
1742             try_return( ntStatus);
1743         }
1744
1745         bFileCreated = TRUE;
1746
1747         pObjectInfo = pDirEntry->ObjectInformation;
1748
1749         if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1750             pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1751         {
1752
1753             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1754                           AFS_TRACE_LEVEL_VERBOSE,
1755                           "AFSProcessCreate (%p) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1756                           Irp,
1757                           &pDirEntry->NameInformation.FileName,
1758                           pObjectInfo->FileId.Cell,
1759                           pObjectInfo->FileId.Volume,
1760                           pObjectInfo->FileId.Vnode,
1761                           pObjectInfo->FileId.Unique);
1762
1763             ntStatus = AFSEvaluateNode( AuthGroup,
1764                                         pDirEntry);
1765
1766             if( !NT_SUCCESS( ntStatus))
1767             {
1768
1769                 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
1770                 {
1771
1772                     if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1773                     {
1774
1775                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1776                                       AFS_TRACE_LEVEL_ERROR,
1777                                       "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
1778                                       Irp,
1779                                       &pDirEntry->NameInformation.FileName,
1780                                       pObjectInfo->FileId.Cell,
1781                                       pObjectInfo->FileId.Volume,
1782                                       pObjectInfo->FileId.Vnode,
1783                                       pObjectInfo->FileId.Unique,
1784                                       pParentObjectInfo->FileId.Cell,
1785                                       pParentObjectInfo->FileId.Volume,
1786                                       pParentObjectInfo->FileId.Vnode,
1787                                       pParentObjectInfo->FileId.Unique,
1788                                       ntStatus);
1789                     }
1790                     else if ( AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId))
1791                     {
1792
1793                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1794                                       AFS_TRACE_LEVEL_ERROR,
1795                                       "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1796                                       Irp,
1797                                       &pDirEntry->NameInformation.FileName,
1798                                       pObjectInfo->FileId.Cell,
1799                                       pObjectInfo->FileId.Volume,
1800                                       pObjectInfo->FileId.Vnode,
1801                                       pObjectInfo->FileId.Unique,
1802                                       pParentObjectInfo->FileId.Cell,
1803                                       pParentObjectInfo->FileId.Volume,
1804                                       pParentObjectInfo->FileId.Vnode,
1805                                       pParentObjectInfo->FileId.Unique,
1806                                       ntStatus);
1807                     }
1808                     else
1809                     {
1810
1811                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1812                                       AFS_TRACE_LEVEL_ERROR,
1813                                       "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1814                                       Irp,
1815                                       &pDirEntry->NameInformation.FileName,
1816                                       pObjectInfo->FileId.Cell,
1817                                       pObjectInfo->FileId.Volume,
1818                                       pObjectInfo->FileId.Vnode,
1819                                       pObjectInfo->FileId.Unique,
1820                                       pParentObjectInfo->FileId.Cell,
1821                                       pParentObjectInfo->FileId.Volume,
1822                                       pParentObjectInfo->FileId.Vnode,
1823                                       pParentObjectInfo->FileId.Unique,
1824                                       pObjectInfo->ParentFileId.Cell,
1825                                       pObjectInfo->ParentFileId.Volume,
1826                                       pObjectInfo->ParentFileId.Vnode,
1827                                       pObjectInfo->ParentFileId.Unique,
1828                                       ntStatus);
1829                     }
1830                 }
1831                 else
1832                 {
1833
1834                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1835                                   AFS_TRACE_LEVEL_ERROR,
1836                                   "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1837                                   Irp,
1838                                   &pDirEntry->NameInformation.FileName,
1839                                   pObjectInfo->FileId.Cell,
1840                                   pObjectInfo->FileId.Volume,
1841                                   pObjectInfo->FileId.Vnode,
1842                                   pObjectInfo->FileId.Unique,
1843                                   ntStatus);
1844                 }
1845
1846                 try_return( ntStatus);
1847             }
1848
1849             ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1850         }
1851
1852         ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
1853                 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
1854
1855         //
1856         // We may have raced and the Fcb is already created
1857         //
1858
1859         //
1860         // Allocate and initialize the Fcb for the file.
1861         //
1862
1863         ntStatus = AFSInitFcb( pDirEntry);
1864
1865         *Fcb = pObjectInfo->Fcb;
1866
1867         if( !NT_SUCCESS( ntStatus))
1868         {
1869
1870             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1871                           AFS_TRACE_LEVEL_ERROR,
1872                           "AFSProcessCreate (%p) Failed to initialize fcb %wZ Status %08lX\n",
1873                           Irp,
1874                           FullFileName,
1875                           ntStatus);
1876
1877             try_return( ntStatus);
1878         }
1879
1880         ntStatus = STATUS_SUCCESS;
1881
1882         //
1883         // Increment the open count on this Fcb
1884         //
1885
1886         lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1887
1888         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1889                       AFS_TRACE_LEVEL_VERBOSE,
1890                       "AFSProcessCreate Increment count on Fcb %p Cnt %d\n",
1891                       *Fcb,
1892                       lCount);
1893
1894         bReleaseFcb = TRUE;
1895
1896         //
1897         // Initialize the Ccb for the file.
1898         //
1899
1900         ntStatus = AFSInitCcb( Ccb,
1901                                pDirEntry,
1902                                *pDesiredAccess,
1903                                0);
1904
1905         if( !NT_SUCCESS( ntStatus))
1906         {
1907
1908             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1909                           AFS_TRACE_LEVEL_ERROR,
1910                           "AFSProcessCreate (%p) Failed to initialize ccb %wZ Status %08lX\n",
1911                           Irp,
1912                           FullFileName,
1913                           ntStatus);
1914
1915             try_return( ntStatus);
1916         }
1917
1918         bAllocatedCcb = TRUE;
1919
1920         //
1921         // If this is a file, update the headers filesizes.
1922         //
1923
1924         if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1925         {
1926
1927             //
1928             // Update the sizes with the information passed in
1929             //
1930
1931             (*Fcb)->Header.AllocationSize.QuadPart  = pObjectInfo->AllocationSize.QuadPart;
1932             (*Fcb)->Header.FileSize.QuadPart        = pObjectInfo->EndOfFile.QuadPart;
1933             (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1934
1935             //
1936             // Notify the system of the addition
1937             //
1938
1939             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1940                                             *Ccb,
1941                                             (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1942                                             (ULONG)FILE_ACTION_ADDED);
1943
1944             (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
1945         }
1946         else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1947         {
1948
1949             //
1950             // This is a new directory node so indicate it has been enumerated
1951             //
1952
1953             SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1954
1955             //
1956             // And the parent directory entry
1957             //
1958
1959             KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1960
1961             //
1962             // Notify the system of the addition
1963             //
1964
1965             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1966                                             *Ccb,
1967                                             (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1968                                             (ULONG)FILE_ACTION_ADDED);
1969         }
1970         else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
1971                  (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
1972                  (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
1973                  (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
1974         {
1975
1976             //
1977             // And the parent directory entry
1978             //
1979
1980             KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1981
1982             //
1983             // Notify the system of the addition
1984             //
1985
1986             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1987                                             *Ccb,
1988                                             (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1989                                             (ULONG)FILE_ACTION_ADDED);
1990         }
1991
1992         //
1993         // Save off the access for the open
1994         //
1995
1996         IoSetShareAccess( *pDesiredAccess,
1997                           usShareAccess,
1998                           pFileObject,
1999                           &(*Fcb)->ShareAccess);
2000
2001         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2002
2003         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2004                       AFS_TRACE_LEVEL_VERBOSE,
2005                       "AFSProcessCreate Increment handle count on Fcb %p Cnt %d\n",
2006                       (*Fcb),
2007                       lCount);
2008
2009         //
2010         // Increment the open reference and handle on the parent node
2011         //
2012
2013         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2014
2015         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2016                       AFS_TRACE_LEVEL_VERBOSE,
2017                       "AFSProcessCreate Increment child open handle count on Parent object %p Cnt %d\n",
2018                       pParentObjectInfo,
2019                       lCount);
2020
2021         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2022
2023         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2024                       AFS_TRACE_LEVEL_VERBOSE,
2025                       "AFSProcessCreate Increment child open ref count on Parent object %p Cnt %d\n",
2026                       pParentObjectInfo,
2027                       lCount);
2028
2029         if( ulOptions & FILE_DELETE_ON_CLOSE)
2030         {
2031
2032             //
2033             // Mark it for delete on close
2034             //
2035
2036             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2037                           AFS_TRACE_LEVEL_VERBOSE,
2038                           "AFSProcessCreate (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2039                           Irp,
2040                           pDirEntry,
2041                           FullFileName);
2042
2043             SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2044         }
2045
2046         //
2047         // Indicate the object is locked in the service
2048         //
2049
2050         SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2051
2052         //
2053         // Return the open result for this file
2054         //
2055
2056         Irp->IoStatus.Information = FILE_CREATED;
2057
2058 try_exit:
2059
2060         //
2061         // If we created the Fcb we need to release the resources
2062         //
2063
2064         if( bReleaseFcb)
2065         {
2066
2067             if( !NT_SUCCESS( ntStatus))
2068             {
2069                 //
2070                 // Decrement the open count on this Fcb
2071                 //
2072
2073                 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2074
2075                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2076                               AFS_TRACE_LEVEL_VERBOSE,
2077                               "AFSProcessCreate Decrement count on Fcb %p Cnt %d\n",
2078                               *Fcb,
2079                               lCount);
2080             }
2081
2082             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2083         }
2084
2085         if ( bFileCreated)
2086         {
2087
2088             //
2089             // Decrement the reference added during initialization of the DE
2090             // AFSInitCcb allocates its own reference count.
2091             //
2092
2093             lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2094
2095             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2096                           AFS_TRACE_LEVEL_VERBOSE,
2097                           "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2098                           &pDirEntry->NameInformation.FileName,
2099                           pDirEntry,
2100                           lCount);
2101
2102             ASSERT( lCount >= 0);
2103         }
2104
2105         if( !NT_SUCCESS( ntStatus))
2106         {
2107
2108             if( bFileCreated)
2109             {
2110
2111                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2112                               AFS_TRACE_LEVEL_VERBOSE,
2113                               "AFSProcessCreate Create failed, removing DE %p from parent object %p Status %08lX\n",
2114                               pDirEntry,
2115                               pParentObjectInfo,
2116                               ntStatus);
2117
2118                 //
2119                 // Remove the dir entry from the parent
2120                 //
2121
2122                 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2123                                 TRUE);
2124
2125                 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2126
2127                 AFSNotifyDelete( pDirEntry,
2128                                  AuthGroup,
2129                                  FALSE);
2130
2131                 //
2132                 // Pull the directory entry from the parent
2133                 //
2134
2135                 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2136                                             pDirEntry,
2137                                             FALSE); // Leave it in the enum list so the worker cleans it up
2138
2139                 //
2140                 // Tag the parent as needing verification
2141                 //
2142
2143                 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2144
2145                 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2146
2147                 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2148             }
2149
2150             if( bAllocatedCcb)
2151             {
2152
2153                 AFSRemoveCcb( NULL,
2154                               *Ccb);
2155             }
2156
2157             //
2158             // Fcb will be freed by AFSPrimaryVolumeWorker thread
2159             //
2160
2161             *Fcb = NULL;
2162
2163             *Ccb = NULL;
2164         }
2165     }
2166
2167     return ntStatus;
2168 }
2169
2170 NTSTATUS
2171 AFSOpenTargetDirectory( IN PIRP Irp,
2172                         IN AFSVolumeCB *VolumeCB,
2173                         IN AFSDirectoryCB *ParentDirectoryCB,
2174                         IN AFSDirectoryCB *TargetDirectoryCB,
2175                         IN UNICODE_STRING *TargetName,
2176                         OUT AFSFcb **Fcb,
2177                         OUT AFSCcb **Ccb)
2178 {
2179     UNREFERENCED_PARAMETER(VolumeCB);
2180     NTSTATUS ntStatus = STATUS_SUCCESS;
2181     PFILE_OBJECT pFileObject = NULL;
2182     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2183     PACCESS_MASK pDesiredAccess = NULL;
2184     USHORT usShareAccess;
2185     BOOLEAN bAllocatedCcb = FALSE;
2186     BOOLEAN bReleaseFcb = FALSE;
2187     AFSObjectInfoCB *pParentObject = NULL;
2188     AFSObjectInfoCB *pGrandParentObject = NULL;
2189     UNICODE_STRING uniTargetName;
2190     LONG lCount;
2191
2192     __Enter
2193     {
2194
2195         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2196         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2197
2198         pFileObject = pIrpSp->FileObject;
2199
2200         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2201                       AFS_TRACE_LEVEL_VERBOSE,
2202                       "AFSOpenTargetDirectory (%p) Processing file %wZ\n",
2203                       Irp,
2204                       TargetName);
2205
2206         pParentObject = ParentDirectoryCB->ObjectInformation;
2207
2208         if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2209         {
2210
2211             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2212         }
2213
2214         //
2215         // Make sure we have an Fcb for the access
2216
2217         //
2218         // Allocate and initialize the Fcb for the file.
2219         //
2220
2221         ntStatus = AFSInitFcb( ParentDirectoryCB);
2222
2223         *Fcb = pParentObject->Fcb;
2224
2225         if( !NT_SUCCESS( ntStatus))
2226         {
2227
2228             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2229                           AFS_TRACE_LEVEL_ERROR,
2230                           "AFSOpenTargetDirectory (%p) Failed to initialize fcb %wZ Status %08lX\n",
2231                           Irp,
2232                           &ParentDirectoryCB->NameInformation.FileName,
2233                           ntStatus);
2234
2235             try_return( ntStatus);
2236         }
2237
2238         ntStatus = STATUS_SUCCESS;
2239
2240         //
2241         // Increment the open count on this Fcb
2242         //
2243
2244         lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2245
2246         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2247                       AFS_TRACE_LEVEL_VERBOSE,
2248                       "AFSOpenTargetDirectory Increment count on Fcb %p Cnt %d\n",
2249                       pParentObject->Fcb,
2250                       lCount);
2251
2252         bReleaseFcb = TRUE;
2253
2254         //
2255         // If there are current opens on the Fcb, check the access.
2256         //
2257
2258         if( pParentObject->Fcb->OpenHandleCount > 0)
2259         {
2260
2261             ntStatus = IoCheckShareAccess( *pDesiredAccess,
2262                                            usShareAccess,
2263                                            pFileObject,
2264                                            &pParentObject->Fcb->ShareAccess,
2265                                            FALSE);
2266
2267             if( !NT_SUCCESS( ntStatus))
2268             {
2269
2270                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2271                               AFS_TRACE_LEVEL_ERROR,
2272                               "AFSOpenTargetDirectory (%p) Access check failure %wZ Status %08lX\n",
2273                               Irp,
2274                               &ParentDirectoryCB->NameInformation.FileName,
2275                               ntStatus);
2276
2277                 try_return( ntStatus);
2278             }
2279         }
2280
2281         //
2282         // Initialize the Ccb for the file.
2283         //
2284
2285         ntStatus = AFSInitCcb( Ccb,
2286                                ParentDirectoryCB,
2287                                *pDesiredAccess,
2288                                0);
2289
2290         if( !NT_SUCCESS( ntStatus))
2291         {
2292
2293             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2294                           AFS_TRACE_LEVEL_ERROR,
2295                           "AFSOpenTargetDirectory (%p) Failed to initialize ccb %wZ Status %08lX\n",
2296                           Irp,
2297                           &ParentDirectoryCB->NameInformation.FileName,
2298                           ntStatus);
2299
2300             try_return( ntStatus);
2301         }
2302
2303         bAllocatedCcb = TRUE;
2304
2305         if( TargetDirectoryCB != NULL &&
2306             FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2307                                 TargetName,
2308                                 FALSE,
2309                                 NULL))
2310         {
2311
2312             Irp->IoStatus.Information = FILE_EXISTS;
2313
2314             uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2315         }
2316         else
2317         {
2318
2319             Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2320
2321             uniTargetName = *TargetName;
2322         }
2323
2324         //
2325         // Update the filename in the fileobject for rename processing
2326         //
2327
2328         RtlCopyMemory( pFileObject->FileName.Buffer,
2329                        uniTargetName.Buffer,
2330                        uniTargetName.Length);
2331
2332         pFileObject->FileName.Length = uniTargetName.Length;
2333
2334         //
2335         // OK, update the share access on the fileobject
2336         //
2337
2338         if( pParentObject->Fcb->OpenHandleCount > 0)
2339         {
2340
2341             IoUpdateShareAccess( pFileObject,
2342                                  &pParentObject->Fcb->ShareAccess);
2343         }
2344         else
2345         {
2346
2347             //
2348             // Set the access
2349             //
2350
2351             IoSetShareAccess( *pDesiredAccess,
2352                               usShareAccess,
2353                               pFileObject,
2354                               &pParentObject->Fcb->ShareAccess);
2355         }
2356
2357         lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2358
2359         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2360                       AFS_TRACE_LEVEL_VERBOSE,
2361                       "AFSOpenTargetDirectory Increment handle count on Fcb %p Cnt %d\n",
2362                       pParentObject->Fcb,
2363                       lCount);
2364
2365         //
2366         // Increment the open reference and handle on the parent node
2367         //
2368
2369         if( BooleanFlagOn( pParentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2370         {
2371
2372             pGrandParentObject = AFSFindObjectInfo( pParentObject->VolumeCB,
2373                                                     &pParentObject->ParentFileId);
2374
2375             if ( pGrandParentObject)
2376             {
2377
2378                 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenHandleCount);
2379
2380                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2381                               AFS_TRACE_LEVEL_VERBOSE,
2382                               "AFSOpenTargetDirectory Increment child open handle count on Parent object %p Cnt %d\n",
2383                               pGrandParentObject,
2384                               lCount);
2385
2386                 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenReferenceCount);
2387
2388                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2389                               AFS_TRACE_LEVEL_VERBOSE,
2390                               "AFSOpenTargetDirectory Increment child open ref count on Parent object %p Cnt %d\n",
2391                               pGrandParentObject,
2392                               lCount);
2393
2394                 AFSReleaseObjectInfo( &pGrandParentObject);
2395             }
2396         }
2397
2398 try_exit:
2399
2400         if( bReleaseFcb)
2401         {
2402
2403             if( !NT_SUCCESS( ntStatus))
2404             {
2405                 //
2406                 // Decrement the open count on this Fcb
2407                 //
2408
2409                 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2410
2411                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2412                               AFS_TRACE_LEVEL_VERBOSE,
2413                               "AFSOpenTargetDirectory Decrement count on Fcb %p Cnt %d\n",
2414                               pParentObject->Fcb,
2415                               lCount);
2416             }
2417
2418             AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2419         }
2420
2421         if( !NT_SUCCESS( ntStatus))
2422         {
2423
2424             if( bAllocatedCcb)
2425             {
2426
2427                 AFSRemoveCcb( NULL,
2428                               *Ccb);
2429             }
2430
2431             *Ccb = NULL;
2432
2433             //
2434             // Fcb will be freed by AFSPrimaryVolumeWorker thread
2435             //
2436
2437             *Fcb = NULL;
2438         }
2439     }
2440
2441     return ntStatus;
2442 }
2443
2444 NTSTATUS
2445 AFSProcessOpen( IN PIRP Irp,
2446                 IN GUID *AuthGroup,
2447                 IN AFSVolumeCB *VolumeCB,
2448                 IN AFSDirectoryCB *ParentDirCB,
2449                 IN AFSDirectoryCB *DirectoryCB,
2450                 OUT AFSFcb **Fcb,
2451                 OUT AFSCcb **Ccb)
2452 {
2453     UNREFERENCED_PARAMETER(VolumeCB);
2454     NTSTATUS ntStatus = STATUS_SUCCESS;
2455     PFILE_OBJECT pFileObject = NULL;
2456     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2457     PACCESS_MASK pDesiredAccess = NULL;
2458     USHORT usShareAccess;
2459     BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE;
2460     ULONG ulOptions = 0;
2461     AFSFileOpenCB   stOpenCB;
2462     AFSFileOpenResultCB stOpenResultCB;
2463     ULONG       ulResultLen = 0;
2464     AFSObjectInfoCB *pParentObjectInfo = NULL;
2465     AFSObjectInfoCB *pObjectInfo = NULL;
2466     ULONG       ulFileAccess = 0;
2467     AFSFileAccessReleaseCB stReleaseFileAccess;
2468     LONG lCount;
2469
2470     __Enter
2471     {
2472
2473         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2474         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2475
2476         pFileObject = pIrpSp->FileObject;
2477
2478         pParentObjectInfo = ParentDirCB->ObjectInformation;
2479
2480         pObjectInfo = DirectoryCB->ObjectInformation;
2481
2482         ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2483                 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
2484
2485         //
2486         // Check if the entry is pending a deletion
2487         //
2488
2489         if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2490         {
2491
2492             ntStatus = STATUS_DELETE_PENDING;
2493
2494             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2495                           AFS_TRACE_LEVEL_ERROR,
2496                           "AFSProcessOpen (%p) Entry pending delete %wZ Status %08lX\n",
2497                           Irp,
2498                           &DirectoryCB->NameInformation.FileName,
2499                           ntStatus);
2500
2501             try_return( ntStatus);
2502         }
2503
2504         //
2505         // Extract out the options
2506         //
2507
2508         ulOptions = pIrpSp->Parameters.Create.Options;
2509
2510         //
2511         // Check if we should go and retrieve updated information for the node
2512         //
2513
2514         ntStatus = AFSValidateEntry( DirectoryCB,
2515                                      AuthGroup,
2516                                      FALSE,
2517                                      TRUE);
2518
2519         if( !NT_SUCCESS( ntStatus))
2520         {
2521
2522             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2523                           AFS_TRACE_LEVEL_ERROR,
2524                           "AFSProcessOpen (%p) Failed to validate entry %wZ Status %08lX\n",
2525                           Irp,
2526                           &DirectoryCB->NameInformation.FileName,
2527                           ntStatus);
2528
2529             try_return( ntStatus);
2530         }
2531
2532         //
2533         // If this is marked for delete on close then be sure we can delete the entry
2534         //
2535
2536         if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2537         {
2538
2539             ntStatus = AFSNotifyDelete( DirectoryCB,
2540                                         AuthGroup,
2541                                         TRUE);
2542
2543             if( !NT_SUCCESS( ntStatus))
2544             {
2545
2546                 ntStatus = STATUS_CANNOT_DELETE;
2547
2548                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2549                               AFS_TRACE_LEVEL_ERROR,
2550                               "AFSProcessOpen (%p) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2551                               Irp,
2552                               &DirectoryCB->NameInformation.FileName,
2553                               ntStatus);
2554
2555                 try_return( ntStatus);
2556             }
2557         }
2558
2559         //
2560         // Be sure we have an Fcb for the current object
2561         //
2562
2563         ntStatus = AFSInitFcb( DirectoryCB);
2564
2565         if( !NT_SUCCESS( ntStatus))
2566         {
2567
2568             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2569                           AFS_TRACE_LEVEL_ERROR,
2570                           "AFSProcessOpen (%p) Failed to init fcb on %wZ Status %08lX\n",
2571                           Irp,
2572                           &DirectoryCB->NameInformation.FileName,
2573                           ntStatus);
2574
2575             try_return( ntStatus);
2576         }
2577
2578         ntStatus = STATUS_SUCCESS;
2579
2580         //
2581         // AFSInitFcb returns the Fcb resource held
2582         //
2583
2584         bReleaseFcb = TRUE;
2585
2586         //
2587         // Increment the open count on this Fcb
2588         //
2589
2590         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2591
2592         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2593                       AFS_TRACE_LEVEL_VERBOSE,
2594                       "AFSProcessOpen Increment2 count on Fcb %p Cnt %d\n",
2595                       pObjectInfo->Fcb,
2596                       lCount);
2597
2598         //
2599         // Check access on the entry
2600         //
2601
2602         if( pObjectInfo->Fcb->OpenHandleCount > 0)
2603         {
2604
2605             ntStatus = IoCheckShareAccess( *pDesiredAccess,
2606                                            usShareAccess,
2607                                            pFileObject,
2608                                            &pObjectInfo->Fcb->ShareAccess,
2609                                            FALSE);
2610
2611             if( !NT_SUCCESS( ntStatus))
2612             {
2613
2614                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2615                               AFS_TRACE_LEVEL_ERROR,
2616                               "AFSProcessOpen (%p) Failed to check share access on %wZ Status %08lX\n",
2617                               Irp,
2618                               &DirectoryCB->NameInformation.FileName,
2619                               ntStatus);
2620
2621                 try_return( ntStatus);
2622             }
2623         }
2624
2625         //
2626         // Additional checks
2627         //
2628
2629         if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2630         {
2631
2632             //
2633             // If the caller is asking for write access then try to flush the image section
2634             //
2635
2636             if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2637                 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2638             {
2639
2640                 BOOLEAN bMmFlushed;
2641
2642                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2643                               AFS_TRACE_LEVEL_VERBOSE,
2644                               "AFSProcessOpen Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2645                               &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2646                               PsGetCurrentThread());
2647
2648                 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2649                                 TRUE);
2650
2651                 bMmFlushed = MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2652                                                   MmFlushForWrite);
2653
2654                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2655                               AFS_TRACE_LEVEL_VERBOSE,
2656                               "AFSProcessOpen Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2657                               &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2658                               PsGetCurrentThread());
2659
2660                 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
2661
2662                 if ( !bMmFlushed)
2663                 {
2664
2665                     ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2666                                                                             STATUS_SHARING_VIOLATION;
2667
2668                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2669                                   AFS_TRACE_LEVEL_ERROR,
2670                                   "AFSProcessOpen (%p) Failed to flush image section %wZ Status %08lX\n",
2671                                   Irp,
2672                                   &DirectoryCB->NameInformation.FileName,
2673                                   ntStatus);
2674
2675                     try_return( ntStatus);
2676                 }
2677             }
2678
2679             if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2680             {
2681
2682                 ntStatus = STATUS_NOT_A_DIRECTORY;
2683
2684                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2685                               AFS_TRACE_LEVEL_ERROR,
2686                               "AFSProcessOpen (%p) Attempt to open file as directory %wZ Status %08lX\n",
2687                               Irp,
2688                               &DirectoryCB->NameInformation.FileName,
2689                               ntStatus);
2690
2691                 try_return( ntStatus);
2692             }
2693
2694             pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2695         }
2696         else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2697                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2698         {
2699
2700             if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2701             {
2702
2703                 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2704
2705                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2706                               AFS_TRACE_LEVEL_ERROR,
2707                               "AFSProcessOpen (%p) Attempt to open directory as file %wZ Status %08lX\n",
2708                               Irp,
2709                               &DirectoryCB->NameInformation.FileName,
2710                               ntStatus);
2711
2712                 try_return( ntStatus);
2713             }
2714         }
2715         else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2716                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2717                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2718                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2719         {
2720
2721         }
2722         else
2723         {
2724             ASSERT( FALSE);
2725             try_return( ntStatus = STATUS_UNSUCCESSFUL);
2726         }
2727
2728         //
2729         // Check with the service that we can open the file
2730         //
2731
2732         stOpenCB.ParentId = pParentObjectInfo->FileId;
2733
2734         stOpenCB.DesiredAccess = *pDesiredAccess;
2735
2736         stOpenCB.ShareAccess = usShareAccess;
2737
2738         stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2739
2740         stOpenCB.Identifier = (ULONGLONG)pFileObject;
2741
2742         stOpenResultCB.GrantedAccess = 0;
2743
2744         ulResultLen = sizeof( AFSFileOpenResultCB);
2745
2746         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2747                                       AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2748                                       AuthGroup,
2749                                       &DirectoryCB->NameInformation.FileName,
2750                                       &pObjectInfo->FileId,
2751                                       (void *)&stOpenCB,
2752                                       sizeof( AFSFileOpenCB),
2753                                       (void *)&stOpenResultCB,
2754                                       &ulResultLen);
2755
2756         if( !NT_SUCCESS( ntStatus))
2757         {
2758
2759             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2760                           AFS_TRACE_LEVEL_ERROR,
2761                           "AFSProcessOpen (%p) Failed open in service %wZ Status %08lX\n",
2762                           Irp,
2763                           &DirectoryCB->NameInformation.FileName,
2764                           ntStatus);
2765
2766             try_return( ntStatus);
2767         }
2768
2769         //
2770         // Save the granted access in case we need to release it below
2771         //
2772
2773         ulFileAccess = stOpenResultCB.FileAccess;
2774
2775         //
2776         // Check if there is a conflict
2777         //
2778
2779         if( !AFSCheckAccess( *pDesiredAccess,
2780                              stOpenResultCB.GrantedAccess,
2781                              BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2782         {
2783
2784             ntStatus = STATUS_ACCESS_DENIED;
2785
2786             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2787                           AFS_TRACE_LEVEL_ERROR,
2788                           "AFSProcessOpen (%p) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2789                           Irp,
2790                           *pDesiredAccess,
2791                           stOpenResultCB.GrantedAccess,
2792                           &DirectoryCB->NameInformation.FileName,
2793                           ntStatus);
2794
2795             try_return( ntStatus);
2796         }
2797
2798         //
2799         // Initialize the Ccb for the file.
2800         //
2801
2802         ntStatus = AFSInitCcb( Ccb,
2803                                DirectoryCB,
2804                                *pDesiredAccess,
2805                                ulFileAccess);
2806
2807         if( !NT_SUCCESS( ntStatus))
2808         {
2809
2810             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2811                           AFS_TRACE_LEVEL_ERROR,
2812                           "AFSProcessOpen (%p) Failed to initialize ccb %wZ Status %08lX\n",
2813                           Irp,
2814                           &DirectoryCB->NameInformation.FileName,
2815                           ntStatus);
2816
2817             try_return( ntStatus);
2818         }
2819
2820         bAllocatedCcb = TRUE;
2821
2822         //
2823         // Perform the access check on the target if this is a mount point or symlink
2824         //
2825
2826         if( pObjectInfo->Fcb->OpenHandleCount > 0)
2827         {
2828
2829             IoUpdateShareAccess( pFileObject,
2830                                  &pObjectInfo->Fcb->ShareAccess);
2831         }
2832         else
2833         {
2834
2835             //
2836             // Set the access
2837             //
2838
2839             IoSetShareAccess( *pDesiredAccess,
2840                               usShareAccess,
2841                               pFileObject,
2842                               &pObjectInfo->Fcb->ShareAccess);
2843         }
2844
2845         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2846
2847         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2848                       AFS_TRACE_LEVEL_VERBOSE,
2849                       "AFSProcessOpen Increment handle count on Fcb %p Cnt %d\n",
2850                       pObjectInfo->Fcb,
2851                       lCount);
2852
2853         //
2854         // Increment the open reference and handle on the parent node
2855         //
2856
2857         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2858
2859         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2860                       AFS_TRACE_LEVEL_VERBOSE,
2861                       "AFSProcessOpen Increment child open handle count on Parent object %p Cnt %d\n",
2862                       pParentObjectInfo,
2863                       lCount);
2864
2865         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2866
2867         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2868                       AFS_TRACE_LEVEL_VERBOSE,
2869                       "AFSProcessOpen Increment child open ref count on Parent object %p Cnt %d\n",
2870                       pParentObjectInfo,
2871                       lCount);
2872
2873         if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2874         {
2875
2876             //
2877             // Mark it for delete on close
2878             //
2879
2880             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2881                           AFS_TRACE_LEVEL_VERBOSE,
2882                           "AFSProcessOpen (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2883                           Irp,
2884                           DirectoryCB,
2885                           &DirectoryCB->NameInformation.FileName);
2886
2887             SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2888         }
2889
2890         //
2891         // Indicate the object is held
2892         //
2893
2894         SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2895
2896         //
2897         // Return the open result for this file
2898         //
2899
2900         Irp->IoStatus.Information = FILE_OPENED;
2901
2902         *Fcb = pObjectInfo->Fcb;
2903
2904 try_exit:
2905
2906         if( bReleaseFcb)
2907         {
2908
2909             if( !NT_SUCCESS( ntStatus))
2910             {
2911                 //
2912                 // Decrement the open count on this Fcb
2913                 //
2914
2915                 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2916
2917                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2918                               AFS_TRACE_LEVEL_VERBOSE,
2919                               "AFSProcessOpen Decrement2 count on Fcb %p Cnt %d\n",
2920                               pObjectInfo->Fcb,
2921                               lCount);
2922             }
2923
2924             AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2925         }
2926
2927         if( !NT_SUCCESS( ntStatus))
2928         {
2929
2930             if ( ulFileAccess > 0)
2931             {
2932
2933                 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2934
2935                 stReleaseFileAccess.FileAccess = ulFileAccess;
2936
2937                 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2938
2939                 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2940                                    AFS_REQUEST_FLAG_SYNCHRONOUS,
2941                                    AuthGroup,
2942                                    &DirectoryCB->NameInformation.FileName,
2943                                    &pObjectInfo->FileId,
2944                                    (void *)&stReleaseFileAccess,
2945                                    sizeof( AFSFileAccessReleaseCB),
2946                                    NULL,
2947                                    NULL);
2948             }
2949
2950             if( bAllocatedCcb)
2951             {
2952
2953                 AFSRemoveCcb( NULL,
2954                               *Ccb);
2955             }
2956
2957             *Ccb = NULL;
2958
2959             //
2960             // Fcb will be freed by AFSPrimaryVolumeWorker thread
2961             //
2962
2963             *Fcb = NULL;
2964         }
2965     }
2966
2967     return ntStatus;
2968 }
2969
2970 NTSTATUS
2971 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
2972                               IN PIRP           Irp,
2973                               IN AFSVolumeCB   *VolumeCB,
2974                               IN GUID          *AuthGroup,
2975                               IN AFSDirectoryCB *ParentDirCB,
2976                               IN AFSDirectoryCB *DirectoryCB,
2977                               OUT AFSFcb       **Fcb,
2978                               OUT AFSCcb       **Ccb)
2979 {
2980     UNREFERENCED_PARAMETER(DeviceObject);
2981     NTSTATUS ntStatus = STATUS_SUCCESS;
2982     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2983     PFILE_OBJECT pFileObject = NULL;
2984     LARGE_INTEGER liZero = {0,0};
2985     BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
2986     ULONG   ulAttributes = 0;
2987     ULONG ulCreateDisposition = 0;
2988     BOOLEAN bAllocatedCcb = FALSE;
2989     BOOLEAN bUserMapped = FALSE;
2990     PACCESS_MASK pDesiredAccess = NULL;
2991     USHORT usShareAccess;
2992     AFSObjectInfoCB *pParentObjectInfo = NULL;
2993     AFSObjectInfoCB *pObjectInfo = NULL;
2994     LONG lCount;
2995     LARGE_INTEGER liSaveSize;
2996     LARGE_INTEGER liSaveVDL;
2997     LARGE_INTEGER liSaveAlloc;
2998
2999     __Enter
3000     {
3001
3002         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3003
3004         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
3005
3006         pFileObject = pIrpSp->FileObject;
3007
3008         ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
3009
3010         ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
3011
3012         if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
3013         {
3014
3015             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3016                           AFS_TRACE_LEVEL_ERROR,
3017                           "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3018                           Irp,
3019                           &DirectoryCB->NameInformation.FileName);
3020
3021             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3022         }
3023
3024         pParentObjectInfo = ParentDirCB->ObjectInformation;
3025
3026         pObjectInfo = DirectoryCB->ObjectInformation;
3027
3028         ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3029                 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
3030
3031         //
3032         // Check if we should go and retrieve updated information for the node
3033         //
3034
3035         ntStatus = AFSValidateEntry( DirectoryCB,
3036                                      AuthGroup,
3037                                      FALSE,
3038                                      TRUE);
3039
3040         if( !NT_SUCCESS( ntStatus))
3041         {
3042
3043             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3044                           AFS_TRACE_LEVEL_ERROR,
3045                           "AFSProcessOverwriteSupersede (%p) Failed to validate entry %wZ Status %08lX\n",
3046                           Irp,
3047                           &DirectoryCB->NameInformation.FileName,
3048                           ntStatus);
3049
3050             try_return( ntStatus);
3051         }
3052
3053         //
3054         // Be sure we have an Fcb for the object block
3055         //
3056
3057         ntStatus = AFSInitFcb( DirectoryCB);
3058
3059         *Fcb = pObjectInfo->Fcb;
3060
3061         if( !NT_SUCCESS( ntStatus))
3062         {
3063
3064             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3065                           AFS_TRACE_LEVEL_ERROR,
3066                           "AFSProcessOverwriteSupersede (%p) Failed to initialize fcb %wZ Status %08lX\n",
3067                           Irp,
3068                           &DirectoryCB->NameInformation.FileName,
3069                           ntStatus);
3070
3071             try_return( ntStatus);
3072         }
3073
3074         ntStatus = STATUS_SUCCESS;
3075
3076         //
3077         // Increment the open count on this Fcb.
3078         //
3079
3080         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3081
3082         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3083                       AFS_TRACE_LEVEL_VERBOSE,
3084                       "AFSProcessOverwriteSupersede Increment2 count on Fcb %p Cnt %d\n",
3085                       pObjectInfo->Fcb,
3086                       lCount);
3087
3088         bReleaseFcb = TRUE;
3089
3090         //
3091         // Check access on the entry
3092         //
3093
3094         if( pObjectInfo->Fcb->OpenHandleCount > 0)
3095         {
3096
3097             ntStatus = IoCheckShareAccess( *pDesiredAccess,
3098                                            usShareAccess,
3099                                            pFileObject,
3100                                            &pObjectInfo->Fcb->ShareAccess,
3101                                            FALSE);
3102
3103             if( !NT_SUCCESS( ntStatus))
3104             {
3105
3106                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3107                               AFS_TRACE_LEVEL_ERROR,
3108                               "AFSProcessOverwriteSupersede (%p) Access check failure %wZ Status %08lX\n",
3109                               Irp,
3110                               &DirectoryCB->NameInformation.FileName,
3111                               ntStatus);
3112
3113                 try_return( ntStatus);
3114             }
3115         }
3116
3117         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3118                       AFS_TRACE_LEVEL_VERBOSE,
3119                       "AFSProcessOverwriteSupercede Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3120                       &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3121                       PsGetCurrentThread());
3122
3123         AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3124                         TRUE);
3125
3126         //
3127         //  Before we actually truncate, check to see if the purge
3128         //  is going to fail.
3129         //
3130
3131         bUserMapped = !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3132                                              &liZero);
3133
3134         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3135                       AFS_TRACE_LEVEL_VERBOSE,
3136                       "AFSProcessOverwriteSupercede Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3137                       &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3138                       PsGetCurrentThread());
3139
3140         AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3141
3142         if( bUserMapped)
3143         {
3144
3145             ntStatus = STATUS_USER_MAPPED_FILE;
3146
3147             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3148                           AFS_TRACE_LEVEL_ERROR,
3149                           "AFSProcessOverwriteSupersede (%p) File user mapped %wZ Status %08lX\n",
3150                           Irp,
3151                           &DirectoryCB->NameInformation.FileName,
3152                           ntStatus);
3153
3154             try_return( ntStatus);
3155         }
3156
3157         //
3158         // Initialize the Ccb for the file.
3159         //
3160
3161         ntStatus = AFSInitCcb( Ccb,
3162                                DirectoryCB,
3163                                *pDesiredAccess,
3164                                0);
3165
3166         if( !NT_SUCCESS( ntStatus))
3167         {
3168
3169             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3170                           AFS_TRACE_LEVEL_ERROR,
3171                           "AFSProcessOverwriteSupersede (%p) Failed to initialize ccb %wZ Status %08lX\n",
3172                           Irp,
3173                           &DirectoryCB->NameInformation.FileName,
3174                           ntStatus);
3175
3176             try_return( ntStatus);
3177         }
3178
3179         bAllocatedCcb = TRUE;
3180
3181         //
3182         // Set the file length to zero
3183         //
3184
3185         AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3186                         TRUE);
3187
3188         bReleasePaging = TRUE;
3189
3190         liSaveSize = pObjectInfo->Fcb->Header.FileSize;
3191         liSaveAlloc = pObjectInfo->Fcb->Header.AllocationSize;
3192         liSaveVDL = pObjectInfo->Fcb->Header.ValidDataLength;
3193
3194         pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3195         pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3196         pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3197
3198         pObjectInfo->EndOfFile.QuadPart = 0;
3199         pObjectInfo->AllocationSize.QuadPart = 0;
3200
3201         //
3202         // Trim down the extents. We do this BEFORE telling the service
3203         // the file is truncated since there is a potential race between
3204         // a worker thread releasing extents and us trimming
3205         //
3206
3207         AFSTrimExtents( pObjectInfo->Fcb,
3208                         &pObjectInfo->Fcb->Header.FileSize);
3209
3210         KeQuerySystemTime( &pObjectInfo->ChangeTime);
3211
3212         KeQuerySystemTime( &pObjectInfo->LastAccessTime);
3213
3214         KeQuerySystemTime( &pObjectInfo->LastWriteTime);
3215
3216         //
3217         // Set the update flag accordingly
3218         //
3219
3220         SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
3221                                           AFS_FCB_FLAG_UPDATE_CREATE_TIME |
3222                                           AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
3223                                           AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
3224                                           AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
3225
3226         ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
3227                                              pObjectInfo,
3228                                              AuthGroup);
3229
3230         if( !NT_SUCCESS( ntStatus))
3231         {
3232
3233             pObjectInfo->Fcb->Header.ValidDataLength = liSaveVDL;
3234             pObjectInfo->Fcb->Header.FileSize = liSaveSize;
3235             pObjectInfo->Fcb->Header.AllocationSize = liSaveAlloc;
3236             pObjectInfo->Fcb->ObjectInformation->EndOfFile = liSaveSize;
3237             pObjectInfo->Fcb->ObjectInformation->AllocationSize = liSaveAlloc;
3238
3239             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3240                           AFS_TRACE_LEVEL_ERROR,
3241                           "AFSProcessOverwriteSupersede (%p) Failed to update file information %wZ Status %08lX\n",
3242                           Irp,
3243                           &DirectoryCB->NameInformation.FileName,
3244                           ntStatus);
3245
3246             try_return( ntStatus);
3247         }
3248
3249         ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
3250
3251         if( ulCreateDisposition == FILE_SUPERSEDE)
3252         {
3253
3254             pObjectInfo->FileAttributes = ulAttributes;
3255
3256         }
3257         else
3258         {
3259
3260             pObjectInfo->FileAttributes |= ulAttributes;
3261         }
3262
3263         //
3264         // Save off the access for the open
3265         //
3266
3267         if( pObjectInfo->Fcb->OpenHandleCount > 0)
3268         {
3269
3270             IoUpdateShareAccess( pFileObject,
3271                                  &pObjectInfo->Fcb->ShareAccess);
3272         }
3273         else
3274         {
3275
3276             //
3277             // Set the access
3278             //
3279
3280             IoSetShareAccess( *pDesiredAccess,
3281                               usShareAccess,
3282                               pFileObject,
3283                               &pObjectInfo->Fcb->ShareAccess);
3284         }
3285
3286         //
3287         // Return the correct action
3288         //
3289
3290         if( ulCreateDisposition == FILE_SUPERSEDE)
3291         {
3292
3293             Irp->IoStatus.Information = FILE_SUPERSEDED;
3294         }
3295         else
3296         {
3297
3298             Irp->IoStatus.Information = FILE_OVERWRITTEN;
3299         }
3300
3301         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
3302
3303         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3304                       AFS_TRACE_LEVEL_VERBOSE,
3305                       "AFSProcessOverwriteSupersede Increment handle count on Fcb %p Cnt %d\n",
3306                       pObjectInfo->Fcb,
3307                       lCount);
3308
3309         //
3310         // Increment the open reference and handle on the parent node
3311         //
3312
3313         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3314
3315         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3316                       AFS_TRACE_LEVEL_VERBOSE,
3317                       "AFSProcessOverwriteSupersede Increment child open handle count on Parent object %p Cnt %d\n",
3318                       pParentObjectInfo,
3319                       lCount);
3320
3321         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3322
3323         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3324                       AFS_TRACE_LEVEL_VERBOSE,
3325                       "AFSProcessOverwriteSupersede Increment child open ref count on Parent object %p Cnt %d\n",
3326                       pParentObjectInfo,
3327                       lCount);
3328
3329         AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3330
3331         bReleaseFcb = FALSE;
3332
3333         *Fcb = pObjectInfo->Fcb;
3334
3335         //
3336         // Now that the Fcb->Resource has been dropped
3337         // we can call CcSetFileSizes.  We are still holding
3338         // the PagingIoResource
3339         //
3340
3341         pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
3342
3343         pFileObject->FsContext = (void *)pObjectInfo->Fcb;
3344
3345         pFileObject->FsContext2 = (void *)*Ccb;
3346
3347         CcSetFileSizes( pFileObject,
3348                         (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3349
3350 try_exit:
3351
3352         if( bReleasePaging)
3353         {
3354
3355             AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3356         }
3357
3358         if( bReleaseFcb)
3359         {
3360
3361             if( !NT_SUCCESS( ntStatus))
3362             {
3363                 //
3364                 // Decrement the open count on this Fcb.
3365                 //
3366
3367                 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
3368
3369                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3370                               AFS_TRACE_LEVEL_VERBOSE,
3371                               "AFSProcessOverwriteSupersede Decrement2 count on Fcb %p Cnt %d\n",
3372                               pObjectInfo->Fcb,
3373                               lCount);
3374             }
3375
3376             AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3377         }
3378
3379         if( !NT_SUCCESS( ntStatus))
3380         {
3381
3382             if( bAllocatedCcb)
3383             {
3384
3385                 AFSRemoveCcb( NULL,
3386                               *Ccb);
3387             }
3388
3389             *Ccb = NULL;
3390
3391             //
3392             // Fcb will be freed by AFSPrimaryVolumeWorker thread
3393             //
3394
3395             *Fcb = NULL;
3396         }
3397     }
3398
3399     return ntStatus;
3400 }
3401
3402 NTSTATUS
3403 AFSControlDeviceCreate( IN PIRP Irp)
3404 {
3405
3406     NTSTATUS ntStatus = STATUS_SUCCESS;
3407
3408     __Enter
3409     {
3410
3411         if ( KernelMode == Irp->RequestorMode) {
3412             //
3413             // For now, just let the open happen
3414             //
3415             Irp->IoStatus.Information = FILE_OPENED;
3416         }
3417         else
3418         {
3419             //
3420             // Not from usermode, All access must be via
3421             // the FS component (which will do the
3422             // security check)
3423             //
3424             ntStatus = STATUS_ACCESS_DENIED;
3425         }
3426     }
3427
3428     return ntStatus;
3429 }
3430
3431 //
3432 // AFSOpenIOCtlFcb does not release a DirOpenReferenceCount on
3433 // the ParentDirCB.
3434 //
3435
3436 NTSTATUS
3437 AFSOpenIOCtlFcb( IN PIRP Irp,
3438                  IN GUID *AuthGroup,
3439                  IN AFSDirectoryCB *ParentDirCB,
3440                  OUT AFSFcb **Fcb,
3441                  OUT AFSCcb **Ccb)
3442 {
3443
3444     NTSTATUS ntStatus = STATUS_SUCCESS;
3445     PFILE_OBJECT pFileObject = NULL;
3446     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3447     BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
3448     AFSPIOCtlOpenCloseRequestCB stPIOCtlOpen;
3449     AFSFileID stFileID;
3450     AFSObjectInfoCB *pParentObjectInfo = NULL;
3451     LONG lCount;
3452
3453     __Enter
3454     {
3455
3456         pFileObject = pIrpSp->FileObject;
3457
3458         pParentObjectInfo = ParentDirCB->ObjectInformation;
3459
3460         //
3461         // If we haven't initialized the PIOCtl DirectoryCB for this directory then do it now
3462         //
3463
3464         if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB == NULL)
3465         {
3466
3467             ntStatus = AFSInitPIOCtlDirectoryCB( pParentObjectInfo);
3468
3469             if( !NT_SUCCESS( ntStatus))
3470             {
3471
3472                 try_return( ntStatus);
3473             }
3474         }
3475
3476         //
3477         // Allocate and initialize the Fcb for the file.
3478         //
3479
3480         ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB);
3481
3482         *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
3483
3484         if( !NT_SUCCESS( ntStatus))
3485         {
3486
3487             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3488                           AFS_TRACE_LEVEL_ERROR,
3489                           "AFSOpenIOCtlFcb (%p) Failed to initialize fcb Status %08lX\n",
3490                           Irp,
3491                           ntStatus);
3492
3493             try_return( ntStatus);
3494         }
3495
3496         ntStatus = STATUS_SUCCESS;
3497
3498         //
3499         // Increment the open reference and handle on the node
3500         //
3501
3502         lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3503
3504         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3505                       AFS_TRACE_LEVEL_VERBOSE,
3506                       "AFSOpenIOCtlFcb Increment count on Fcb %p Cnt %d\n",
3507                       (*Fcb),
3508                       lCount);
3509
3510         bReleaseFcb = TRUE;
3511
3512         //
3513         // Initialize the Ccb for the file.
3514         //
3515
3516         ntStatus = AFSInitCcb( Ccb,
3517                                pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
3518                                0,
3519                                0);
3520
3521         if( !NT_SUCCESS( ntStatus))
3522         {
3523
3524             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3525                           AFS_TRACE_LEVEL_ERROR,
3526                           "AFSOpenIOCtlFcb (%p) Failed to initialize ccb Status %08lX\n",
3527                           Irp,
3528                           ntStatus);
3529
3530             try_return( ntStatus);
3531         }
3532
3533         bAllocatedCcb = TRUE;
3534
3535         //
3536         // Set the PIOCtl index
3537         //
3538
3539         (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3540
3541         RtlZeroMemory( &stPIOCtlOpen,
3542                        sizeof( AFSPIOCtlOpenCloseRequestCB));
3543
3544         stPIOCtlOpen.RequestId = (*Ccb)->RequestID;
3545
3546         stPIOCtlOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3547
3548         RtlZeroMemory( &stFileID,
3549                        sizeof( AFSFileID));
3550
3551         //
3552         // The parent directory FID of the node
3553         //
3554
3555         stFileID = pParentObjectInfo->FileId;
3556
3557         //
3558         // Issue the open request to the service
3559         //
3560
3561         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_OPEN,
3562                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
3563                                       AuthGroup,
3564                                       NULL,
3565                                       &stFileID,
3566                                       (void *)&stPIOCtlOpen,
3567                                       sizeof( AFSPIOCtlOpenCloseRequestCB),
3568                                       NULL,
3569                                       NULL);
3570
3571         if( !NT_SUCCESS( ntStatus))
3572         {
3573
3574             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3575                           AFS_TRACE_LEVEL_ERROR,
3576                           "AFSOpenIOCtlFcb (%p) Failed service open Status %08lX\n",
3577                           Irp,
3578                           ntStatus);
3579
3580             try_return( ntStatus);
3581         }
3582
3583         //
3584         // Increment the handle on the node
3585         //
3586
3587         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3588
3589         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3590                       AFS_TRACE_LEVEL_VERBOSE,
3591                       "AFSOpenIOCtlFcb Increment handle count on Fcb %p Cnt %d\n",
3592                       (*Fcb),
3593                       lCount);
3594
3595         //
3596         // Increment the open reference and handle on the parent node
3597         //
3598
3599         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3600
3601         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3602                       AFS_TRACE_LEVEL_VERBOSE,
3603                       "AFSOpenIOCtlFcb Increment child open handle count on Parent object %p Cnt %d\n",
3604                       pParentObjectInfo,
3605                       lCount);
3606
3607         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3608
3609         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3610                       AFS_TRACE_LEVEL_VERBOSE,
3611                       "AFSOpenIOCtlFcb Increment child open ref count on Parent object %p Cnt %d\n",
3612                       pParentObjectInfo,
3613                       lCount);
3614
3615         //
3616         // Return the open result for this file
3617         //
3618
3619         Irp->IoStatus.Information = FILE_OPENED;
3620
3621 try_exit:
3622
3623         //
3624         // If we created the Fcb we need to release the resources
3625         //
3626
3627         if( bReleaseFcb)
3628         {
3629
3630             if( !NT_SUCCESS( ntStatus))
3631             {
3632                 //
3633                 // Decrement the open reference and handle on the node
3634                 //
3635
3636                 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3637
3638                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3639                               AFS_TRACE_LEVEL_VERBOSE,
3640                               "AFSOpenIOCtlFcb Decrement count on Fcb %p Cnt %d\n",
3641                               (*Fcb),
3642                               lCount);
3643             }
3644
3645             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3646         }
3647
3648         if( !NT_SUCCESS( ntStatus))
3649         {
3650
3651             if( bAllocatedCcb)
3652             {
3653
3654                 AFSRemoveCcb( NULL,
3655                               *Ccb);
3656             }
3657
3658             *Ccb = NULL;
3659
3660             //
3661             // Fcb will be freed by AFSPrimaryVolumeWorker thread
3662             //
3663
3664             *Fcb = NULL;
3665         }
3666     }
3667
3668     return ntStatus;
3669 }
3670
3671 NTSTATUS
3672 AFSOpenSpecialShareFcb( IN PIRP Irp,
3673                         IN GUID *AuthGroup,
3674                         IN AFSDirectoryCB *DirectoryCB,
3675                         OUT AFSFcb **Fcb,
3676                         OUT AFSCcb **Ccb)
3677 {
3678
3679     NTSTATUS ntStatus = STATUS_SUCCESS;
3680     PFILE_OBJECT pFileObject = NULL;
3681     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3682     BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE, bAllocateFcb = FALSE;
3683     AFSObjectInfoCB *pObjectInfo = NULL;
3684     AFSObjectInfoCB *pParentObjectInfo = NULL;
3685     AFSPipeOpenCloseRequestCB stPipeOpen;
3686     LONG lCount;
3687
3688     __Enter
3689     {
3690
3691         pFileObject = pIrpSp->FileObject;
3692
3693         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3694                       AFS_TRACE_LEVEL_VERBOSE_2,
3695                       "AFSOpenSpecialShareFcb (%p) Processing Share %wZ open\n",
3696                       Irp,
3697                       &DirectoryCB->NameInformation.FileName);
3698
3699         pObjectInfo = DirectoryCB->ObjectInformation;
3700
3701         if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
3702         {
3703
3704             pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
3705                                                    &pObjectInfo->ParentFileId);
3706         }
3707
3708         if( DirectoryCB->ObjectInformation->Fcb == NULL)
3709         {
3710
3711             //
3712             // Allocate and initialize the Fcb for the file.
3713             //
3714
3715             ntStatus = AFSInitFcb( DirectoryCB);
3716
3717             *Fcb = pObjectInfo->Fcb;
3718
3719             if( !NT_SUCCESS( ntStatus))
3720             {
3721
3722                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3723                               AFS_TRACE_LEVEL_ERROR,
3724                               "AFSOpenSpecialShareFcb (%p) Failed to initialize fcb Status %08lX\n",
3725                               Irp,
3726                               ntStatus);
3727
3728                 try_return( ntStatus);
3729             }
3730
3731             if ( ntStatus != STATUS_REPARSE)
3732             {
3733
3734                 bAllocateFcb = TRUE;
3735             }
3736
3737             ntStatus = STATUS_SUCCESS;
3738         }
3739         else
3740         {
3741
3742             *Fcb = pObjectInfo->Fcb;
3743
3744             AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
3745                             TRUE);
3746         }
3747
3748         //
3749         // Increment the open count on this Fcb
3750         //
3751
3752         lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3753
3754         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3755                       AFS_TRACE_LEVEL_VERBOSE,
3756                       "AFSOpenSpecialShareFcb Increment count on Fcb %p Cnt %d\n",
3757                       (*Fcb),
3758                       lCount);
3759
3760         bReleaseFcb = TRUE;
3761
3762         //
3763         // Initialize the Ccb for the file.
3764         //
3765
3766         ntStatus = AFSInitCcb( Ccb,
3767                                DirectoryCB,
3768                                0,
3769                                0);
3770
3771         if( !NT_SUCCESS( ntStatus))
3772         {
3773
3774             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3775                           AFS_TRACE_LEVEL_ERROR,
3776                           "AFSOpenSpecialShareFcb (%p) Failed to initialize ccb Status %08lX\n",
3777                           Irp,
3778                           ntStatus);
3779
3780             try_return( ntStatus);
3781         }
3782
3783         bAllocatedCcb = TRUE;
3784
3785         //
3786         // Call the service to open the share
3787         //
3788
3789         (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3790
3791         RtlZeroMemory( &stPipeOpen,
3792                        sizeof( AFSPipeOpenCloseRequestCB));
3793
3794         stPipeOpen.RequestId = (*Ccb)->RequestID;
3795
3796         stPipeOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3797
3798         //
3799         // Issue the open request to the service
3800         //
3801
3802         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_OPEN,
3803                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
3804                                       AuthGroup,
3805                                       &DirectoryCB->NameInformation.FileName,
3806                                       NULL,
3807                                       (void *)&stPipeOpen,
3808                                       sizeof( AFSPipeOpenCloseRequestCB),
3809                                       NULL,
3810                                       NULL);
3811
3812         if( !NT_SUCCESS( ntStatus))
3813         {
3814
3815             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3816                           AFS_TRACE_LEVEL_ERROR,
3817                           "AFSOpenSpecialShareFcb (%p) Failed service open Status %08lX\n",
3818                           Irp,
3819                           ntStatus);
3820
3821             try_return( ntStatus);
3822         }
3823
3824         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3825
3826         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3827                       AFS_TRACE_LEVEL_VERBOSE,
3828                       "AFSOpenSpecialShareFcb Increment handle count on Fcb %p Cnt %d\n",
3829                       (*Fcb),
3830                       lCount);
3831
3832         //
3833         // Increment the open reference and handle on the parent node
3834         //
3835
3836         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3837
3838         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3839                       AFS_TRACE_LEVEL_VERBOSE,
3840                       "AFSOpenSpecialShareFcb Increment child open handle count on Parent object %p Cnt %d\n",
3841                       pParentObjectInfo,
3842                       lCount);
3843
3844         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3845
3846         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3847                       AFS_TRACE_LEVEL_VERBOSE,
3848                       "AFSOpenSpecialShareFcb Increment child open ref count on Parent object %p Cnt %d\n",
3849                       pParentObjectInfo,
3850                       lCount);
3851
3852         //
3853         // Return the open result for this file
3854         //
3855
3856         Irp->IoStatus.Information = FILE_OPENED;
3857
3858 try_exit:
3859
3860         if( bReleaseFcb)
3861         {
3862
3863             if( !NT_SUCCESS( ntStatus))
3864             {
3865                 //
3866                 // Decrement the open count on this Fcb
3867                 //
3868
3869                 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3870
3871                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3872                               AFS_TRACE_LEVEL_VERBOSE,
3873                               "AFSOpenSpecialShareFcb Decrement count on Fcb %p Cnt %d\n",
3874                               (*Fcb),
3875                               lCount);
3876             }
3877
3878             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3879         }
3880
3881         if( !NT_SUCCESS( ntStatus))
3882         {
3883
3884             if( bAllocatedCcb)
3885             {
3886
3887                 AFSRemoveCcb( NULL,
3888                               *Ccb);
3889             }
3890
3891             *Ccb = NULL;
3892
3893             if( bAllocateFcb)
3894             {
3895
3896                 //
3897                 // Need to tear down this Fcb since it is not in the tree for the worker thread
3898                 //
3899
3900                 AFSAcquireExcl( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
3901                                 TRUE);
3902
3903                 AFSRemoveFcb( &DirectoryCB->ObjectInformation->Fcb);
3904
3905                 AFSReleaseResource( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
3906             }
3907
3908             *Fcb = NULL;
3909         }
3910     }
3911
3912     return ntStatus;
3913 }