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