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