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,
3083                               AFS_TRACE_LEVEL_ERROR,
3084                               "AFSProcessOpen (%p) Attempt to open directory as file %wZ Status %08lX\n",
3085                               Irp,
3086                               &DirectoryCB->NameInformation.FileName,
3087                               ntStatus));
3088
3089                 try_return( ntStatus);
3090             }
3091         }
3092         else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3093                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
3094                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3095                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
3096         {
3097
3098         }
3099         else
3100         {
3101             ASSERT( FALSE);
3102             try_return( ntStatus = STATUS_UNSUCCESSFUL);
3103         }
3104
3105         //
3106         // Check with the service that we can open the file
3107         //
3108
3109         stOpenCB.ParentId = pParentObjectInfo->FileId;
3110
3111         stOpenCB.DesiredAccess = *pDesiredAccess;
3112
3113         stOpenCB.ShareAccess = usShareAccess;
3114
3115         stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
3116
3117         stOpenCB.Identifier = (ULONGLONG)pFileObject;
3118
3119         stOpenResultCB.GrantedAccess = 0;
3120
3121         ulResultLen = sizeof( AFSFileOpenResultCB);
3122
3123         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
3124                                       AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
3125                                       AuthGroup,
3126                                       &DirectoryCB->NameInformation.FileName,
3127                                       &pObjectInfo->FileId,
3128                                       pObjectInfo->VolumeCB->VolumeInformation.Cell,
3129                                       pObjectInfo->VolumeCB->VolumeInformation.CellLength,
3130                                       (void *)&stOpenCB,
3131                                       sizeof( AFSFileOpenCB),
3132                                       (void *)&stOpenResultCB,
3133                                       &ulResultLen);
3134
3135         if( !NT_SUCCESS( ntStatus))
3136         {
3137
3138             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3139                           AFS_TRACE_LEVEL_ERROR,
3140                           "AFSProcessOpen (%p) Failed open in service %wZ Status %08lX\n",
3141                           Irp,
3142                           &DirectoryCB->NameInformation.FileName,
3143                           ntStatus));
3144
3145             try_return( ntStatus);
3146         }
3147
3148         //
3149         // Save the granted access in case we need to release it below
3150         //
3151
3152         ulFileAccess = stOpenResultCB.FileAccess;
3153
3154         //
3155         // Check if there is a conflict
3156         //
3157
3158         if( !AFSCheckAccess( *pDesiredAccess,
3159                              stOpenResultCB.GrantedAccess,
3160                              BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
3161         {
3162
3163             ntStatus = STATUS_ACCESS_DENIED;
3164
3165             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3166                           AFS_TRACE_LEVEL_ERROR,
3167                           "AFSProcessOpen (%p) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
3168                           Irp,
3169                           *pDesiredAccess,
3170                           stOpenResultCB.GrantedAccess,
3171                           &DirectoryCB->NameInformation.FileName,
3172                           ntStatus));
3173
3174             try_return( ntStatus);
3175         }
3176
3177         //
3178         // Initialize the Ccb for the file.
3179         //
3180
3181         ntStatus = AFSInitCcb( Ccb,
3182                                DirectoryCB,
3183                                *pDesiredAccess,
3184                                ulFileAccess);
3185
3186         if( !NT_SUCCESS( ntStatus))
3187         {
3188
3189             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3190                           AFS_TRACE_LEVEL_ERROR,
3191                           "AFSProcessOpen (%p) Failed to initialize ccb %wZ Status %08lX\n",
3192                           Irp,
3193                           &DirectoryCB->NameInformation.FileName,
3194                           ntStatus));
3195
3196             try_return( ntStatus);
3197         }
3198
3199         bAllocatedCcb = TRUE;
3200
3201         //
3202         // Perform the access check on the target if this is a mount point or symlink
3203         //
3204
3205         if( pObjectInfo->Fcb->OpenHandleCount > 0)
3206         {
3207
3208             IoUpdateShareAccess( pFileObject,
3209                                  &pObjectInfo->Fcb->ShareAccess);
3210         }
3211         else
3212         {
3213
3214             //
3215             // Set the access
3216             //
3217
3218             IoSetShareAccess( *pDesiredAccess,
3219                               usShareAccess,
3220                               pFileObject,
3221                               &pObjectInfo->Fcb->ShareAccess);
3222         }
3223
3224         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
3225
3226         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3227                       AFS_TRACE_LEVEL_VERBOSE,
3228                       "AFSProcessOpen Increment handle count on Fcb %p Cnt %d\n",
3229                       pObjectInfo->Fcb,
3230                       lCount));
3231
3232         //
3233         // Increment the open reference and handle on the parent node
3234         //
3235
3236         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3237
3238         AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3239                       AFS_TRACE_LEVEL_VERBOSE,
3240                       "AFSProcessOpen Increment child open handle count on Parent object %p Cnt %d\n",
3241                       pParentObjectInfo,
3242                       lCount));
3243
3244         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3245
3246         AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3247                       AFS_TRACE_LEVEL_VERBOSE,
3248                       "AFSProcessOpen Increment child open ref count on Parent object %p Cnt %d\n",
3249                       pParentObjectInfo,
3250                       lCount));
3251
3252         if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
3253         {
3254
3255             //
3256             // Mark it for delete on close
3257             //
3258
3259             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3260                           AFS_TRACE_LEVEL_VERBOSE,
3261                           "AFSProcessOpen (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
3262                           Irp,
3263                           DirectoryCB,
3264                           &DirectoryCB->NameInformation.FileName));
3265
3266             SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
3267         }
3268
3269         //
3270         // Indicate the object is held
3271         //
3272
3273         SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
3274
3275         //
3276         // Return the open result for this file
3277         //
3278
3279         Irp->IoStatus.Information = FILE_OPENED;
3280
3281         *Fcb = pObjectInfo->Fcb;
3282
3283 try_exit:
3284
3285         if( bReleaseFcb)
3286         {
3287
3288             if( !NT_SUCCESS( ntStatus))
3289             {
3290                 //
3291                 // Decrement the open count on this Fcb
3292                 //
3293
3294                 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
3295
3296                 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3297                               AFS_TRACE_LEVEL_VERBOSE,
3298                               "AFSProcessOpen Decrement2 count on Fcb %p Cnt %d\n",
3299                               pObjectInfo->Fcb,
3300                               lCount));
3301             }
3302
3303             AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3304         }
3305
3306         if( !NT_SUCCESS( ntStatus))
3307         {
3308
3309             if ( ulFileAccess > 0)
3310             {
3311
3312                 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
3313
3314                 stReleaseFileAccess.FileAccess = ulFileAccess;
3315
3316                 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
3317
3318                 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
3319                                    AFS_REQUEST_FLAG_SYNCHRONOUS,
3320                                    AuthGroup,
3321                                    &DirectoryCB->NameInformation.FileName,
3322                                    &pObjectInfo->FileId,
3323                                    pObjectInfo->VolumeCB->VolumeInformation.Cell,
3324                                    pObjectInfo->VolumeCB->VolumeInformation.CellLength,
3325                                    (void *)&stReleaseFileAccess,
3326                                    sizeof( AFSFileAccessReleaseCB),
3327                                    NULL,
3328                                    NULL);
3329             }
3330
3331             if( bAllocatedCcb)
3332             {
3333
3334                 AFSRemoveCcb( NULL,
3335                               *Ccb);
3336             }
3337
3338             *Ccb = NULL;
3339
3340             //
3341             // Fcb will be freed by AFSPrimaryVolumeWorker thread
3342             //
3343
3344             *Fcb = NULL;
3345         }
3346     }
3347
3348     return ntStatus;
3349 }
3350
3351 NTSTATUS
3352 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
3353                               IN PIRP           Irp,
3354                               IN AFSVolumeCB   *VolumeCB,
3355                               IN GUID          *AuthGroup,
3356                               IN AFSDirectoryCB *ParentDirCB,
3357                               IN AFSDirectoryCB *DirectoryCB,
3358                               OUT AFSFcb       **Fcb,
3359                               OUT AFSCcb       **Ccb)
3360 {
3361     UNREFERENCED_PARAMETER(DeviceObject);
3362     NTSTATUS ntStatus = STATUS_SUCCESS;
3363     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3364     PFILE_OBJECT pFileObject = NULL;
3365     LARGE_INTEGER liZero = {0,0};
3366     BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
3367     ULONG   ulAttributes = 0;
3368     ULONG ulCreateDisposition = 0;
3369     BOOLEAN bAllocatedCcb = FALSE;
3370     BOOLEAN bUserMapped = FALSE;
3371     PACCESS_MASK pDesiredAccess = NULL;
3372     USHORT usShareAccess;
3373     AFSObjectInfoCB *pParentObjectInfo = NULL;
3374     AFSObjectInfoCB *pObjectInfo = NULL;
3375     LONG lCount;
3376     LARGE_INTEGER liSaveSize;
3377     LARGE_INTEGER liSaveVDL;
3378     LARGE_INTEGER liSaveAlloc;
3379
3380     __Enter
3381     {
3382
3383         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3384
3385         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
3386
3387         pFileObject = pIrpSp->FileObject;
3388
3389         ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
3390
3391         ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
3392
3393         if( BooleanFlagOn( VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
3394         {
3395
3396             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3397                           AFS_TRACE_LEVEL_ERROR,
3398                           "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3399                           Irp,
3400                           &DirectoryCB->NameInformation.FileName));
3401
3402             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3403         }
3404
3405         pParentObjectInfo = ParentDirCB->ObjectInformation;
3406
3407         pObjectInfo = DirectoryCB->ObjectInformation;
3408
3409         ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3410                 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
3411
3412         //
3413         // Check if we should go and retrieve updated information for the node
3414         //
3415
3416         ntStatus = AFSValidateEntry( DirectoryCB,
3417                                      AuthGroup,
3418                                      FALSE,
3419                                      TRUE);
3420
3421         if( !NT_SUCCESS( ntStatus))
3422         {
3423
3424             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3425                           AFS_TRACE_LEVEL_ERROR,
3426                           "AFSProcessOverwriteSupersede (%p) Failed to validate entry %wZ Status %08lX\n",
3427                           Irp,
3428                           &DirectoryCB->NameInformation.FileName,
3429                           ntStatus));
3430
3431             try_return( ntStatus);
3432         }
3433
3434         //
3435         // Be sure we have an Fcb for the object block
3436         //
3437
3438         ntStatus = AFSInitFcb( DirectoryCB);
3439
3440         *Fcb = pObjectInfo->Fcb;
3441
3442         if( !NT_SUCCESS( ntStatus))
3443         {
3444
3445             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3446                           AFS_TRACE_LEVEL_ERROR,
3447                           "AFSProcessOverwriteSupersede (%p) Failed to initialize fcb %wZ Status %08lX\n",
3448                           Irp,
3449                           &DirectoryCB->NameInformation.FileName,
3450                           ntStatus));
3451
3452             try_return( ntStatus);
3453         }
3454
3455         ntStatus = STATUS_SUCCESS;
3456
3457         //
3458         // Increment the open count on this Fcb.
3459         //
3460
3461         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3462
3463         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3464                       AFS_TRACE_LEVEL_VERBOSE,
3465                       "AFSProcessOverwriteSupersede Increment2 count on Fcb %p Cnt %d\n",
3466                       pObjectInfo->Fcb,
3467                       lCount));
3468
3469         bReleaseFcb = TRUE;
3470
3471         //
3472         // Check access on the entry
3473         //
3474
3475         if( pObjectInfo->Fcb->OpenHandleCount > 0)
3476         {
3477
3478             ntStatus = IoCheckShareAccess( *pDesiredAccess,
3479                                            usShareAccess,
3480                                            pFileObject,
3481                                            &pObjectInfo->Fcb->ShareAccess,
3482                                            FALSE);
3483
3484             if( !NT_SUCCESS( ntStatus))
3485             {
3486
3487                 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3488                               AFS_TRACE_LEVEL_ERROR,
3489                               "AFSProcessOverwriteSupersede (%p) Access check failure %wZ Status %08lX\n",
3490                               Irp,
3491                               &DirectoryCB->NameInformation.FileName,
3492                               ntStatus));
3493
3494                 try_return( ntStatus);
3495             }
3496         }
3497
3498         AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3499                       AFS_TRACE_LEVEL_VERBOSE,
3500                       "AFSProcessOverwriteSupercede Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3501                       &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3502                       PsGetCurrentThread()));
3503
3504         AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3505                         TRUE);
3506
3507         //
3508         //  Before we actually truncate, check to see if the purge
3509         //  is going to fail.
3510         //
3511
3512         bUserMapped = !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3513                                              &liZero);
3514
3515         AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3516                       AFS_TRACE_LEVEL_VERBOSE,
3517                       "AFSProcessOverwriteSupercede Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3518                       &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3519                       PsGetCurrentThread()));
3520
3521         AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3522
3523         if( bUserMapped)
3524         {
3525
3526             ntStatus = STATUS_USER_MAPPED_FILE;
3527
3528             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3529                           AFS_TRACE_LEVEL_ERROR,
3530                           "AFSProcessOverwriteSupersede (%p) File user mapped %wZ Status %08lX\n",
3531                           Irp,
3532                           &DirectoryCB->NameInformation.FileName,
3533                           ntStatus));
3534
3535             try_return( ntStatus);
3536         }
3537
3538         //
3539         // Initialize the Ccb for the file.
3540         //
3541
3542         ntStatus = AFSInitCcb( Ccb,
3543                                DirectoryCB,
3544                                *pDesiredAccess,
3545                                0);
3546
3547         if( !NT_SUCCESS( ntStatus))
3548         {
3549
3550             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3551                           AFS_TRACE_LEVEL_ERROR,
3552                           "AFSProcessOverwriteSupersede (%p) Failed to initialize ccb %wZ Status %08lX\n",
3553                           Irp,
3554                           &DirectoryCB->NameInformation.FileName,
3555                           ntStatus));
3556
3557             try_return( ntStatus);
3558         }
3559
3560         bAllocatedCcb = TRUE;
3561
3562         //
3563         // Set the file length to zero
3564         //
3565
3566         AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3567                         TRUE);
3568
3569         bReleasePaging = TRUE;
3570
3571         liSaveSize = pObjectInfo->Fcb->Header.FileSize;
3572         liSaveAlloc = pObjectInfo->Fcb->Header.AllocationSize;
3573         liSaveVDL = pObjectInfo->Fcb->Header.ValidDataLength;
3574
3575         pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3576         pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3577         pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3578
3579         pObjectInfo->EndOfFile.QuadPart = 0;
3580         pObjectInfo->AllocationSize.QuadPart = 0;
3581
3582         //
3583         // Trim down the extents. We do this BEFORE telling the service
3584         // the file is truncated since there is a potential race between
3585         // a worker thread releasing extents and us trimming
3586         //
3587
3588         AFSTrimExtents( pObjectInfo->Fcb,
3589                         &pObjectInfo->Fcb->Header.FileSize);
3590
3591         KeQuerySystemTime( &pObjectInfo->ChangeTime);
3592
3593         KeQuerySystemTime( &pObjectInfo->LastAccessTime);
3594
3595         KeQuerySystemTime( &pObjectInfo->LastWriteTime);
3596
3597         //
3598         // Set the update flag accordingly
3599         //
3600
3601         SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
3602                                           AFS_FCB_FLAG_UPDATE_CREATE_TIME |
3603                                           AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
3604                                           AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
3605                                           AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
3606
3607         ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
3608                                              pObjectInfo,
3609                                              AuthGroup);
3610
3611         if( !NT_SUCCESS( ntStatus))
3612         {
3613
3614             pObjectInfo->Fcb->Header.ValidDataLength = liSaveVDL;
3615             pObjectInfo->Fcb->Header.FileSize = liSaveSize;
3616             pObjectInfo->Fcb->Header.AllocationSize = liSaveAlloc;
3617             pObjectInfo->Fcb->ObjectInformation->EndOfFile = liSaveSize;
3618             pObjectInfo->Fcb->ObjectInformation->AllocationSize = liSaveAlloc;
3619
3620             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3621                           AFS_TRACE_LEVEL_ERROR,
3622                           "AFSProcessOverwriteSupersede (%p) Failed to update file information %wZ Status %08lX\n",
3623                           Irp,
3624                           &DirectoryCB->NameInformation.FileName,
3625                           ntStatus));
3626
3627             try_return( ntStatus);
3628         }
3629
3630         ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
3631
3632         if( ulCreateDisposition == FILE_SUPERSEDE)
3633         {
3634
3635             pObjectInfo->FileAttributes = ulAttributes;
3636
3637         }
3638         else
3639         {
3640
3641             pObjectInfo->FileAttributes |= ulAttributes;
3642         }
3643
3644         //
3645         // Save off the access for the open
3646         //
3647
3648         if( pObjectInfo->Fcb->OpenHandleCount > 0)
3649         {
3650
3651             IoUpdateShareAccess( pFileObject,
3652                                  &pObjectInfo->Fcb->ShareAccess);
3653         }
3654         else
3655         {
3656
3657             //
3658             // Set the access
3659             //
3660
3661             IoSetShareAccess( *pDesiredAccess,
3662                               usShareAccess,
3663                               pFileObject,
3664                               &pObjectInfo->Fcb->ShareAccess);
3665         }
3666
3667         //
3668         // Return the correct action
3669         //
3670
3671         if( ulCreateDisposition == FILE_SUPERSEDE)
3672         {
3673
3674             Irp->IoStatus.Information = FILE_SUPERSEDED;
3675         }
3676         else
3677         {
3678
3679             Irp->IoStatus.Information = FILE_OVERWRITTEN;
3680         }
3681
3682         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
3683
3684         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3685                       AFS_TRACE_LEVEL_VERBOSE,
3686                       "AFSProcessOverwriteSupersede Increment handle count on Fcb %p Cnt %d\n",
3687                       pObjectInfo->Fcb,
3688                       lCount));
3689
3690         //
3691         // Increment the open reference and handle on the parent node
3692         //
3693
3694         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3695
3696         AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3697                       AFS_TRACE_LEVEL_VERBOSE,
3698                       "AFSProcessOverwriteSupersede Increment child open handle count on Parent object %p Cnt %d\n",
3699                       pParentObjectInfo,
3700                       lCount));
3701
3702         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3703
3704         AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3705                       AFS_TRACE_LEVEL_VERBOSE,
3706                       "AFSProcessOverwriteSupersede Increment child open ref count on Parent object %p Cnt %d\n",
3707                       pParentObjectInfo,
3708                       lCount));
3709
3710         AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3711
3712         bReleaseFcb = FALSE;
3713
3714         *Fcb = pObjectInfo->Fcb;
3715
3716         //
3717         // Now that the Fcb->Resource has been dropped
3718         // we can call CcSetFileSizes.  We are still holding
3719         // the PagingIoResource
3720         //
3721
3722         pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
3723
3724         pFileObject->FsContext = (void *)pObjectInfo->Fcb;
3725
3726         pFileObject->FsContext2 = (void *)*Ccb;
3727
3728         CcSetFileSizes( pFileObject,
3729                         (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3730
3731 try_exit:
3732
3733         if( bReleasePaging)
3734         {
3735
3736             AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3737         }
3738
3739         if( bReleaseFcb)
3740         {
3741
3742             if( !NT_SUCCESS( ntStatus))
3743             {
3744                 //
3745                 // Decrement the open count on this Fcb.
3746                 //
3747
3748                 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
3749
3750                 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3751                               AFS_TRACE_LEVEL_VERBOSE,
3752                               "AFSProcessOverwriteSupersede Decrement2 count on Fcb %p Cnt %d\n",
3753                               pObjectInfo->Fcb,
3754                               lCount));
3755             }
3756
3757             AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3758         }
3759
3760         if( !NT_SUCCESS( ntStatus))
3761         {
3762
3763             if( bAllocatedCcb)
3764             {
3765
3766                 AFSRemoveCcb( NULL,
3767                               *Ccb);
3768             }
3769
3770             *Ccb = NULL;
3771
3772             //
3773             // Fcb will be freed by AFSPrimaryVolumeWorker thread
3774             //
3775
3776             *Fcb = NULL;
3777         }
3778     }
3779
3780     return ntStatus;
3781 }
3782
3783 NTSTATUS
3784 AFSControlDeviceCreate( IN PIRP Irp)
3785 {
3786
3787     NTSTATUS ntStatus = STATUS_SUCCESS;
3788
3789     __Enter
3790     {
3791
3792         if ( KernelMode == Irp->RequestorMode) {
3793             //
3794             // For now, just let the open happen
3795             //
3796             Irp->IoStatus.Information = FILE_OPENED;
3797         }
3798         else
3799         {
3800             //
3801             // Not from usermode, All access must be via
3802             // the FS component (which will do the
3803             // security check)
3804             //
3805             ntStatus = STATUS_ACCESS_DENIED;
3806         }
3807     }
3808
3809     return ntStatus;
3810 }
3811
3812 //
3813 // AFSOpenIOCtlFcb does not release a DirOpenReferenceCount on
3814 // the ParentDirCB.
3815 //
3816
3817 NTSTATUS
3818 AFSOpenIOCtlFcb( IN PIRP Irp,
3819                  IN GUID *AuthGroup,
3820                  IN AFSDirectoryCB *ParentDirCB,
3821                  OUT AFSFcb **Fcb,
3822                  OUT AFSCcb **Ccb)
3823 {
3824
3825     NTSTATUS ntStatus = STATUS_SUCCESS;
3826     PFILE_OBJECT pFileObject = NULL;
3827     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3828     BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
3829     AFSPIOCtlOpenCloseRequestCB stPIOCtlOpen;
3830     AFSFileID stFileID;
3831     AFSObjectInfoCB *pParentObjectInfo = NULL;
3832     LONG lCount;
3833
3834     __Enter
3835     {
3836
3837         pFileObject = pIrpSp->FileObject;
3838
3839         pParentObjectInfo = ParentDirCB->ObjectInformation;
3840
3841         //
3842         // If we haven't initialized the PIOCtl DirectoryCB for this directory then do it now
3843         //
3844
3845         if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB == NULL)
3846         {
3847
3848             ntStatus = AFSInitPIOCtlDirectoryCB( pParentObjectInfo);
3849
3850             if( !NT_SUCCESS( ntStatus))
3851             {
3852
3853                 try_return( ntStatus);
3854             }
3855         }
3856
3857         //
3858         // Allocate and initialize the Fcb for the file.
3859         //
3860
3861         ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB);
3862
3863         *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
3864
3865         if( !NT_SUCCESS( ntStatus))
3866         {
3867
3868             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3869                           AFS_TRACE_LEVEL_ERROR,
3870                           "AFSOpenIOCtlFcb (%p) Failed to initialize fcb Status %08lX\n",
3871                           Irp,
3872                           ntStatus));
3873
3874             try_return( ntStatus);
3875         }
3876
3877         ntStatus = STATUS_SUCCESS;
3878
3879         //
3880         // Increment the open reference and handle on the node
3881         //
3882
3883         lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3884
3885         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3886                       AFS_TRACE_LEVEL_VERBOSE,
3887                       "AFSOpenIOCtlFcb Increment count on Fcb %p Cnt %d\n",
3888                       (*Fcb),
3889                       lCount));
3890
3891         bReleaseFcb = TRUE;
3892
3893         //
3894         // Initialize the Ccb for the file.
3895         //
3896
3897         ntStatus = AFSInitCcb( Ccb,
3898                                pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
3899                                0,
3900                                0);
3901
3902         if( !NT_SUCCESS( ntStatus))
3903         {
3904
3905             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3906                           AFS_TRACE_LEVEL_ERROR,
3907                           "AFSOpenIOCtlFcb (%p) Failed to initialize ccb Status %08lX\n",
3908                           Irp,
3909                           ntStatus));
3910
3911             try_return( ntStatus);
3912         }
3913
3914         bAllocatedCcb = TRUE;
3915
3916         //
3917         // Set the PIOCtl index
3918         //
3919
3920         (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3921
3922         RtlZeroMemory( &stPIOCtlOpen,
3923                        sizeof( AFSPIOCtlOpenCloseRequestCB));
3924
3925         stPIOCtlOpen.RequestId = (*Ccb)->RequestID;
3926
3927         stPIOCtlOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3928
3929         RtlZeroMemory( &stFileID,
3930                        sizeof( AFSFileID));
3931
3932         //
3933         // The parent directory FID of the node
3934         //
3935
3936         stFileID = pParentObjectInfo->FileId;
3937
3938         //
3939         // Issue the open request to the service
3940         //
3941
3942         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_OPEN,
3943                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
3944                                       AuthGroup,
3945                                       NULL,
3946                                       &stFileID,
3947                                       NULL,
3948                                       0,
3949                                       (void *)&stPIOCtlOpen,
3950                                       sizeof( AFSPIOCtlOpenCloseRequestCB),
3951                                       NULL,
3952                                       NULL);
3953
3954         if( !NT_SUCCESS( ntStatus))
3955         {
3956
3957             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3958                           AFS_TRACE_LEVEL_ERROR,
3959                           "AFSOpenIOCtlFcb (%p) Failed service open Status %08lX\n",
3960                           Irp,
3961                           ntStatus));
3962
3963             try_return( ntStatus);
3964         }
3965
3966         //
3967         // Increment the handle on the node
3968         //
3969
3970         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3971
3972         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3973                       AFS_TRACE_LEVEL_VERBOSE,
3974                       "AFSOpenIOCtlFcb Increment handle count on Fcb %p Cnt %d\n",
3975                       (*Fcb),
3976                       lCount));
3977
3978         //
3979         // Increment the open reference and handle on the parent node
3980         //
3981
3982         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3983
3984         AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3985                       AFS_TRACE_LEVEL_VERBOSE,
3986                       "AFSOpenIOCtlFcb Increment child open handle count on Parent object %p Cnt %d\n",
3987                       pParentObjectInfo,
3988                       lCount));
3989
3990         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3991
3992         AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3993                       AFS_TRACE_LEVEL_VERBOSE,
3994                       "AFSOpenIOCtlFcb Increment child open ref count on Parent object %p Cnt %d\n",
3995                       pParentObjectInfo,
3996                       lCount));
3997
3998         //
3999         // Return the open result for this file
4000         //
4001
4002         Irp->IoStatus.Information = FILE_OPENED;
4003
4004 try_exit:
4005
4006         //
4007         // If we created the Fcb we need to release the resources
4008         //
4009
4010         if( bReleaseFcb)
4011         {
4012
4013             if( !NT_SUCCESS( ntStatus))
4014             {
4015                 //
4016                 // Decrement the open reference and handle on the node
4017                 //
4018
4019                 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
4020
4021                 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
4022                               AFS_TRACE_LEVEL_VERBOSE,
4023                               "AFSOpenIOCtlFcb Decrement count on Fcb %p Cnt %d\n",
4024                               (*Fcb),
4025                               lCount));
4026             }
4027
4028             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
4029         }
4030
4031         if( !NT_SUCCESS( ntStatus))
4032         {
4033
4034             if( bAllocatedCcb)
4035             {
4036
4037                 AFSRemoveCcb( NULL,
4038                               *Ccb);
4039             }
4040
4041             *Ccb = NULL;
4042
4043             //
4044             // Fcb will be freed by AFSPrimaryVolumeWorker thread
4045             //
4046
4047             *Fcb = NULL;
4048         }
4049     }
4050
4051     return ntStatus;
4052 }
4053
4054 NTSTATUS
4055 AFSOpenSpecialShareFcb( IN PIRP Irp,
4056                         IN GUID *AuthGroup,
4057                         IN AFSDirectoryCB *DirectoryCB,
4058                         OUT AFSFcb **Fcb,
4059                         OUT AFSCcb **Ccb)
4060 {
4061
4062     NTSTATUS ntStatus = STATUS_SUCCESS;
4063     PFILE_OBJECT pFileObject = NULL;
4064     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4065     BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE, bAllocateFcb = FALSE;
4066     AFSObjectInfoCB *pObjectInfo = NULL;
4067     AFSObjectInfoCB *pParentObjectInfo = NULL;
4068     AFSPipeOpenCloseRequestCB stPipeOpen;
4069     LONG lCount;
4070
4071     __Enter
4072     {
4073
4074         pFileObject = pIrpSp->FileObject;
4075
4076         AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4077                       AFS_TRACE_LEVEL_VERBOSE_2,
4078                       "AFSOpenSpecialShareFcb (%p) Processing Share %wZ open\n",
4079                       Irp,
4080                       &DirectoryCB->NameInformation.FileName));
4081
4082         pObjectInfo = DirectoryCB->ObjectInformation;
4083
4084         if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
4085         {
4086
4087             pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
4088                                                    &pObjectInfo->ParentFileId,
4089                                                    TRUE);
4090         }
4091
4092         if( DirectoryCB->ObjectInformation->Fcb == NULL)
4093         {
4094
4095             //
4096             // Allocate and initialize the Fcb for the file.
4097             //
4098
4099             ntStatus = AFSInitFcb( DirectoryCB);
4100
4101             *Fcb = pObjectInfo->Fcb;
4102
4103             if( !NT_SUCCESS( ntStatus))
4104             {
4105
4106                 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4107                               AFS_TRACE_LEVEL_ERROR,
4108                               "AFSOpenSpecialShareFcb (%p) Failed to initialize fcb Status %08lX\n",
4109                               Irp,
4110                               ntStatus));
4111
4112                 try_return( ntStatus);
4113             }
4114
4115             if ( ntStatus != STATUS_REPARSE)
4116             {
4117
4118                 bAllocateFcb = TRUE;
4119             }
4120
4121             ntStatus = STATUS_SUCCESS;
4122         }
4123         else
4124         {
4125
4126             *Fcb = pObjectInfo->Fcb;
4127
4128             AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
4129                             TRUE);
4130         }
4131
4132         //
4133         // Increment the open count on this Fcb
4134         //
4135
4136         lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
4137
4138         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
4139                       AFS_TRACE_LEVEL_VERBOSE,
4140                       "AFSOpenSpecialShareFcb Increment count on Fcb %p Cnt %d\n",
4141                       (*Fcb),
4142                       lCount));
4143
4144         bReleaseFcb = TRUE;
4145
4146         //
4147         // Initialize the Ccb for the file.
4148         //
4149
4150         ntStatus = AFSInitCcb( Ccb,
4151                                DirectoryCB,
4152                                0,
4153                                0);
4154
4155         if( !NT_SUCCESS( ntStatus))
4156         {
4157
4158             AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4159                           AFS_TRACE_LEVEL_ERROR,
4160                           "AFSOpenSpecialShareFcb (%p) Failed to initialize ccb Status %08lX\n",
4161                           Irp,
4162                           ntStatus));
4163
4164             try_return( ntStatus);
4165         }
4166
4167         bAllocatedCcb = TRUE;
4168
4169         //
4170         // Call the service to open the share
4171         //
4172
4173         (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
4174
4175         RtlZeroMemory( &stPipeOpen,
4176                        sizeof( AFSPipeOpenCloseRequestCB));
4177
4178         stPipeOpen.RequestId = (*Ccb)->RequestID;
4179
4180         stPipeOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
4181
4182         //
4183         // Issue the open request to the service
4184         //
4185
4186         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_OPEN,
4187                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
4188                                       AuthGroup,
4189                                       &DirectoryCB->NameInformation.FileName,
4190                                       NULL,
4191                                       NULL,
4192                                       0,
4193                                       (void *)&stPipeOpen,
4194                                       sizeof( AFSPipeOpenCloseRequestCB),
4195                                       NULL,
4196                                       NULL);
4197
4198         if( !NT_SUCCESS( ntStatus))
4199         {
4200
4201             AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4202                           AFS_TRACE_LEVEL_ERROR,
4203                           "AFSOpenSpecialShareFcb (%p) Failed service open Status %08lX\n",
4204                           Irp,
4205                           ntStatus));
4206
4207             try_return( ntStatus);
4208         }
4209
4210         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
4211
4212         AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
4213                       AFS_TRACE_LEVEL_VERBOSE,
4214                       "AFSOpenSpecialShareFcb Increment handle count on Fcb %p Cnt %d\n",
4215                       (*Fcb),
4216                       lCount));
4217
4218         //
4219         // Increment the open reference and handle on the parent node
4220         //
4221
4222         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
4223
4224         AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4225                       AFS_TRACE_LEVEL_VERBOSE,
4226                       "AFSOpenSpecialShareFcb Increment child open handle count on Parent object %p Cnt %d\n",
4227                       pParentObjectInfo,
4228                       lCount));
4229
4230         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
4231
4232         AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4233                       AFS_TRACE_LEVEL_VERBOSE,
4234                       "AFSOpenSpecialShareFcb Increment child open ref count on Parent object %p Cnt %d\n",
4235                       pParentObjectInfo,
4236                       lCount));
4237
4238         //
4239         // Return the open result for this file
4240         //
4241
4242         Irp->IoStatus.Information = FILE_OPENED;
4243
4244 try_exit:
4245
4246         if( bReleaseFcb)
4247         {
4248
4249             if( !NT_SUCCESS( ntStatus))
4250             {
4251                 //
4252                 // Decrement the open count on this Fcb
4253                 //
4254
4255                 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
4256
4257                 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
4258                               AFS_TRACE_LEVEL_VERBOSE,
4259                               "AFSOpenSpecialShareFcb Decrement count on Fcb %p Cnt %d\n",
4260                               (*Fcb),
4261                               lCount));
4262             }
4263
4264             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
4265         }
4266
4267         if( !NT_SUCCESS( ntStatus))
4268         {
4269
4270             if( bAllocatedCcb)
4271             {
4272
4273                 AFSRemoveCcb( NULL,
4274                               *Ccb);
4275             }
4276
4277             *Ccb = NULL;
4278
4279             if( bAllocateFcb)
4280             {
4281
4282                 //
4283                 // Need to tear down this Fcb since it is not in the tree for the worker thread
4284                 //
4285
4286                 AFSAcquireExcl( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
4287                                 TRUE);
4288
4289                 AFSRemoveFcb( &DirectoryCB->ObjectInformation->Fcb);
4290
4291                 AFSReleaseResource( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
4292             }
4293
4294             *Fcb = NULL;
4295         }
4296     }
4297
4298     return ntStatus;
4299 }