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