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