Windows: AFSNameArrayClone leak in AFSCommonCreate
[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                 else
823                 {
824
825                     AFSFreeNameArray( pNameArrayClone);
826
827                     pNameArrayClone = NULL;
828                 }
829
830                 if ( pNewVolumeCB != NULL)
831                 {
832
833                     //
834                     // AFSLocateNameEntry returns pNewVolumeCB with a reference held
835                     // even if pVolumeCB == pNewVolumeCB.  It is always safe to release
836                     // the reference on pVolumeCB that was held prior to the call.
837                     // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
838                     // will be released second.
839                     //
840
841                     lCount = AFSVolumeDecrement( pVolumeCB,
842                                                  VolumeReferenceReason);
843
844                     AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
845                                   AFS_TRACE_LEVEL_VERBOSE,
846                                   "AFSCommonCreate Decrement count on volume %p Reason %u Cnt %d\n",
847                                   pVolumeCB,
848                                   VolumeReferenceReason,
849                                   lCount));
850
851                     pVolumeCB = pNewVolumeCB;
852
853                     pNewVolumeCB = NULL;
854
855                     VolumeReferenceReason = NewVolumeReferenceReason;
856
857                     NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
858
859                     bReleaseVolume = (pVolumeCB != NULL);
860                 }
861
862                 //
863                 // AFSLocateNameEntry does not alter the reference count of
864                 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
865                 // a reference held.
866                 //
867
868                 if ( bReleaseParentDir)
869                 {
870
871                     lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
872
873                     AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
874                                   AFS_TRACE_LEVEL_VERBOSE,
875                                   "AFSCommonCreate DecrementX count on %wZ DE %p Ccb %p Cnt %d\n",
876                                   &pParentDirectoryCB->NameInformation.FileName,
877                                   pParentDirectoryCB,
878                                   pCcb,
879                                   lCount));
880                 }
881
882                 pParentDirectoryCB = pNewParentDirectoryCB;
883
884                 pNewParentDirectoryCB = NULL;
885
886                 bReleaseParentDir = (pParentDirectoryCB != NULL);
887
888                 if ( pDirectoryCB)
889                 {
890
891                     bReleaseDir = TRUE;
892                 }
893
894                 if( !NT_SUCCESS( ntStatus) &&
895                     ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
896                 {
897
898                     if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
899                     {
900                         uniSubstitutedPathName.Buffer = NULL;
901                     }
902
903                     //
904                     // AFSLocateNameEntry released the Parent while walking the
905                     // branch
906                     //
907
908                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
909                                   AFS_TRACE_LEVEL_VERBOSE,
910                                   "AFSCommonCreate (%p) Failed to locate name entry for %wZ Status %08lX\n",
911                                   Irp,
912                                   &uniFileName,
913                                   ntStatus));
914
915                     try_return( ntStatus);
916                 }
917
918                 //
919                 // Check for STATUS_REPARSE
920                 //
921
922                 if( ntStatus == STATUS_REPARSE)
923                 {
924
925                     uniSubstitutedPathName.Buffer = NULL;
926
927                     //
928                     // Update the information and return
929                     //
930
931                     Irp->IoStatus.Information = IO_REPARSE;
932
933                     try_return( ntStatus);
934                 }
935
936                 //
937                 // If we re-allocated the name, then update our substitute name
938                 //
939
940                 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
941                 {
942
943                     uniSubstitutedPathName = uniRootFileName;
944                 }
945                 else
946                 {
947
948                     uniSubstitutedPathName.Buffer = NULL;
949                 }
950
951                 //
952                 // Check for a symlink access
953                 //
954
955                 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
956                     pParentDirectoryCB != NULL)
957                 {
958
959                     //
960                     // pParentDirectoryCB DirOpenReferenceCount is still held
961                     //
962
963                     UNICODE_STRING uniFinalComponent;
964
965                     uniFinalComponent.Length = 0;
966                     uniFinalComponent.MaximumLength = 0;
967                     uniFinalComponent.Buffer = NULL;
968
969                     AFSRetrieveFinalComponent( &uniFileName,
970                                                &uniFinalComponent);
971
972                     ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
973                                                       &uniFinalComponent);
974
975                     if( !NT_SUCCESS( ntStatus) &&
976                         ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
977                     {
978
979                         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
980                                       AFS_TRACE_LEVEL_VERBOSE,
981                                       "AFSCommonCreate (%p) Failing access to symlink %wZ Status %08lX\n",
982                                       Irp,
983                                       &uniFileName,
984                                       ntStatus));
985
986                         try_return( ntStatus);
987                     }
988                 }
989             }
990         }
991
992         //
993         // If we have no parent then this is a root open, be sure there is a directory entry
994         // for the root
995         //
996
997         else if( pParentDirectoryCB == NULL &&
998                  pDirectoryCB == NULL)
999         {
1000
1001             pDirectoryCB = pVolumeCB->DirectoryCB;
1002
1003             lCount = InterlockedIncrement( &pDirectoryCB->DirOpenReferenceCount);
1004
1005             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1006                           AFS_TRACE_LEVEL_VERBOSE,
1007                           "AFSCommonCreate Increment0 count on %wZ DE %p Ccb %p Cnt %d\n",
1008                           &pDirectoryCB->NameInformation.FileName,
1009                           pDirectoryCB,
1010                           pCcb,
1011                           lCount));
1012
1013             bReleaseDir = TRUE;
1014         }
1015
1016         if( bOpenTargetDirectory)
1017         {
1018
1019             //
1020             // If we have a directory cb for the entry then dereference it and reference the parent
1021             //
1022
1023             if( pDirectoryCB != NULL)
1024             {
1025
1026                 if ( !bReleaseParentDir)
1027                 {
1028
1029                     //
1030                     // Perform in this order to prevent thrashing
1031                     //
1032
1033                     lCount = InterlockedIncrement( &pParentDirectoryCB->DirOpenReferenceCount);
1034
1035                     AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1036                                   AFS_TRACE_LEVEL_VERBOSE,
1037                                   "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
1038                                   &pParentDirectoryCB->NameInformation.FileName,
1039                                   pParentDirectoryCB,
1040                                   pCcb,
1041                                   lCount));
1042
1043                     bReleaseParentDir = TRUE;
1044                 }
1045
1046                 //
1047                 // Do NOT decrement the reference count on the pDirectoryCB yet.
1048                 // The BackupEntry below might drop the count to zero leaving
1049                 // the entry subject to being deleted and we need some of the
1050                 // contents during later processing
1051                 //
1052
1053                 AFSBackupEntry( pNameArray);
1054             }
1055
1056             //
1057             // OK, open the target directory
1058             //
1059
1060             if( uniComponentName.Length == 0)
1061             {
1062                 AFSRetrieveFinalComponent( &uniFileName,
1063                                            &uniComponentName);
1064             }
1065
1066             ntStatus = AFSOpenTargetDirectory( Irp,
1067                                                pVolumeCB,
1068                                                pParentDirectoryCB,
1069                                                pDirectoryCB,
1070                                                &uniComponentName,
1071                                                &pFcb,
1072                                                &pCcb);
1073
1074             if( !NT_SUCCESS( ntStatus))
1075             {
1076
1077                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1078                               AFS_TRACE_LEVEL_ERROR,
1079                               "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
1080                               &pParentDirectoryCB->NameInformation.FileName,
1081                               ntStatus));
1082             }
1083
1084             try_return( ntStatus);
1085         }
1086
1087         if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
1088         {
1089
1090             if( pDirectoryCB == NULL ||
1091                 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1092             {
1093                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1094                               AFS_TRACE_LEVEL_VERBOSE,
1095                               "AFSCommonCreate (%p) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
1096                               Irp,
1097                               &uniFileName,
1098                               pDirectoryCB,
1099                               pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0));
1100             }
1101             else
1102             {
1103                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1104                               AFS_TRACE_LEVEL_VERBOSE,
1105                               "AFSCommonCreate (%p) Opening as reparse point %wZ Type %08lX\n",
1106                               Irp,
1107                               &uniFileName,
1108                               pDirectoryCB->ObjectInformation->FileType));
1109
1110                 bOpenedReparsePoint = TRUE;
1111             }
1112         }
1113
1114         //
1115         // Based on the options passed in, process the file accordingly.
1116         //
1117
1118         if( ulCreateDisposition == FILE_CREATE ||
1119             ( ( ulCreateDisposition == FILE_OPEN_IF ||
1120                 ulCreateDisposition == FILE_OVERWRITE_IF) &&
1121               pDirectoryCB == NULL))
1122         {
1123
1124             if( uniComponentName.Length == 0 ||
1125                 pDirectoryCB != NULL)
1126             {
1127
1128                 //
1129                 // We traversed the entire path so we found each entry,
1130                 // fail with collision
1131                 //
1132
1133                 if( pDirectoryCB != NULL)
1134                 {
1135
1136                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1137                                   AFS_TRACE_LEVEL_VERBOSE,
1138                                   "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
1139                                   &pDirectoryCB->NameInformation.FileName,
1140                                   ntStatus));
1141                 }
1142                 else
1143                 {
1144
1145                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1146                                   AFS_TRACE_LEVEL_VERBOSE,
1147                                   "AFSCommonCreate Object name collision on create Status %08lX\n",
1148                                   ntStatus));
1149                 }
1150
1151                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
1152             }
1153
1154             //
1155             // OK, go and create the node
1156             //
1157
1158             ntStatus = AFSProcessCreate( Irp,
1159                                          &stAuthGroup,
1160                                          pVolumeCB,
1161                                          pParentDirectoryCB,
1162                                          &uniFileName,
1163                                          &uniComponentName,
1164                                          &uniRootFileName,
1165                                          &pFcb,
1166                                          &pCcb);
1167
1168             if( !NT_SUCCESS( ntStatus))
1169             {
1170
1171                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1172                               AFS_TRACE_LEVEL_ERROR,
1173                               "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
1174                               &uniComponentName,
1175                               &pParentDirectoryCB->NameInformation.FileName,
1176                               ntStatus));
1177             }
1178
1179             try_return( ntStatus);
1180         }
1181
1182         //
1183         // We should not have an extra component except for PIOCtl opens
1184         //
1185
1186         if( uniComponentName.Length > 0)
1187         {
1188
1189             //
1190             // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
1191             //
1192
1193             if( RtlCompareUnicodeString( &AFSPIOCtlName,
1194                                          &uniComponentName,
1195                                          TRUE) == 0)
1196             {
1197
1198                 //
1199                 // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
1200                 // pParentDirectoryCB.
1201                 //
1202
1203                 ntStatus = AFSOpenIOCtlFcb( Irp,
1204                                             &stAuthGroup,
1205                                             pParentDirectoryCB,
1206                                             &pFcb,
1207                                             &pCcb);
1208
1209                 if( !NT_SUCCESS( ntStatus))
1210                 {
1211
1212                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1213                                   AFS_TRACE_LEVEL_ERROR,
1214                                   "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
1215                                   &uniComponentName,
1216                                   ntStatus));
1217                 }
1218             }
1219             else
1220             {
1221
1222                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1223                               AFS_TRACE_LEVEL_VERBOSE,
1224                               "AFSCommonCreate (%p) File %wZ name not found\n",
1225                               Irp,
1226                               &uniFileName));
1227
1228                 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1229             }
1230
1231             try_return( ntStatus);
1232         }
1233
1234         //
1235         // For root opens the parent will be NULL
1236         //
1237
1238         if( pParentDirectoryCB == NULL)
1239         {
1240
1241             //
1242             // Check for the delete on close flag for the root
1243             //
1244
1245             if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
1246             {
1247
1248                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1249                               AFS_TRACE_LEVEL_ERROR,
1250                               "AFSCommonCreate (%p) Attempt to open root as delete on close\n",
1251                               Irp));
1252
1253                 try_return( ntStatus = STATUS_CANNOT_DELETE);
1254             }
1255
1256             //
1257             // If this is the target directory, then bail
1258             //
1259
1260             if( bOpenTargetDirectory)
1261             {
1262
1263                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1264                               AFS_TRACE_LEVEL_ERROR,
1265                               "AFSCommonCreate (%p) Attempt to open root as target directory\n",
1266                               Irp));
1267
1268                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1269             }
1270
1271             //
1272             // Go and open the root of the volume
1273             //
1274
1275             ntStatus = AFSOpenRoot( Irp,
1276                                     pVolumeCB,
1277                                     &stAuthGroup,
1278                                     &pFcb,
1279                                     &pCcb);
1280
1281             if( !NT_SUCCESS( ntStatus))
1282             {
1283
1284                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1285                               AFS_TRACE_LEVEL_ERROR,
1286                               "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
1287                               pVolumeCB->ObjectInformation.FileId.Cell,
1288                               pVolumeCB->ObjectInformation.FileId.Volume,
1289                               ntStatus));
1290             }
1291
1292             try_return( ntStatus);
1293         }
1294
1295         //
1296         // At this point if we have no pDirectoryCB it was not found.
1297         //
1298
1299         if( pDirectoryCB == NULL)
1300         {
1301
1302             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1303                           AFS_TRACE_LEVEL_ERROR,
1304                           "AFSCommonCreate Failing access to %wZ Name not found\n",
1305                           &uniFileName));
1306
1307             try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1308         }
1309
1310         if( ulCreateDisposition == FILE_OVERWRITE ||
1311             ulCreateDisposition == FILE_SUPERSEDE ||
1312             ulCreateDisposition == FILE_OVERWRITE_IF)
1313         {
1314
1315             //
1316             // Go process a file for overwrite or supersede.
1317             //
1318
1319             ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
1320                                                      Irp,
1321                                                      pVolumeCB,
1322                                                      &stAuthGroup,
1323                                                      pParentDirectoryCB,
1324                                                      pDirectoryCB,
1325                                                      &pFcb,
1326                                                      &pCcb);
1327
1328             if( !NT_SUCCESS( ntStatus))
1329             {
1330
1331                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1332                               AFS_TRACE_LEVEL_ERROR,
1333                               "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
1334                               &pDirectoryCB->NameInformation.FileName,
1335                               ntStatus));
1336             }
1337
1338             try_return( ntStatus);
1339         }
1340
1341         //
1342         // Trying to open the file
1343         //
1344
1345         ntStatus = AFSProcessOpen( Irp,
1346                                    &stAuthGroup,
1347                                    pVolumeCB,
1348                                    pParentDirectoryCB,
1349                                    pDirectoryCB,
1350                                    &pFcb,
1351                                    &pCcb);
1352
1353         if( !NT_SUCCESS( ntStatus))
1354         {
1355
1356             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1357                           AFS_TRACE_LEVEL_ERROR,
1358                           "AFSCommonCreate Failed open on %wZ Status %08lX\n",
1359                           &pDirectoryCB->NameInformation.FileName,
1360                           ntStatus));
1361         }
1362
1363 try_exit:
1364
1365         if( NT_SUCCESS( ntStatus) &&
1366             ntStatus != STATUS_REPARSE)
1367         {
1368
1369             if( pCcb != NULL)
1370             {
1371
1372                 AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
1373                                 TRUE);
1374
1375                 RtlCopyMemory( &pCcb->AuthGroup,
1376                                &stAuthGroup,
1377                                sizeof( GUID));
1378
1379                 //
1380                 // If we have a substitute name, then use it
1381                 //
1382
1383                 if( uniSubstitutedPathName.Buffer != NULL)
1384                 {
1385
1386                     pCcb->FullFileName = uniSubstitutedPathName;
1387
1388                     SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1389
1390                     ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1391                 }
1392                 else
1393                 {
1394
1395                     pCcb->FullFileName = uniRootFileName;
1396
1397                     if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1398                     {
1399
1400                         SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1401
1402                         ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1403                     }
1404                 }
1405
1406                 if( bOpenedReparsePoint)
1407                 {
1408                     SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1409                 }
1410
1411                 lCount = pCcb->DirectoryCB->DirOpenReferenceCount;
1412
1413                 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1414                               AFS_TRACE_LEVEL_VERBOSE,
1415                               "AFSCommonCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1416                               &pCcb->DirectoryCB->NameInformation.FileName,
1417                               pCcb->DirectoryCB,
1418                               pCcb,
1419                               lCount));
1420
1421                 ASSERT( lCount >= 0);
1422
1423                 pCcb->CurrentDirIndex = 0;
1424
1425                 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1426                 {
1427
1428                     SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1429                 }
1430
1431                 //
1432                 // Save off the name array for this instance
1433                 //
1434
1435                 pCcb->NameArray = pNameArray;
1436
1437                 pNameArray = NULL;
1438
1439                 AFSReleaseResource( &pCcb->NPCcb->CcbLock);
1440             }
1441
1442             //
1443             // If we make it here then init the FO for the request.
1444             //
1445
1446             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1447                           AFS_TRACE_LEVEL_VERBOSE_2,
1448                           "AFSCommonCreate (%p) FileObject %p FsContext %p FsContext2 %p\n",
1449                           Irp,
1450                           pFileObject,
1451                           pFcb,
1452                           pCcb));
1453
1454             pFileObject->FsContext = (void *)pFcb;
1455
1456             pFileObject->FsContext2 = (void *)pCcb;
1457
1458             if( pFcb != NULL)
1459             {
1460
1461                 ASSERT( pFcb->OpenHandleCount > 0);
1462
1463                 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1464
1465                 //
1466                 // For files perform additional processing
1467                 //
1468
1469                 switch( pFcb->Header.NodeTypeCode)
1470                 {
1471
1472                     case AFS_FILE_FCB:
1473                     case AFS_IOCTL_FCB:
1474                     {
1475
1476                         pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1477                     }
1478                 }
1479
1480                 //
1481                 // If the user did not request nobuffering then mark the FO as cacheable
1482                 //
1483
1484                 if( bNoIntermediateBuffering)
1485                 {
1486
1487                     pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1488                 }
1489                 else
1490                 {
1491
1492                     pFileObject->Flags |= FO_CACHE_SUPPORTED;
1493                 }
1494
1495                 //
1496                 // If the file was opened for execution then we need to set the bit in the FO
1497                 //
1498
1499                 if( BooleanFlagOn( *pDesiredAccess,
1500                                    FILE_EXECUTE))
1501                 {
1502
1503                     SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1504                 }
1505
1506                 //
1507                 // Update the last access time
1508                 //
1509
1510                 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1511
1512                 if( pCcb != NULL)
1513                 {
1514                     AFSInsertCcb( pFcb,
1515                                   pCcb);
1516                 }
1517             }
1518             else
1519             {
1520
1521                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1522                               AFS_TRACE_LEVEL_ERROR,
1523                               "AFSCommonCreate (%p) Returning with NULL Fcb FileObject %p FsContext %p FsContext2 %p\n",
1524                               Irp,
1525                               pFileObject,
1526                               pFcb,
1527                               pCcb));
1528             }
1529         }
1530         else
1531         {
1532             if( NT_SUCCESS( ntStatus) &&
1533                 ntStatus == STATUS_REPARSE)
1534             {
1535
1536                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1537                               AFS_TRACE_LEVEL_ERROR,
1538                               "AFSCommonCreate (%p) STATUS_REPARSE FileObject %p FsContext %p FsContext2 %p\n",
1539                               Irp,
1540                               pFileObject,
1541                               pFcb,
1542                               pCcb));
1543             }
1544
1545             //
1546             // Free up the sub name if we have one
1547             //
1548
1549             if( uniSubstitutedPathName.Buffer != NULL)
1550             {
1551
1552                 AFSExFreePoolWithTag( uniSubstitutedPathName.Buffer, 0);
1553
1554                 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1555             }
1556         }
1557
1558         //
1559         // Free up the name array ...
1560         //
1561
1562         if( pNameArray != NULL)
1563         {
1564
1565             AFSFreeNameArray( pNameArray);
1566         }
1567
1568         if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1569         {
1570
1571             AFSExFreePoolWithTag( uniRootFileName.Buffer, 0);
1572         }
1573
1574         if( bReleaseVolume)
1575         {
1576
1577             lCount = AFSVolumeDecrement( pVolumeCB,
1578                                          VolumeReferenceReason);
1579
1580             AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1581                           AFS_TRACE_LEVEL_VERBOSE,
1582                           "AFSCommonCreate Decrement count on Volume %08lX Reason %u Cnt %d\n",
1583                           pVolumeCB,
1584                           VolumeReferenceReason,
1585                           lCount));
1586         }
1587
1588         if ( bReleaseDir)
1589         {
1590
1591             //
1592             // Release the reference from AFSLocateNameEntry
1593             //
1594
1595             lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
1596
1597             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1598                           AFS_TRACE_LEVEL_VERBOSE,
1599                           "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1600                           &pDirectoryCB->NameInformation.FileName,
1601                           pDirectoryCB,
1602                           pCcb,
1603                           lCount));
1604
1605             ASSERT( lCount >= 0);
1606         }
1607
1608         if ( bReleaseParentDir)
1609         {
1610
1611             //
1612             // Release the reference from AFSLocateNameEntry
1613             //
1614
1615             lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
1616
1617             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1618                           AFS_TRACE_LEVEL_VERBOSE,
1619                           "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1620                           &pParentDirectoryCB->NameInformation.FileName,
1621                           pParentDirectoryCB,
1622                           pCcb,
1623                           lCount));
1624
1625             ASSERT( lCount >= 0);
1626         }
1627
1628         //
1629         // Setup the Irp for completion, the Information has been set previously
1630         //
1631
1632         Irp->IoStatus.Status = ntStatus;
1633     }
1634
1635     return ntStatus;
1636 }
1637
1638 NTSTATUS
1639 AFSOpenAFSRoot( IN PIRP Irp,
1640                 IN AFSFcb **Fcb,
1641                 IN AFSCcb **Ccb)
1642 {
1643
1644     NTSTATUS ntStatus = STATUS_SUCCESS;
1645     LONG lCount;
1646
1647     __Enter
1648     {
1649
1650         //
1651         // Initialize the Ccb for the file.
1652         //
1653
1654         ntStatus = AFSInitCcb( Ccb,
1655                                AFSGlobalRoot->DirectoryCB,
1656                                0,
1657                                0);
1658
1659         if( !NT_SUCCESS( ntStatus))
1660         {
1661
1662             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1663                           AFS_TRACE_LEVEL_ERROR,
1664                           "AFSOpenAFSRoot (%p) Failed to allocate Ccb\n",
1665                           Irp));
1666
1667             try_return( ntStatus);
1668         }
1669
1670         //
1671         // Increment the open count on this Fcb
1672         //
1673
1674         lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1675
1676         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1677                       AFS_TRACE_LEVEL_VERBOSE,
1678                       "AFSOpenAFSRoot Increment count on Fcb %p Cnt %d\n",
1679                       AFSGlobalRoot->RootFcb,
1680                       lCount));
1681
1682         lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1683
1684         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1685                       AFS_TRACE_LEVEL_VERBOSE,
1686                       "AFSOpenAFSRoot Increment handle count on Fcb %p Cnt %d\n",
1687                       AFSGlobalRoot->RootFcb,
1688                       lCount));
1689
1690         *Fcb = AFSGlobalRoot->RootFcb;
1691
1692         //
1693         // Return the open result for this file
1694         //
1695
1696         Irp->IoStatus.Information = FILE_OPENED;
1697
1698 try_exit:
1699
1700         NOTHING;
1701     }
1702
1703     return ntStatus;
1704 }
1705
1706 NTSTATUS
1707 AFSOpenRoot( IN PIRP Irp,
1708              IN AFSVolumeCB *VolumeCB,
1709              IN GUID *AuthGroup,
1710              OUT AFSFcb **RootFcb,
1711              OUT AFSCcb **Ccb)
1712 {
1713
1714     NTSTATUS ntStatus = STATUS_SUCCESS;
1715     PFILE_OBJECT pFileObject = NULL;
1716     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1717     PACCESS_MASK pDesiredAccess = NULL;
1718     USHORT usShareAccess;
1719     ULONG ulOptions;
1720     BOOLEAN bAllocatedCcb = FALSE;
1721     BOOLEAN bReleaseFcb = FALSE;
1722     AFSFileOpenCB   stOpenCB;
1723     AFSFileOpenResultCB stOpenResultCB;
1724     ULONG       ulResultLen = 0;
1725     LONG        lCount;
1726
1727     __Enter
1728     {
1729
1730         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1731         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1732         ulOptions = pIrpSp->Parameters.Create.Options;
1733
1734         pFileObject = pIrpSp->FileObject;
1735
1736         if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1737         {
1738
1739             ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1740
1741             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1742                           AFS_TRACE_LEVEL_ERROR,
1743                           "AFSOpenRoot (%p) Attempt to open root as file Status %08lX\n",
1744                           Irp,
1745                           ntStatus));
1746
1747             try_return( ntStatus);
1748         }
1749
1750         //
1751         // Check if we should go and retrieve updated information for the node
1752         //
1753
1754         ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1755                                      AuthGroup,
1756                                      FALSE,
1757                                      TRUE);
1758
1759         if( !NT_SUCCESS( ntStatus))
1760         {
1761
1762             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1763                           AFS_TRACE_LEVEL_ERROR,
1764                           "AFSOpenRoot (%p) Failed to validate root entry Status %08lX\n",
1765                           Irp,
1766                           ntStatus));
1767
1768             try_return( ntStatus);
1769         }
1770
1771         //
1772         // Check with the service that we can open the file
1773         //
1774
1775         RtlZeroMemory( &stOpenCB,
1776                        sizeof( AFSFileOpenCB));
1777
1778         stOpenCB.DesiredAccess = *pDesiredAccess;
1779
1780         stOpenCB.ShareAccess = usShareAccess;
1781
1782         stOpenResultCB.GrantedAccess = 0;
1783
1784         ulResultLen = sizeof( AFSFileOpenResultCB);
1785
1786         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1787                                       AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1788                                       AuthGroup,
1789                                       NULL,
1790                                       &VolumeCB->ObjectInformation.FileId,
1791                                       VolumeCB->VolumeInformation.Cell,
1792                                       VolumeCB->VolumeInformation.CellLength,
1793                                       (void *)&stOpenCB,
1794                                       sizeof( AFSFileOpenCB),
1795                                       (void *)&stOpenResultCB,
1796                                       &ulResultLen);
1797
1798         if( !NT_SUCCESS( ntStatus))
1799         {
1800
1801             UNICODE_STRING uniGUID;
1802
1803             uniGUID.Length = 0;
1804             uniGUID.MaximumLength = 0;
1805             uniGUID.Buffer = NULL;
1806
1807             if( AuthGroup != NULL)
1808             {
1809                 RtlStringFromGUID( *AuthGroup,
1810                                    &uniGUID);
1811             }
1812
1813             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1814                           AFS_TRACE_LEVEL_ERROR,
1815                           "AFSOpenRoot (%p) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1816                           Irp,
1817                           VolumeCB->ObjectInformation.FileId.Cell,
1818                           VolumeCB->ObjectInformation.FileId.Volume,
1819                           &uniGUID,
1820                           ntStatus));
1821
1822             if( AuthGroup != NULL)
1823             {
1824                 RtlFreeUnicodeString( &uniGUID);
1825             }
1826
1827             try_return( ntStatus);
1828         }
1829
1830         //
1831         // If the entry is not initialized then do it now
1832         //
1833
1834         if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1835         {
1836
1837             AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1838                             TRUE);
1839
1840             ntStatus = AFSEnumerateDirectory( AuthGroup,
1841                                               &VolumeCB->ObjectInformation,
1842                                               TRUE);
1843
1844             if( !NT_SUCCESS( ntStatus))
1845             {
1846
1847                 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1848
1849                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1850                               AFS_TRACE_LEVEL_ERROR,
1851                               "AFSOpenRoot (%p) Failed to enumerate directory Status %08lX\n",
1852                               Irp,
1853                               ntStatus));
1854
1855                 try_return( ntStatus);
1856             }
1857
1858             AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1859         }
1860
1861         //
1862         // If the root fcb has been initialized then check access otherwise
1863         // init the volume fcb
1864         //
1865
1866         ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1867                                    VolumeCB);
1868
1869         if( !NT_SUCCESS( ntStatus))
1870         {
1871
1872             try_return( ntStatus);
1873         }
1874
1875         lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1876
1877         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1878                       AFS_TRACE_LEVEL_VERBOSE,
1879                       "AFSOpenRoot Increment count on Fcb %p Cnt %d\n",
1880                       VolumeCB->RootFcb,
1881                       lCount));
1882
1883         bReleaseFcb = TRUE;
1884
1885         //
1886         // If there are current opens on the Fcb, check the access.
1887         //
1888
1889         if( VolumeCB->RootFcb->OpenHandleCount > 0)
1890         {
1891
1892             ntStatus = IoCheckShareAccess( *pDesiredAccess,
1893                                            usShareAccess,
1894                                            pFileObject,
1895                                            &VolumeCB->RootFcb->ShareAccess,
1896                                            FALSE);
1897
1898             if( !NT_SUCCESS( ntStatus))
1899             {
1900
1901                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1902                               AFS_TRACE_LEVEL_ERROR,
1903                               "AFSOpenRoot (%p) Access check failure Status %08lX\n",
1904                               Irp,
1905                               ntStatus));
1906
1907                 try_return( ntStatus);
1908             }
1909         }
1910
1911         //
1912         // Initialize the Ccb for the file.
1913         //
1914
1915         ntStatus = AFSInitCcb( Ccb,
1916                                VolumeCB->DirectoryCB,
1917                                *pDesiredAccess,
1918                                0);
1919
1920         if( !NT_SUCCESS( ntStatus))
1921         {
1922
1923             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1924                           AFS_TRACE_LEVEL_ERROR,
1925                           "AFSOpenRoot (%p) Failed to allocate Ccb Status %08lX\n",
1926                           Irp,
1927                           ntStatus));
1928
1929             try_return( ntStatus);
1930         }
1931
1932         bAllocatedCcb = TRUE;
1933
1934         //
1935         // OK, update the share access on the fileobject
1936         //
1937
1938         if( VolumeCB->RootFcb->OpenHandleCount > 0)
1939         {
1940
1941             IoUpdateShareAccess( pFileObject,
1942                                  &VolumeCB->RootFcb->ShareAccess);
1943         }
1944         else
1945         {
1946
1947             //
1948             // Set the access
1949             //
1950
1951             IoSetShareAccess( *pDesiredAccess,
1952                               usShareAccess,
1953                               pFileObject,
1954                               &VolumeCB->RootFcb->ShareAccess);
1955         }
1956
1957         //
1958         // Increment the open count on this Fcb
1959         //
1960
1961         lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1962
1963         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1964                       AFS_TRACE_LEVEL_VERBOSE,
1965                       "AFSOpenRoot Increment handle count on Fcb %p Cnt %d\n",
1966                       VolumeCB->RootFcb,
1967                       lCount));
1968
1969         //
1970         // Indicate the object is held
1971         //
1972
1973         SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1974
1975         //
1976         // Return the open result for this file
1977         //
1978
1979         Irp->IoStatus.Information = FILE_OPENED;
1980
1981         *RootFcb = VolumeCB->RootFcb;
1982
1983 try_exit:
1984
1985         if( bReleaseFcb)
1986         {
1987             if ( !NT_SUCCESS( ntStatus))
1988             {
1989
1990                 lCount = InterlockedDecrement( &VolumeCB->RootFcb->OpenReferenceCount);
1991
1992                 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1993                               AFS_TRACE_LEVEL_VERBOSE,
1994                               "AFSOpenRoot Decrement count on Fcb %p Cnt %d\n",
1995                               VolumeCB->RootFcb,
1996                               lCount));
1997             }
1998
1999             AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
2000         }
2001
2002         if( !NT_SUCCESS( ntStatus))
2003         {
2004
2005             if( bAllocatedCcb)
2006             {
2007
2008                 AFSRemoveCcb( NULL,
2009                               *Ccb);
2010
2011                 *Ccb = NULL;
2012             }
2013
2014             Irp->IoStatus.Information = 0;
2015         }
2016     }
2017
2018     return ntStatus;
2019 }
2020
2021 NTSTATUS
2022 AFSProcessCreate( IN PIRP               Irp,
2023                   IN GUID              *AuthGroup,
2024                   IN AFSVolumeCB       *VolumeCB,
2025                   IN AFSDirectoryCB    *ParentDirCB,
2026                   IN PUNICODE_STRING    FileName,
2027                   IN PUNICODE_STRING    ComponentName,
2028                   IN PUNICODE_STRING    FullFileName,
2029                   OUT AFSFcb          **Fcb,
2030                   OUT AFSCcb          **Ccb)
2031 {
2032
2033     NTSTATUS ntStatus = STATUS_SUCCESS;
2034     PFILE_OBJECT pFileObject = NULL;
2035     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2036     ULONG ulOptions = 0;
2037     ULONG ulAttributes = 0;
2038     BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
2039     PACCESS_MASK pDesiredAccess = NULL;
2040     USHORT usShareAccess;
2041     AFSDirectoryCB *pDirEntry = NULL;
2042     AFSObjectInfoCB *pParentObjectInfo = NULL;
2043     AFSObjectInfoCB *pObjectInfo = NULL;
2044     LONG lCount;
2045
2046     __Enter
2047     {
2048
2049         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2050         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2051
2052         pFileObject = pIrpSp->FileObject;
2053
2054         //
2055         // Extract out the options
2056         //
2057
2058         ulOptions = pIrpSp->Parameters.Create.Options;
2059
2060         //
2061         // We pass all attributes they want to apply to the file to the create
2062         //
2063
2064         ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
2065
2066         //
2067         // If this is a directory create then set the attribute correctly
2068         //
2069
2070         if( ulOptions & FILE_DIRECTORY_FILE)
2071         {
2072
2073             ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
2074         }
2075
2076         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2077                       AFS_TRACE_LEVEL_VERBOSE,
2078                       "AFSProcessCreate (%p) Creating file %wZ Attributes %08lX\n",
2079                       Irp,
2080                       FullFileName,
2081                       ulAttributes));
2082
2083         if( BooleanFlagOn( VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
2084         {
2085
2086             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2087                           AFS_TRACE_LEVEL_ERROR,
2088                           "AFSProcessCreate Request failed due to read only volume %wZ\n",
2089                           FullFileName));
2090
2091             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
2092         }
2093
2094         pParentObjectInfo = ParentDirCB->ObjectInformation;
2095
2096         //
2097         // Allocate and insert the direntry into the parent node
2098         //
2099
2100         ntStatus = AFSCreateDirEntry( AuthGroup,
2101                                       pParentObjectInfo,
2102                                       ParentDirCB,
2103                                       FileName,
2104                                       ComponentName,
2105                                       ulAttributes,
2106                                       &pDirEntry);
2107
2108         if( !NT_SUCCESS( ntStatus))
2109         {
2110
2111             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2112                           AFS_TRACE_LEVEL_ERROR,
2113                           "AFSProcessCreate (%p) Failed to create directory entry %wZ Status %08lX\n",
2114                           Irp,
2115                           FullFileName,
2116                           ntStatus));
2117
2118             try_return( ntStatus);
2119         }
2120
2121         bFileCreated = TRUE;
2122
2123         pObjectInfo = pDirEntry->ObjectInformation;
2124
2125         if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
2126             pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
2127         {
2128
2129             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2130                           AFS_TRACE_LEVEL_VERBOSE,
2131                           "AFSProcessCreate (%p) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2132                           Irp,
2133                           &pDirEntry->NameInformation.FileName,
2134                           pObjectInfo->FileId.Cell,
2135                           pObjectInfo->FileId.Volume,
2136                           pObjectInfo->FileId.Vnode,
2137                           pObjectInfo->FileId.Unique));
2138
2139             ntStatus = AFSEvaluateNode( AuthGroup,
2140                                         pDirEntry);
2141
2142             if( !NT_SUCCESS( ntStatus))
2143             {
2144
2145                 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
2146                 {
2147
2148                     if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2149                     {
2150
2151                         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2152                                       AFS_TRACE_LEVEL_ERROR,
2153                                       "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
2154                                       Irp,
2155                                       &pDirEntry->NameInformation.FileName,
2156                                       pObjectInfo->FileId.Cell,
2157                                       pObjectInfo->FileId.Volume,
2158                                       pObjectInfo->FileId.Vnode,
2159                                       pObjectInfo->FileId.Unique,
2160                                       pParentObjectInfo->FileId.Cell,
2161                                       pParentObjectInfo->FileId.Volume,
2162                                       pParentObjectInfo->FileId.Vnode,
2163                                       pParentObjectInfo->FileId.Unique,
2164                                       ntStatus));
2165                     }
2166                     else if ( AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId))
2167                     {
2168
2169                         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2170                                       AFS_TRACE_LEVEL_ERROR,
2171                                       "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2172                                       Irp,
2173                                       &pDirEntry->NameInformation.FileName,
2174                                       pObjectInfo->FileId.Cell,
2175                                       pObjectInfo->FileId.Volume,
2176                                       pObjectInfo->FileId.Vnode,
2177                                       pObjectInfo->FileId.Unique,
2178                                       pParentObjectInfo->FileId.Cell,
2179                                       pParentObjectInfo->FileId.Volume,
2180                                       pParentObjectInfo->FileId.Vnode,
2181                                       pParentObjectInfo->FileId.Unique,
2182                                       ntStatus));
2183                     }
2184                     else
2185                     {
2186
2187                         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2188                                       AFS_TRACE_LEVEL_ERROR,
2189                                       "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2190                                       Irp,
2191                                       &pDirEntry->NameInformation.FileName,
2192                                       pObjectInfo->FileId.Cell,
2193                                       pObjectInfo->FileId.Volume,
2194                                       pObjectInfo->FileId.Vnode,
2195                                       pObjectInfo->FileId.Unique,
2196                                       pParentObjectInfo->FileId.Cell,
2197                                       pParentObjectInfo->FileId.Volume,
2198                                       pParentObjectInfo->FileId.Vnode,
2199                                       pParentObjectInfo->FileId.Unique,
2200                                       pObjectInfo->ParentFileId.Cell,
2201                                       pObjectInfo->ParentFileId.Volume,
2202                                       pObjectInfo->ParentFileId.Vnode,
2203                                       pObjectInfo->ParentFileId.Unique,
2204                                       ntStatus));
2205                     }
2206                 }
2207                 else
2208                 {
2209
2210                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2211                                   AFS_TRACE_LEVEL_ERROR,
2212                                   "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2213                                   Irp,
2214                                   &pDirEntry->NameInformation.FileName,
2215                                   pObjectInfo->FileId.Cell,
2216                                   pObjectInfo->FileId.Volume,
2217                                   pObjectInfo->FileId.Vnode,
2218                                   pObjectInfo->FileId.Unique,
2219                                   ntStatus));
2220                 }
2221
2222                 try_return( ntStatus);
2223             }
2224
2225             ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
2226         }
2227
2228         ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2229                 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
2230
2231         //
2232         // We may have raced and the Fcb is already created
2233         //
2234
2235         //
2236         // Allocate and initialize the Fcb for the file.
2237         //
2238
2239         ntStatus = AFSInitFcb( pDirEntry);
2240
2241         *Fcb = pObjectInfo->Fcb;
2242
2243         if( !NT_SUCCESS( ntStatus))
2244         {
2245
2246             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2247                           AFS_TRACE_LEVEL_ERROR,
2248                           "AFSProcessCreate (%p) Failed to initialize fcb %wZ Status %08lX\n",
2249                           Irp,
2250                           FullFileName,
2251                           ntStatus));
2252
2253             try_return( ntStatus);
2254         }
2255
2256         ntStatus = STATUS_SUCCESS;
2257
2258         //
2259         // Increment the open count on this Fcb
2260         //
2261
2262         lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
2263
2264         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2265                       AFS_TRACE_LEVEL_VERBOSE,
2266                       "AFSProcessCreate Increment count on Fcb %p Cnt %d\n",
2267                       *Fcb,
2268                       lCount));
2269
2270         bReleaseFcb = TRUE;
2271
2272         //
2273         // Initialize the Ccb for the file.
2274         //
2275
2276         ntStatus = AFSInitCcb( Ccb,
2277                                pDirEntry,
2278                                *pDesiredAccess,
2279                                0);
2280
2281         if( !NT_SUCCESS( ntStatus))
2282         {
2283
2284             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2285                           AFS_TRACE_LEVEL_ERROR,
2286                           "AFSProcessCreate (%p) Failed to initialize ccb %wZ Status %08lX\n",
2287                           Irp,
2288                           FullFileName,
2289                           ntStatus));
2290
2291             try_return( ntStatus);
2292         }
2293
2294         bAllocatedCcb = TRUE;
2295
2296         //
2297         // If this is a file, update the headers filesizes.
2298         //
2299
2300         if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
2301         {
2302
2303             //
2304             // Update the sizes with the information passed in
2305             //
2306
2307             (*Fcb)->Header.AllocationSize.QuadPart  = pObjectInfo->AllocationSize.QuadPart;
2308             (*Fcb)->Header.FileSize.QuadPart        = pObjectInfo->EndOfFile.QuadPart;
2309             (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2310
2311             //
2312             // Notify the system of the addition
2313             //
2314
2315             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2316                                             *Ccb,
2317                                             (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
2318                                             (ULONG)FILE_ACTION_ADDED);
2319
2320             (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2321         }
2322         else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2323         {
2324
2325             //
2326             // This is a new directory node so indicate it has been enumerated
2327             //
2328
2329             SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
2330
2331             //
2332             // And the parent directory entry
2333             //
2334
2335             KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2336
2337             //
2338             // Notify the system of the addition
2339             //
2340
2341             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2342                                             *Ccb,
2343                                             (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2344                                             (ULONG)FILE_ACTION_ADDED);
2345         }
2346         else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2347                  (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2348                  (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2349                  (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
2350         {
2351
2352             //
2353             // And the parent directory entry
2354             //
2355
2356             KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2357
2358             //
2359             // Notify the system of the addition
2360             //
2361
2362             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2363                                             *Ccb,
2364                                             (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2365                                             (ULONG)FILE_ACTION_ADDED);
2366         }
2367
2368         //
2369         // Save off the access for the open
2370         //
2371
2372         IoSetShareAccess( *pDesiredAccess,
2373                           usShareAccess,
2374                           pFileObject,
2375                           &(*Fcb)->ShareAccess);
2376
2377         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2378
2379         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2380                       AFS_TRACE_LEVEL_VERBOSE,
2381                       "AFSProcessCreate Increment handle count on Fcb %p Cnt %d\n",
2382                       (*Fcb),
2383                       lCount));
2384
2385         //
2386         // Increment the open reference and handle on the parent node
2387         //
2388
2389         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2390
2391         AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2392                       AFS_TRACE_LEVEL_VERBOSE,
2393                       "AFSProcessCreate Increment child open handle count on Parent object %p Cnt %d\n",
2394                       pParentObjectInfo,
2395                       lCount));
2396
2397         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2398
2399         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2400                       AFS_TRACE_LEVEL_VERBOSE,
2401                       "AFSProcessCreate Increment child open ref count on Parent object %p Cnt %d\n",
2402                       pParentObjectInfo,
2403                       lCount));
2404
2405         if( ulOptions & FILE_DELETE_ON_CLOSE)
2406         {
2407
2408             //
2409             // Mark it for delete on close
2410             //
2411
2412             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2413                           AFS_TRACE_LEVEL_VERBOSE,
2414                           "AFSProcessCreate (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2415                           Irp,
2416                           pDirEntry,
2417                           FullFileName));
2418
2419             SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2420         }
2421
2422         //
2423         // Indicate the object is locked in the service
2424         //
2425
2426         SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2427
2428         //
2429         // Return the open result for this file
2430         //
2431
2432         Irp->IoStatus.Information = FILE_CREATED;
2433
2434 try_exit:
2435
2436         //
2437         // If we created the Fcb we need to release the resources
2438         //
2439
2440         if( bReleaseFcb)
2441         {
2442
2443             if( !NT_SUCCESS( ntStatus))
2444             {
2445                 //
2446                 // Decrement the open count on this Fcb
2447                 //
2448
2449                 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2450
2451                 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2452                               AFS_TRACE_LEVEL_VERBOSE,
2453                               "AFSProcessCreate Decrement count on Fcb %p Cnt %d\n",
2454                               *Fcb,
2455                               lCount));
2456             }
2457
2458             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2459         }
2460
2461         if ( bFileCreated)
2462         {
2463
2464             //
2465             // Decrement the reference added during initialization of the DE
2466             // AFSInitCcb allocates its own reference count.
2467             //
2468
2469             lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2470
2471             AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2472                           AFS_TRACE_LEVEL_VERBOSE,
2473                           "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2474                           &pDirEntry->NameInformation.FileName,
2475                           pDirEntry,
2476                           lCount));
2477
2478             ASSERT( lCount >= 0);
2479         }
2480
2481         if( !NT_SUCCESS( ntStatus))
2482         {
2483
2484             if( bFileCreated)
2485             {
2486
2487                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2488                               AFS_TRACE_LEVEL_VERBOSE,
2489                               "AFSProcessCreate Create failed, removing DE %p from parent object %p Status %08lX\n",
2490                               pDirEntry,
2491                               pParentObjectInfo,
2492                               ntStatus));
2493
2494                 //
2495                 // Remove the dir entry from the parent
2496                 //
2497
2498                 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2499                                 TRUE);
2500
2501                 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2502
2503                 AFSNotifyDelete( pDirEntry,
2504                                  AuthGroup,
2505                                  FALSE);
2506
2507                 //
2508                 // Pull the directory entry from the parent
2509                 //
2510
2511                 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2512                                             pDirEntry,
2513                                             FALSE); // Leave it in the enum list so the worker cleans it up
2514
2515                 //
2516                 // Tag the parent as needing verification
2517                 //
2518
2519                 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2520
2521                 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2522
2523                 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2524             }
2525
2526             if( bAllocatedCcb)
2527             {
2528
2529                 AFSRemoveCcb( NULL,
2530                               *Ccb);
2531             }
2532
2533             //
2534             // Fcb will be freed by AFSPrimaryVolumeWorker thread
2535             //
2536
2537             *Fcb = NULL;
2538
2539             *Ccb = NULL;
2540         }
2541     }
2542
2543     return ntStatus;
2544 }
2545
2546 NTSTATUS
2547 AFSOpenTargetDirectory( IN PIRP Irp,
2548                         IN AFSVolumeCB *VolumeCB,
2549                         IN AFSDirectoryCB *ParentDirectoryCB,
2550                         IN AFSDirectoryCB *TargetDirectoryCB,
2551                         IN UNICODE_STRING *TargetName,
2552                         OUT AFSFcb **Fcb,
2553                         OUT AFSCcb **Ccb)
2554 {
2555     UNREFERENCED_PARAMETER(VolumeCB);
2556     NTSTATUS ntStatus = STATUS_SUCCESS;
2557     PFILE_OBJECT pFileObject = NULL;
2558     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2559     PACCESS_MASK pDesiredAccess = NULL;
2560     USHORT usShareAccess;
2561     BOOLEAN bAllocatedCcb = FALSE;
2562     BOOLEAN bReleaseFcb = FALSE;
2563     AFSObjectInfoCB *pParentObject = NULL;
2564     AFSObjectInfoCB *pGrandParentObject = NULL;
2565     UNICODE_STRING uniTargetName;
2566     LONG lCount;
2567
2568     __Enter
2569     {
2570
2571         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2572         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2573
2574         pFileObject = pIrpSp->FileObject;
2575
2576         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2577                       AFS_TRACE_LEVEL_VERBOSE,
2578                       "AFSOpenTargetDirectory (%p) Processing file %wZ\n",
2579                       Irp,
2580                       TargetName));
2581
2582         pParentObject = ParentDirectoryCB->ObjectInformation;
2583
2584         if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2585         {
2586
2587             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2588         }
2589
2590         //
2591         // Make sure we have an Fcb for the access
2592
2593         //
2594         // Allocate and initialize the Fcb for the file.
2595         //
2596
2597         ntStatus = AFSInitFcb( ParentDirectoryCB);
2598
2599         *Fcb = pParentObject->Fcb;
2600
2601         if( !NT_SUCCESS( ntStatus))
2602         {
2603
2604             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2605                           AFS_TRACE_LEVEL_ERROR,
2606                           "AFSOpenTargetDirectory (%p) Failed to initialize fcb %wZ Status %08lX\n",
2607                           Irp,
2608                           &ParentDirectoryCB->NameInformation.FileName,
2609                           ntStatus));
2610
2611             try_return( ntStatus);
2612         }
2613
2614         ntStatus = STATUS_SUCCESS;
2615
2616         //
2617         // Increment the open count on this Fcb
2618         //
2619
2620         lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2621
2622         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2623                       AFS_TRACE_LEVEL_VERBOSE,
2624                       "AFSOpenTargetDirectory Increment count on Fcb %p Cnt %d\n",
2625                       pParentObject->Fcb,
2626                       lCount));
2627
2628         bReleaseFcb = TRUE;
2629
2630         //
2631         // If there are current opens on the Fcb, check the access.
2632         //
2633
2634         if( pParentObject->Fcb->OpenHandleCount > 0)
2635         {
2636
2637             ntStatus = IoCheckShareAccess( *pDesiredAccess,
2638                                            usShareAccess,
2639                                            pFileObject,
2640                                            &pParentObject->Fcb->ShareAccess,
2641                                            FALSE);
2642
2643             if( !NT_SUCCESS( ntStatus))
2644             {
2645
2646                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2647                               AFS_TRACE_LEVEL_ERROR,
2648                               "AFSOpenTargetDirectory (%p) Access check failure %wZ Status %08lX\n",
2649                               Irp,
2650                               &ParentDirectoryCB->NameInformation.FileName,
2651                               ntStatus));
2652
2653                 try_return( ntStatus);
2654             }
2655         }
2656
2657         //
2658         // Initialize the Ccb for the file.
2659         //
2660
2661         ntStatus = AFSInitCcb( Ccb,
2662                                ParentDirectoryCB,
2663                                *pDesiredAccess,
2664                                0);
2665
2666         if( !NT_SUCCESS( ntStatus))
2667         {
2668
2669             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2670                           AFS_TRACE_LEVEL_ERROR,
2671                           "AFSOpenTargetDirectory (%p) Failed to initialize ccb %wZ Status %08lX\n",
2672                           Irp,
2673                           &ParentDirectoryCB->NameInformation.FileName,
2674                           ntStatus));
2675
2676             try_return( ntStatus);
2677         }
2678
2679         bAllocatedCcb = TRUE;
2680
2681         if( TargetDirectoryCB != NULL &&
2682             FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2683                                 TargetName,
2684                                 FALSE,
2685                                 NULL))
2686         {
2687
2688             Irp->IoStatus.Information = FILE_EXISTS;
2689
2690             uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2691         }
2692         else
2693         {
2694
2695             Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2696
2697             uniTargetName = *TargetName;
2698         }
2699
2700         //
2701         // Update the filename in the fileobject for rename processing
2702         //
2703
2704         RtlCopyMemory( pFileObject->FileName.Buffer,
2705                        uniTargetName.Buffer,
2706                        uniTargetName.Length);
2707
2708         pFileObject->FileName.Length = uniTargetName.Length;
2709
2710         //
2711         // OK, update the share access on the fileobject
2712         //
2713
2714         if( pParentObject->Fcb->OpenHandleCount > 0)
2715         {
2716
2717             IoUpdateShareAccess( pFileObject,
2718                                  &pParentObject->Fcb->ShareAccess);
2719         }
2720         else
2721         {
2722
2723             //
2724             // Set the access
2725             //
2726
2727             IoSetShareAccess( *pDesiredAccess,
2728                               usShareAccess,
2729                               pFileObject,
2730                               &pParentObject->Fcb->ShareAccess);
2731         }
2732
2733         lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2734
2735         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2736                       AFS_TRACE_LEVEL_VERBOSE,
2737                       "AFSOpenTargetDirectory Increment handle count on Fcb %p Cnt %d\n",
2738                       pParentObject->Fcb,
2739                       lCount));
2740
2741         //
2742         // Increment the open reference and handle on the parent node
2743         //
2744
2745         if( BooleanFlagOn( pParentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2746         {
2747
2748             pGrandParentObject = AFSFindObjectInfo( pParentObject->VolumeCB,
2749                                                     &pParentObject->ParentFileId,
2750                                                     TRUE);
2751
2752             if ( pGrandParentObject)
2753             {
2754
2755                 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenHandleCount);
2756
2757                 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2758                               AFS_TRACE_LEVEL_VERBOSE,
2759                               "AFSOpenTargetDirectory Increment child open handle count on Parent object %p Cnt %d\n",
2760                               pGrandParentObject,
2761                               lCount));
2762
2763                 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenReferenceCount);
2764
2765                 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2766                               AFS_TRACE_LEVEL_VERBOSE,
2767                               "AFSOpenTargetDirectory Increment child open ref count on Parent object %p Cnt %d\n",
2768                               pGrandParentObject,
2769                               lCount));
2770
2771                 AFSReleaseObjectInfo( &pGrandParentObject);
2772             }
2773         }
2774
2775 try_exit:
2776
2777         if( bReleaseFcb)
2778         {
2779
2780             if( !NT_SUCCESS( ntStatus))
2781             {
2782                 //
2783                 // Decrement the open count on this Fcb
2784                 //
2785
2786                 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2787
2788                 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2789                               AFS_TRACE_LEVEL_VERBOSE,
2790                               "AFSOpenTargetDirectory Decrement count on Fcb %p Cnt %d\n",
2791                               pParentObject->Fcb,
2792                               lCount));
2793             }
2794
2795             AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2796         }
2797
2798         if( !NT_SUCCESS( ntStatus))
2799         {
2800
2801             if( bAllocatedCcb)
2802             {
2803
2804                 AFSRemoveCcb( NULL,
2805                               *Ccb);
2806             }
2807
2808             *Ccb = NULL;
2809
2810             //
2811             // Fcb will be freed by AFSPrimaryVolumeWorker thread
2812             //
2813
2814             *Fcb = NULL;
2815         }
2816     }
2817
2818     return ntStatus;
2819 }
2820
2821 NTSTATUS
2822 AFSProcessOpen( IN PIRP Irp,
2823                 IN GUID *AuthGroup,
2824                 IN AFSVolumeCB *VolumeCB,
2825                 IN AFSDirectoryCB *ParentDirCB,
2826                 IN AFSDirectoryCB *DirectoryCB,
2827                 OUT AFSFcb **Fcb,
2828                 OUT AFSCcb **Ccb)
2829 {
2830     UNREFERENCED_PARAMETER(VolumeCB);
2831     NTSTATUS ntStatus = STATUS_SUCCESS;
2832     PFILE_OBJECT pFileObject = NULL;
2833     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2834     PACCESS_MASK pDesiredAccess = NULL;
2835     USHORT usShareAccess;
2836     BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE;
2837     ULONG ulOptions = 0;
2838     AFSFileOpenCB   stOpenCB;
2839     AFSFileOpenResultCB stOpenResultCB;
2840     ULONG       ulResultLen = 0;
2841     AFSObjectInfoCB *pParentObjectInfo = NULL;
2842     AFSObjectInfoCB *pObjectInfo = NULL;
2843     ULONG       ulFileAccess = 0;
2844     AFSFileAccessReleaseCB stReleaseFileAccess;
2845     LONG lCount;
2846
2847     __Enter
2848     {
2849
2850         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2851         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2852
2853         pFileObject = pIrpSp->FileObject;
2854
2855         pParentObjectInfo = ParentDirCB->ObjectInformation;
2856
2857         pObjectInfo = DirectoryCB->ObjectInformation;
2858
2859         ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2860                 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
2861
2862         //
2863         // Check if the entry is pending a deletion
2864         //
2865
2866         if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2867         {
2868
2869             ntStatus = STATUS_DELETE_PENDING;
2870
2871             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2872                           AFS_TRACE_LEVEL_ERROR,
2873                           "AFSProcessOpen (%p) Entry pending delete %wZ Status %08lX\n",
2874                           Irp,
2875                           &DirectoryCB->NameInformation.FileName,
2876                           ntStatus));
2877
2878             try_return( ntStatus);
2879         }
2880
2881         //
2882         // Extract out the options
2883         //
2884
2885         ulOptions = pIrpSp->Parameters.Create.Options;
2886
2887         //
2888         // Check if we should go and retrieve updated information for the node
2889         //
2890
2891         ntStatus = AFSValidateEntry( DirectoryCB,
2892                                      AuthGroup,
2893                                      FALSE,
2894                                      TRUE);
2895
2896         if( !NT_SUCCESS( ntStatus))
2897         {
2898
2899             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2900                           AFS_TRACE_LEVEL_ERROR,
2901                           "AFSProcessOpen (%p) Failed to validate entry %wZ Status %08lX\n",
2902                           Irp,
2903                           &DirectoryCB->NameInformation.FileName,
2904                           ntStatus));
2905
2906             try_return( ntStatus);
2907         }
2908
2909         //
2910         // If this is marked for delete on close then be sure we can delete the entry
2911         //
2912
2913         if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2914         {
2915
2916             ntStatus = AFSNotifyDelete( DirectoryCB,
2917                                         AuthGroup,
2918                                         TRUE);
2919
2920             if( !NT_SUCCESS( ntStatus))
2921             {
2922
2923                 ntStatus = STATUS_CANNOT_DELETE;
2924
2925                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2926                               AFS_TRACE_LEVEL_ERROR,
2927                               "AFSProcessOpen (%p) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2928                               Irp,
2929                               &DirectoryCB->NameInformation.FileName,
2930                               ntStatus));
2931
2932                 try_return( ntStatus);
2933             }
2934         }
2935
2936         //
2937         // Be sure we have an Fcb for the current object
2938         //
2939
2940         ntStatus = AFSInitFcb( DirectoryCB);
2941
2942         if( !NT_SUCCESS( ntStatus))
2943         {
2944
2945             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2946                           AFS_TRACE_LEVEL_ERROR,
2947                           "AFSProcessOpen (%p) Failed to init fcb on %wZ Status %08lX\n",
2948                           Irp,
2949                           &DirectoryCB->NameInformation.FileName,
2950                           ntStatus));
2951
2952             try_return( ntStatus);
2953         }
2954
2955         ntStatus = STATUS_SUCCESS;
2956
2957         //
2958         // AFSInitFcb returns the Fcb resource held
2959         //
2960
2961         bReleaseFcb = TRUE;
2962
2963         //
2964         // Increment the open count on this Fcb
2965         //
2966
2967         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2968
2969         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2970                       AFS_TRACE_LEVEL_VERBOSE,
2971                       "AFSProcessOpen Increment2 count on Fcb %p Cnt %d\n",
2972                       pObjectInfo->Fcb,
2973                       lCount));
2974
2975         //
2976         // Check access on the entry
2977         //
2978
2979         if( pObjectInfo->Fcb->OpenHandleCount > 0)
2980         {
2981
2982             ntStatus = IoCheckShareAccess( *pDesiredAccess,
2983                                            usShareAccess,
2984                                            pFileObject,
2985                                            &pObjectInfo->Fcb->ShareAccess,
2986                                            FALSE);
2987
2988             if( !NT_SUCCESS( ntStatus))
2989             {
2990
2991                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2992                               AFS_TRACE_LEVEL_ERROR,
2993                               "AFSProcessOpen (%p) Failed to check share access on %wZ Status %08lX\n",
2994                               Irp,
2995                               &DirectoryCB->NameInformation.FileName,
2996                               ntStatus));
2997
2998                 try_return( ntStatus);
2999             }
3000         }
3001
3002         //
3003         // Additional checks
3004         //
3005
3006         if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
3007         {
3008
3009             //
3010             // If the caller is asking for write access then try to flush the image section
3011             //
3012
3013             if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
3014                 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
3015             {
3016
3017                 BOOLEAN bMmFlushed;
3018
3019                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3020                               AFS_TRACE_LEVEL_VERBOSE,
3021                               "AFSProcessOpen Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3022                               &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3023                               PsGetCurrentThread()));
3024
3025                 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3026                                 TRUE);
3027
3028                 bMmFlushed = MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3029                                                   MmFlushForWrite);
3030
3031                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3032                               AFS_TRACE_LEVEL_VERBOSE,
3033                               "AFSProcessOpen Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3034                               &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3035                               PsGetCurrentThread()));
3036
3037                 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3038
3039                 if ( !bMmFlushed)
3040                 {
3041
3042                     ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
3043                                                                             STATUS_SHARING_VIOLATION;
3044
3045                     AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3046                                   AFS_TRACE_LEVEL_ERROR,
3047                                   "AFSProcessOpen (%p) Failed to flush image section %wZ Status %08lX\n",
3048                                   Irp,
3049                                   &DirectoryCB->NameInformation.FileName,
3050                                   ntStatus));
3051
3052                     try_return( ntStatus);
3053                 }
3054             }
3055
3056             if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
3057             {
3058
3059                 ntStatus = STATUS_NOT_A_DIRECTORY;
3060
3061                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3062                               AFS_TRACE_LEVEL_ERROR,
3063                               "AFSProcessOpen (%p) Attempt to open file as directory %wZ Status %08lX\n",
3064                               Irp,
3065                               &DirectoryCB->NameInformation.FileName,
3066                               ntStatus));
3067
3068                 try_return( ntStatus);
3069             }
3070
3071             pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
3072         }
3073         else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3074                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
3075         {
3076
3077             if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
3078             {
3079
3080                 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
3081
3082                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,</