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