Windows: Add Cell name to AFSProcessRequest parameters
[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             if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1461             {
1462
1463                 ntStatus = AFSEnumerateDirectory( AuthGroup,
1464                                                   &VolumeCB->ObjectInformation,
1465                                                   TRUE);
1466
1467                 if( !NT_SUCCESS( ntStatus))
1468                 {
1469
1470                     AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1471
1472                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1473                                   AFS_TRACE_LEVEL_ERROR,
1474                                   "AFSOpenRoot (%p) Failed to enumerate directory Status %08lX\n",
1475                                   Irp,
1476                                   ntStatus);
1477
1478                     try_return( ntStatus);
1479                 }
1480
1481                 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1482             }
1483
1484             AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1485         }
1486
1487         //
1488         // If the root fcb has been initialized then check access otherwise
1489         // init the volume fcb
1490         //
1491
1492         ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1493                                    VolumeCB);
1494
1495         if( !NT_SUCCESS( ntStatus))
1496         {
1497
1498             try_return( ntStatus);
1499         }
1500
1501         lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1502
1503         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1504                       AFS_TRACE_LEVEL_VERBOSE,
1505                       "AFSOpenRoot Increment count on Fcb %p Cnt %d\n",
1506                       VolumeCB->RootFcb,
1507                       lCount);
1508
1509         bReleaseFcb = TRUE;
1510
1511         //
1512         // If there are current opens on the Fcb, check the access.
1513         //
1514
1515         if( VolumeCB->RootFcb->OpenHandleCount > 0)
1516         {
1517
1518             ntStatus = IoCheckShareAccess( *pDesiredAccess,
1519                                            usShareAccess,
1520                                            pFileObject,
1521                                            &VolumeCB->RootFcb->ShareAccess,
1522                                            FALSE);
1523
1524             if( !NT_SUCCESS( ntStatus))
1525             {
1526
1527                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1528                               AFS_TRACE_LEVEL_ERROR,
1529                               "AFSOpenRoot (%p) Access check failure Status %08lX\n",
1530                               Irp,
1531                               ntStatus);
1532
1533                 try_return( ntStatus);
1534             }
1535         }
1536
1537         //
1538         // Initialize the Ccb for the file.
1539         //
1540
1541         ntStatus = AFSInitCcb( Ccb,
1542                                VolumeCB->DirectoryCB,
1543                                *pDesiredAccess,
1544                                0);
1545
1546         if( !NT_SUCCESS( ntStatus))
1547         {
1548
1549             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1550                           AFS_TRACE_LEVEL_ERROR,
1551                           "AFSOpenRoot (%p) Failed to allocate Ccb Status %08lX\n",
1552                           Irp,
1553                           ntStatus);
1554
1555             try_return( ntStatus);
1556         }
1557
1558         bAllocatedCcb = TRUE;
1559
1560         //
1561         // OK, update the share access on the fileobject
1562         //
1563
1564         if( VolumeCB->RootFcb->OpenHandleCount > 0)
1565         {
1566
1567             IoUpdateShareAccess( pFileObject,
1568                                  &VolumeCB->RootFcb->ShareAccess);
1569         }
1570         else
1571         {
1572
1573             //
1574             // Set the access
1575             //
1576
1577             IoSetShareAccess( *pDesiredAccess,
1578                               usShareAccess,
1579                               pFileObject,
1580                               &VolumeCB->RootFcb->ShareAccess);
1581         }
1582
1583         //
1584         // Increment the open count on this Fcb
1585         //
1586
1587         lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1588
1589         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1590                       AFS_TRACE_LEVEL_VERBOSE,
1591                       "AFSOpenRoot Increment handle count on Fcb %p Cnt %d\n",
1592                       VolumeCB->RootFcb,
1593                       lCount);
1594
1595         //
1596         // Indicate the object is held
1597         //
1598
1599         SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1600
1601         //
1602         // Return the open result for this file
1603         //
1604
1605         Irp->IoStatus.Information = FILE_OPENED;
1606
1607         *RootFcb = VolumeCB->RootFcb;
1608
1609 try_exit:
1610
1611         if( bReleaseFcb)
1612         {
1613             if ( !NT_SUCCESS( ntStatus))
1614             {
1615
1616                 lCount = InterlockedDecrement( &VolumeCB->RootFcb->OpenReferenceCount);
1617
1618                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1619                               AFS_TRACE_LEVEL_VERBOSE,
1620                               "AFSOpenRoot Decrement count on Fcb %p Cnt %d\n",
1621                               VolumeCB->RootFcb,
1622                               lCount);
1623             }
1624
1625             AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1626         }
1627
1628         if( !NT_SUCCESS( ntStatus))
1629         {
1630
1631             if( bAllocatedCcb)
1632             {
1633
1634                 AFSRemoveCcb( NULL,
1635                               *Ccb);
1636
1637                 *Ccb = NULL;
1638             }
1639
1640             Irp->IoStatus.Information = 0;
1641         }
1642     }
1643
1644     return ntStatus;
1645 }
1646
1647 NTSTATUS
1648 AFSProcessCreate( IN PIRP               Irp,
1649                   IN GUID              *AuthGroup,
1650                   IN AFSVolumeCB       *VolumeCB,
1651                   IN AFSDirectoryCB    *ParentDirCB,
1652                   IN PUNICODE_STRING    FileName,
1653                   IN PUNICODE_STRING    ComponentName,
1654                   IN PUNICODE_STRING    FullFileName,
1655                   OUT AFSFcb          **Fcb,
1656                   OUT AFSCcb          **Ccb)
1657 {
1658
1659     NTSTATUS ntStatus = STATUS_SUCCESS;
1660     PFILE_OBJECT pFileObject = NULL;
1661     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1662     ULONG ulOptions = 0;
1663     ULONG ulAttributes = 0;
1664     BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1665     PACCESS_MASK pDesiredAccess = NULL;
1666     USHORT usShareAccess;
1667     AFSDirectoryCB *pDirEntry = NULL;
1668     AFSObjectInfoCB *pParentObjectInfo = NULL;
1669     AFSObjectInfoCB *pObjectInfo = NULL;
1670     LONG lCount;
1671
1672     __Enter
1673     {
1674
1675         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1676         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1677
1678         pFileObject = pIrpSp->FileObject;
1679
1680         //
1681         // Extract out the options
1682         //
1683
1684         ulOptions = pIrpSp->Parameters.Create.Options;
1685
1686         //
1687         // We pass all attributes they want to apply to the file to the create
1688         //
1689
1690         ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1691
1692         //
1693         // If this is a directory create then set the attribute correctly
1694         //
1695
1696         if( ulOptions & FILE_DIRECTORY_FILE)
1697         {
1698
1699             ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1700         }
1701
1702         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1703                       AFS_TRACE_LEVEL_VERBOSE,
1704                       "AFSProcessCreate (%p) Creating file %wZ Attributes %08lX\n",
1705                       Irp,
1706                       FullFileName,
1707                       ulAttributes);
1708
1709         if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1710         {
1711
1712             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1713                           AFS_TRACE_LEVEL_ERROR,
1714                           "AFSProcessCreate Request failed due to read only volume %wZ\n",
1715                           FullFileName);
1716
1717             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
1718         }
1719
1720         pParentObjectInfo = ParentDirCB->ObjectInformation;
1721
1722         //
1723         // Allocate and insert the direntry into the parent node
1724         //
1725
1726         ntStatus = AFSCreateDirEntry( AuthGroup,
1727                                       pParentObjectInfo,
1728                                       ParentDirCB,
1729                                       FileName,
1730                                       ComponentName,
1731                                       ulAttributes,
1732                                       &pDirEntry);
1733
1734         if( !NT_SUCCESS( ntStatus))
1735         {
1736
1737             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1738                           AFS_TRACE_LEVEL_ERROR,
1739                           "AFSProcessCreate (%p) Failed to create directory entry %wZ Status %08lX\n",
1740                           Irp,
1741                           FullFileName,
1742                           ntStatus);
1743
1744             try_return( ntStatus);
1745         }
1746
1747         bFileCreated = TRUE;
1748
1749         pObjectInfo = pDirEntry->ObjectInformation;
1750
1751         if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1752             pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1753         {
1754
1755             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1756                           AFS_TRACE_LEVEL_VERBOSE,
1757                           "AFSProcessCreate (%p) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1758                           Irp,
1759                           &pDirEntry->NameInformation.FileName,
1760                           pObjectInfo->FileId.Cell,
1761                           pObjectInfo->FileId.Volume,
1762                           pObjectInfo->FileId.Vnode,
1763                           pObjectInfo->FileId.Unique);
1764
1765             ntStatus = AFSEvaluateNode( AuthGroup,
1766                                         pDirEntry);
1767
1768             if( !NT_SUCCESS( ntStatus))
1769             {
1770
1771                 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
1772                 {
1773
1774                     if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1775                     {
1776
1777                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1778                                       AFS_TRACE_LEVEL_ERROR,
1779                                       "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
1780                                       Irp,
1781                                       &pDirEntry->NameInformation.FileName,
1782                                       pObjectInfo->FileId.Cell,
1783                                       pObjectInfo->FileId.Volume,
1784                                       pObjectInfo->FileId.Vnode,
1785                                       pObjectInfo->FileId.Unique,
1786                                       pParentObjectInfo->FileId.Cell,
1787                                       pParentObjectInfo->FileId.Volume,
1788                                       pParentObjectInfo->FileId.Vnode,
1789                                       pParentObjectInfo->FileId.Unique,
1790                                       ntStatus);
1791                     }
1792                     else if ( AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId))
1793                     {
1794
1795                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1796                                       AFS_TRACE_LEVEL_ERROR,
1797                                       "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1798                                       Irp,
1799                                       &pDirEntry->NameInformation.FileName,
1800                                       pObjectInfo->FileId.Cell,
1801                                       pObjectInfo->FileId.Volume,
1802                                       pObjectInfo->FileId.Vnode,
1803                                       pObjectInfo->FileId.Unique,
1804                                       pParentObjectInfo->FileId.Cell,
1805                                       pParentObjectInfo->FileId.Volume,
1806                                       pParentObjectInfo->FileId.Vnode,
1807                                       pParentObjectInfo->FileId.Unique,
1808                                       ntStatus);
1809                     }
1810                     else
1811                     {
1812
1813                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1814                                       AFS_TRACE_LEVEL_ERROR,
1815                                       "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1816                                       Irp,
1817                                       &pDirEntry->NameInformation.FileName,
1818                                       pObjectInfo->FileId.Cell,
1819                                       pObjectInfo->FileId.Volume,
1820                                       pObjectInfo->FileId.Vnode,
1821                                       pObjectInfo->FileId.Unique,
1822                                       pParentObjectInfo->FileId.Cell,
1823                                       pParentObjectInfo->FileId.Volume,
1824                                       pParentObjectInfo->FileId.Vnode,
1825                                       pParentObjectInfo->FileId.Unique,
1826                                       pObjectInfo->ParentFileId.Cell,
1827                                       pObjectInfo->ParentFileId.Volume,
1828                                       pObjectInfo->ParentFileId.Vnode,
1829                                       pObjectInfo->ParentFileId.Unique,
1830                                       ntStatus);
1831                     }
1832                 }
1833                 else
1834                 {
1835
1836                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1837                                   AFS_TRACE_LEVEL_ERROR,
1838                                   "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1839                                   Irp,
1840                                   &pDirEntry->NameInformation.FileName,
1841                                   pObjectInfo->FileId.Cell,
1842                                   pObjectInfo->FileId.Volume,
1843                                   pObjectInfo->FileId.Vnode,
1844                                   pObjectInfo->FileId.Unique,
1845                                   ntStatus);
1846                 }
1847
1848                 try_return( ntStatus);
1849             }
1850
1851             ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1852         }
1853
1854         ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
1855                 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
1856
1857         //
1858         // We may have raced and the Fcb is already created
1859         //
1860
1861         //
1862         // Allocate and initialize the Fcb for the file.
1863         //
1864
1865         ntStatus = AFSInitFcb( pDirEntry);
1866
1867         *Fcb = pObjectInfo->Fcb;
1868
1869         if( !NT_SUCCESS( ntStatus))
1870         {
1871
1872             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1873                           AFS_TRACE_LEVEL_ERROR,
1874                           "AFSProcessCreate (%p) Failed to initialize fcb %wZ Status %08lX\n",
1875                           Irp,
1876                           FullFileName,
1877                           ntStatus);
1878
1879             try_return( ntStatus);
1880         }
1881
1882         ntStatus = STATUS_SUCCESS;
1883
1884         //
1885         // Increment the open count on this Fcb
1886         //
1887
1888         lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1889
1890         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1891                       AFS_TRACE_LEVEL_VERBOSE,
1892                       "AFSProcessCreate Increment count on Fcb %p Cnt %d\n",
1893                       *Fcb,
1894                       lCount);
1895
1896         bReleaseFcb = TRUE;
1897
1898         //
1899         // Initialize the Ccb for the file.
1900         //
1901
1902         ntStatus = AFSInitCcb( Ccb,
1903                                pDirEntry,
1904                                *pDesiredAccess,
1905                                0);
1906
1907         if( !NT_SUCCESS( ntStatus))
1908         {
1909
1910             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1911                           AFS_TRACE_LEVEL_ERROR,
1912                           "AFSProcessCreate (%p) Failed to initialize ccb %wZ Status %08lX\n",
1913                           Irp,
1914                           FullFileName,
1915                           ntStatus);
1916
1917             try_return( ntStatus);
1918         }
1919
1920         bAllocatedCcb = TRUE;
1921
1922         //
1923         // If this is a file, update the headers filesizes.
1924         //
1925
1926         if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1927         {
1928
1929             //
1930             // Update the sizes with the information passed in
1931             //
1932
1933             (*Fcb)->Header.AllocationSize.QuadPart  = pObjectInfo->AllocationSize.QuadPart;
1934             (*Fcb)->Header.FileSize.QuadPart        = pObjectInfo->EndOfFile.QuadPart;
1935             (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1936
1937             //
1938             // Notify the system of the addition
1939             //
1940
1941             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1942                                             *Ccb,
1943                                             (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1944                                             (ULONG)FILE_ACTION_ADDED);
1945
1946             (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
1947         }
1948         else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1949         {
1950
1951             //
1952             // This is a new directory node so indicate it has been enumerated
1953             //
1954
1955             SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1956
1957             //
1958             // And the parent directory entry
1959             //
1960
1961             KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1962
1963             //
1964             // Notify the system of the addition
1965             //
1966
1967             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1968                                             *Ccb,
1969                                             (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1970                                             (ULONG)FILE_ACTION_ADDED);
1971         }
1972         else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
1973                  (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
1974                  (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
1975                  (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
1976         {
1977
1978             //
1979             // And the parent directory entry
1980             //
1981
1982             KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1983
1984             //
1985             // Notify the system of the addition
1986             //
1987
1988             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1989                                             *Ccb,
1990                                             (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1991                                             (ULONG)FILE_ACTION_ADDED);
1992         }
1993
1994         //
1995         // Save off the access for the open
1996         //
1997
1998         IoSetShareAccess( *pDesiredAccess,
1999                           usShareAccess,
2000                           pFileObject,
2001                           &(*Fcb)->ShareAccess);
2002
2003         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2004
2005         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2006                       AFS_TRACE_LEVEL_VERBOSE,
2007                       "AFSProcessCreate Increment handle count on Fcb %p Cnt %d\n",
2008                       (*Fcb),
2009                       lCount);
2010
2011         //
2012         // Increment the open reference and handle on the parent node
2013         //
2014
2015         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2016
2017         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2018                       AFS_TRACE_LEVEL_VERBOSE,
2019                       "AFSProcessCreate Increment child open handle count on Parent object %p Cnt %d\n",
2020                       pParentObjectInfo,
2021                       lCount);
2022
2023         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2024
2025         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2026                       AFS_TRACE_LEVEL_VERBOSE,
2027                       "AFSProcessCreate Increment child open ref count on Parent object %p Cnt %d\n",
2028                       pParentObjectInfo,
2029                       lCount);
2030
2031         if( ulOptions & FILE_DELETE_ON_CLOSE)
2032         {
2033
2034             //
2035             // Mark it for delete on close
2036             //
2037
2038             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2039                           AFS_TRACE_LEVEL_VERBOSE,
2040                           "AFSProcessCreate (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2041                           Irp,
2042                           pDirEntry,
2043                           FullFileName);
2044
2045             SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2046         }
2047
2048         //
2049         // Indicate the object is locked in the service
2050         //
2051
2052         SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2053
2054         //
2055         // Return the open result for this file
2056         //
2057
2058         Irp->IoStatus.Information = FILE_CREATED;
2059
2060 try_exit:
2061
2062         //
2063         // If we created the Fcb we need to release the resources
2064         //
2065
2066         if( bReleaseFcb)
2067         {
2068
2069             if( !NT_SUCCESS( ntStatus))
2070             {
2071                 //
2072                 // Decrement the open count on this Fcb
2073                 //
2074
2075                 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2076
2077                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2078                               AFS_TRACE_LEVEL_VERBOSE,
2079                               "AFSProcessCreate Decrement count on Fcb %p Cnt %d\n",
2080                               *Fcb,
2081                               lCount);
2082             }
2083
2084             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2085         }
2086
2087         if ( bFileCreated)
2088         {
2089
2090             //
2091             // Decrement the reference added during initialization of the DE
2092             // AFSInitCcb allocates its own reference count.
2093             //
2094
2095             lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2096
2097             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2098                           AFS_TRACE_LEVEL_VERBOSE,
2099                           "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2100                           &pDirEntry->NameInformation.FileName,
2101                           pDirEntry,
2102                           lCount);
2103
2104             ASSERT( lCount >= 0);
2105         }
2106
2107         if( !NT_SUCCESS( ntStatus))
2108         {
2109
2110             if( bFileCreated)
2111             {
2112
2113                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2114                               AFS_TRACE_LEVEL_VERBOSE,
2115                               "AFSProcessCreate Create failed, removing DE %p from parent object %p Status %08lX\n",
2116                               pDirEntry,
2117                               pParentObjectInfo,
2118                               ntStatus);
2119
2120                 //
2121                 // Remove the dir entry from the parent
2122                 //
2123
2124                 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2125                                 TRUE);
2126
2127                 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2128
2129                 AFSNotifyDelete( pDirEntry,
2130                                  AuthGroup,
2131                                  FALSE);
2132
2133                 //
2134                 // Pull the directory entry from the parent
2135                 //
2136
2137                 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2138                                             pDirEntry,
2139                                             FALSE); // Leave it in the enum list so the worker cleans it up
2140
2141                 //
2142                 // Tag the parent as needing verification
2143                 //
2144
2145                 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2146
2147                 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2148
2149                 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2150             }
2151
2152             if( bAllocatedCcb)
2153             {
2154
2155                 AFSRemoveCcb( NULL,
2156                               *Ccb);
2157             }
2158
2159             //
2160             // Fcb will be freed by AFSPrimaryVolumeWorker thread
2161             //
2162
2163             *Fcb = NULL;
2164
2165             *Ccb = NULL;
2166         }
2167     }
2168
2169     return ntStatus;
2170 }
2171
2172 NTSTATUS
2173 AFSOpenTargetDirectory( IN PIRP Irp,
2174                         IN AFSVolumeCB *VolumeCB,
2175                         IN AFSDirectoryCB *ParentDirectoryCB,
2176                         IN AFSDirectoryCB *TargetDirectoryCB,
2177                         IN UNICODE_STRING *TargetName,
2178                         OUT AFSFcb **Fcb,
2179                         OUT AFSCcb **Ccb)
2180 {
2181     UNREFERENCED_PARAMETER(VolumeCB);
2182     NTSTATUS ntStatus = STATUS_SUCCESS;
2183     PFILE_OBJECT pFileObject = NULL;
2184     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2185     PACCESS_MASK pDesiredAccess = NULL;
2186     USHORT usShareAccess;
2187     BOOLEAN bAllocatedCcb = FALSE;
2188     BOOLEAN bReleaseFcb = FALSE;
2189     AFSObjectInfoCB *pParentObject = NULL;
2190     AFSObjectInfoCB *pGrandParentObject = NULL;
2191     UNICODE_STRING uniTargetName;
2192     LONG lCount;
2193
2194     __Enter
2195     {
2196
2197         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2198         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2199
2200         pFileObject = pIrpSp->FileObject;
2201
2202         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2203                       AFS_TRACE_LEVEL_VERBOSE,
2204                       "AFSOpenTargetDirectory (%p) Processing file %wZ\n",
2205                       Irp,
2206                       TargetName);
2207
2208         pParentObject = ParentDirectoryCB->ObjectInformation;
2209
2210         if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2211         {
2212
2213             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2214         }
2215
2216         //
2217         // Make sure we have an Fcb for the access
2218
2219         //
2220         // Allocate and initialize the Fcb for the file.
2221         //
2222
2223         ntStatus = AFSInitFcb( ParentDirectoryCB);
2224
2225         *Fcb = pParentObject->Fcb;
2226
2227         if( !NT_SUCCESS( ntStatus))
2228         {
2229
2230             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2231                           AFS_TRACE_LEVEL_ERROR,
2232                           "AFSOpenTargetDirectory (%p) Failed to initialize fcb %wZ Status %08lX\n",
2233                           Irp,
2234                           &ParentDirectoryCB->NameInformation.FileName,
2235                           ntStatus);
2236
2237             try_return( ntStatus);
2238         }
2239
2240         ntStatus = STATUS_SUCCESS;
2241
2242         //
2243         // Increment the open count on this Fcb
2244         //
2245
2246         lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2247
2248         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2249                       AFS_TRACE_LEVEL_VERBOSE,
2250                       "AFSOpenTargetDirectory Increment count on Fcb %p Cnt %d\n",
2251                       pParentObject->Fcb,
2252                       lCount);
2253
2254         bReleaseFcb = TRUE;
2255
2256         //
2257         // If there are current opens on the Fcb, check the access.
2258         //
2259
2260         if( pParentObject->Fcb->OpenHandleCount > 0)
2261         {
2262
2263             ntStatus = IoCheckShareAccess( *pDesiredAccess,
2264                                            usShareAccess,
2265                                            pFileObject,
2266                                            &pParentObject->Fcb->ShareAccess,
2267                                            FALSE);
2268
2269             if( !NT_SUCCESS( ntStatus))
2270             {
2271
2272                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2273                               AFS_TRACE_LEVEL_ERROR,
2274                               "AFSOpenTargetDirectory (%p) Access check failure %wZ Status %08lX\n",
2275                               Irp,
2276                               &ParentDirectoryCB->NameInformation.FileName,
2277                               ntStatus);
2278
2279                 try_return( ntStatus);
2280             }
2281         }
2282
2283         //
2284         // Initialize the Ccb for the file.
2285         //
2286
2287         ntStatus = AFSInitCcb( Ccb,
2288                                ParentDirectoryCB,
2289                                *pDesiredAccess,
2290                                0);
2291
2292         if( !NT_SUCCESS( ntStatus))
2293         {
2294
2295             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2296                           AFS_TRACE_LEVEL_ERROR,
2297                           "AFSOpenTargetDirectory (%p) Failed to initialize ccb %wZ Status %08lX\n",
2298                           Irp,
2299                           &ParentDirectoryCB->NameInformation.FileName,
2300                           ntStatus);
2301
2302             try_return( ntStatus);
2303         }
2304
2305         bAllocatedCcb = TRUE;
2306
2307         if( TargetDirectoryCB != NULL &&
2308             FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2309                                 TargetName,
2310                                 FALSE,
2311                                 NULL))
2312         {
2313
2314             Irp->IoStatus.Information = FILE_EXISTS;
2315
2316             uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2317         }
2318         else
2319         {
2320
2321             Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2322
2323             uniTargetName = *TargetName;
2324         }
2325
2326         //
2327         // Update the filename in the fileobject for rename processing
2328         //
2329
2330         RtlCopyMemory( pFileObject->FileName.Buffer,
2331                        uniTargetName.Buffer,
2332                        uniTargetName.Length);
2333
2334         pFileObject->FileName.Length = uniTargetName.Length;
2335
2336         //
2337         // OK, update the share access on the fileobject
2338         //
2339
2340         if( pParentObject->Fcb->OpenHandleCount > 0)
2341         {
2342
2343             IoUpdateShareAccess( pFileObject,
2344                                  &pParentObject->Fcb->ShareAccess);
2345         }
2346         else
2347         {
2348
2349             //
2350             // Set the access
2351             //
2352
2353             IoSetShareAccess( *pDesiredAccess,
2354                               usShareAccess,
2355                               pFileObject,
2356                               &pParentObject->Fcb->ShareAccess);
2357         }
2358
2359         lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2360
2361         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2362                       AFS_TRACE_LEVEL_VERBOSE,
2363                       "AFSOpenTargetDirectory Increment handle count on Fcb %p Cnt %d\n",
2364                       pParentObject->Fcb,
2365                       lCount);
2366
2367         //
2368         // Increment the open reference and handle on the parent node
2369         //
2370
2371         if( BooleanFlagOn( pParentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2372         {
2373
2374             pGrandParentObject = AFSFindObjectInfo( pParentObject->VolumeCB,
2375                                                     &pParentObject->ParentFileId);
2376
2377             if ( pGrandParentObject)
2378             {
2379
2380                 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenHandleCount);
2381
2382                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2383                               AFS_TRACE_LEVEL_VERBOSE,
2384                               "AFSOpenTargetDirectory Increment child open handle count on Parent object %p Cnt %d\n",
2385                               pGrandParentObject,
2386                               lCount);
2387
2388                 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenReferenceCount);
2389
2390                 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2391                               AFS_TRACE_LEVEL_VERBOSE,
2392                               "AFSOpenTargetDirectory Increment child open ref count on Parent object %p Cnt %d\n",
2393                               pGrandParentObject,
2394                               lCount);
2395
2396                 AFSReleaseObjectInfo( &pGrandParentObject);
2397             }
2398         }
2399
2400 try_exit:
2401
2402         if( bReleaseFcb)
2403         {
2404
2405             if( !NT_SUCCESS( ntStatus))
2406             {
2407                 //
2408                 // Decrement the open count on this Fcb
2409                 //
2410
2411                 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2412
2413                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2414                               AFS_TRACE_LEVEL_VERBOSE,
2415                               "AFSOpenTargetDirectory Decrement count on Fcb %p Cnt %d\n",
2416                               pParentObject->Fcb,
2417                               lCount);
2418             }
2419
2420             AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2421         }
2422
2423         if( !NT_SUCCESS( ntStatus))
2424         {
2425
2426             if( bAllocatedCcb)
2427             {
2428
2429                 AFSRemoveCcb( NULL,
2430                               *Ccb);
2431             }
2432
2433             *Ccb = NULL;
2434
2435             //
2436             // Fcb will be freed by AFSPrimaryVolumeWorker thread
2437             //
2438
2439             *Fcb = NULL;
2440         }
2441     }
2442
2443     return ntStatus;
2444 }
2445
2446 NTSTATUS
2447 AFSProcessOpen( IN PIRP Irp,
2448                 IN GUID *AuthGroup,
2449                 IN AFSVolumeCB *VolumeCB,
2450                 IN AFSDirectoryCB *ParentDirCB,
2451                 IN AFSDirectoryCB *DirectoryCB,
2452                 OUT AFSFcb **Fcb,
2453                 OUT AFSCcb **Ccb)
2454 {
2455     UNREFERENCED_PARAMETER(VolumeCB);
2456     NTSTATUS ntStatus = STATUS_SUCCESS;
2457     PFILE_OBJECT pFileObject = NULL;
2458     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2459     PACCESS_MASK pDesiredAccess = NULL;
2460     USHORT usShareAccess;
2461     BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE;
2462     ULONG ulOptions = 0;
2463     AFSFileOpenCB   stOpenCB;
2464     AFSFileOpenResultCB stOpenResultCB;
2465     ULONG       ulResultLen = 0;
2466     AFSObjectInfoCB *pParentObjectInfo = NULL;
2467     AFSObjectInfoCB *pObjectInfo = NULL;
2468     ULONG       ulFileAccess = 0;
2469     AFSFileAccessReleaseCB stReleaseFileAccess;
2470     LONG lCount;
2471
2472     __Enter
2473     {
2474
2475         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2476         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2477
2478         pFileObject = pIrpSp->FileObject;
2479
2480         pParentObjectInfo = ParentDirCB->ObjectInformation;
2481
2482         pObjectInfo = DirectoryCB->ObjectInformation;
2483
2484         ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2485                 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
2486
2487         //
2488         // Check if the entry is pending a deletion
2489         //
2490
2491         if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2492         {
2493
2494             ntStatus = STATUS_DELETE_PENDING;
2495
2496             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2497                           AFS_TRACE_LEVEL_ERROR,
2498                           "AFSProcessOpen (%p) Entry pending delete %wZ Status %08lX\n",
2499                           Irp,
2500                           &DirectoryCB->NameInformation.FileName,
2501                           ntStatus);
2502
2503             try_return( ntStatus);
2504         }
2505
2506         //
2507         // Extract out the options
2508         //
2509
2510         ulOptions = pIrpSp->Parameters.Create.Options;
2511
2512         //
2513         // Check if we should go and retrieve updated information for the node
2514         //
2515
2516         ntStatus = AFSValidateEntry( DirectoryCB,
2517                                      AuthGroup,
2518                                      FALSE,
2519                                      TRUE);
2520
2521         if( !NT_SUCCESS( ntStatus))
2522         {
2523
2524             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2525                           AFS_TRACE_LEVEL_ERROR,
2526                           "AFSProcessOpen (%p) Failed to validate entry %wZ Status %08lX\n",
2527                           Irp,
2528                           &DirectoryCB->NameInformation.FileName,
2529                           ntStatus);
2530
2531             try_return( ntStatus);
2532         }
2533
2534         //
2535         // If this is marked for delete on close then be sure we can delete the entry
2536         //
2537
2538         if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2539         {
2540
2541             ntStatus = AFSNotifyDelete( DirectoryCB,
2542                                         AuthGroup,
2543                                         TRUE);
2544
2545             if( !NT_SUCCESS( ntStatus))
2546             {
2547
2548                 ntStatus = STATUS_CANNOT_DELETE;
2549
2550                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2551                               AFS_TRACE_LEVEL_ERROR,
2552                               "AFSProcessOpen (%p) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2553                               Irp,
2554                               &DirectoryCB->NameInformation.FileName,
2555                               ntStatus);
2556
2557                 try_return( ntStatus);
2558             }
2559         }
2560
2561         //
2562         // Be sure we have an Fcb for the current object
2563         //
2564
2565         ntStatus = AFSInitFcb( DirectoryCB);
2566
2567         if( !NT_SUCCESS( ntStatus))
2568         {
2569
2570             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2571                           AFS_TRACE_LEVEL_ERROR,
2572                           "AFSProcessOpen (%p) Failed to init fcb on %wZ Status %08lX\n",
2573                           Irp,
2574                           &DirectoryCB->NameInformation.FileName,
2575                           ntStatus);
2576
2577             try_return( ntStatus);
2578         }
2579
2580         ntStatus = STATUS_SUCCESS;
2581
2582         //
2583         // AFSInitFcb returns the Fcb resource held
2584         //
2585
2586         bReleaseFcb = TRUE;
2587
2588         //
2589         // Increment the open count on this Fcb
2590         //
2591
2592         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2593
2594         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2595                       AFS_TRACE_LEVEL_VERBOSE,
2596                       "AFSProcessOpen Increment2 count on Fcb %p Cnt %d\n",
2597                       pObjectInfo->Fcb,
2598                       lCount);
2599
2600         //
2601         // Check access on the entry
2602         //
2603
2604         if( pObjectInfo->Fcb->OpenHandleCount > 0)
2605         {
2606
2607             ntStatus = IoCheckShareAccess( *pDesiredAccess,
2608                                            usShareAccess,
2609                                            pFileObject,
2610                                            &pObjectInfo->Fcb->ShareAccess,
2611                                            FALSE);
2612
2613             if( !NT_SUCCESS( ntStatus))
2614             {
2615
2616                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2617                               AFS_TRACE_LEVEL_ERROR,
2618                               "AFSProcessOpen (%p) Failed to check share access on %wZ Status %08lX\n",
2619                               Irp,
2620                               &DirectoryCB->NameInformation.FileName,
2621                               ntStatus);
2622
2623                 try_return( ntStatus);
2624             }
2625         }
2626
2627         //
2628         // Additional checks
2629         //
2630
2631         if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2632         {
2633
2634             //
2635             // If the caller is asking for write access then try to flush the image section
2636             //
2637
2638             if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2639                 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2640             {
2641
2642                 BOOLEAN bMmFlushed;
2643
2644                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2645                               AFS_TRACE_LEVEL_VERBOSE,
2646                               "AFSProcessOpen Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2647                               &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2648                               PsGetCurrentThread());
2649
2650                 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2651                                 TRUE);
2652
2653                 bMmFlushed = MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2654                                                   MmFlushForWrite);
2655
2656                 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2657                               AFS_TRACE_LEVEL_VERBOSE,
2658                               "AFSProcessOpen Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2659                               &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2660                               PsGetCurrentThread());
2661
2662                 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
2663
2664                 if ( !bMmFlushed)
2665                 {
2666
2667                     ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2668                                                                             STATUS_SHARING_VIOLATION;
2669
2670                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2671                                   AFS_TRACE_LEVEL_ERROR,
2672                                   "AFSProcessOpen (%p) Failed to flush image section %wZ Status %08lX\n",
2673                                   Irp,
2674                                   &DirectoryCB->NameInformation.FileName,
2675                                   ntStatus);
2676
2677                     try_return( ntStatus);
2678                 }
2679             }
2680
2681             if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2682             {
2683
2684                 ntStatus = STATUS_NOT_A_DIRECTORY;
2685
2686                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2687                               AFS_TRACE_LEVEL_ERROR,
2688                               "AFSProcessOpen (%p) Attempt to open file as directory %wZ Status %08lX\n",
2689                               Irp,
2690                               &DirectoryCB->NameInformation.FileName,
2691                               ntStatus);
2692
2693                 try_return( ntStatus);
2694             }
2695
2696             pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2697         }
2698         else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2699                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2700         {
2701
2702             if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2703             {
2704
2705                 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2706
2707                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2708                               AFS_TRACE_LEVEL_ERROR,
2709                               "AFSProcessOpen (%p) Attempt to open directory as file %wZ Status %08lX\n",
2710                               Irp,
2711                               &DirectoryCB->NameInformation.FileName,
2712                               ntStatus);
2713
2714                 try_return( ntStatus);
2715             }
2716         }
2717         else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2718                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2719                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2720                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2721         {
2722
2723         }
2724         else
2725         {
2726             ASSERT( FALSE);
2727             try_return( ntStatus = STATUS_UNSUCCESSFUL);
2728         }
2729
2730         //
2731         // Check with the service that we can open the file
2732         //
2733
2734         stOpenCB.ParentId = pParentObjectInfo->FileId;
2735
2736         stOpenCB.DesiredAccess = *pDesiredAccess;
2737
2738         stOpenCB.ShareAccess = usShareAccess;
2739
2740         stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2741
2742         stOpenCB.Identifier = (ULONGLONG)pFileObject;
2743
2744         stOpenResultCB.GrantedAccess = 0;
2745
2746         ulResultLen = sizeof( AFSFileOpenResultCB);
2747
2748         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2749                                       AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2750                                       AuthGroup,
2751                                       &DirectoryCB->NameInformation.FileName,
2752                                       &pObjectInfo->FileId,
2753                                       pObjectInfo->VolumeCB->VolumeInformation.Cell,
2754                                       pObjectInfo->VolumeCB->VolumeInformation.CellLength,
2755                                       (void *)&stOpenCB,
2756                                       sizeof( AFSFileOpenCB),
2757                                       (void *)&stOpenResultCB,
2758                                       &ulResultLen);
2759
2760         if( !NT_SUCCESS( ntStatus))
2761         {
2762
2763             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2764                           AFS_TRACE_LEVEL_ERROR,
2765                           "AFSProcessOpen (%p) Failed open in service %wZ Status %08lX\n",
2766                           Irp,
2767                           &DirectoryCB->NameInformation.FileName,
2768                           ntStatus);
2769
2770             try_return( ntStatus);
2771         }
2772
2773         //
2774         // Save the granted access in case we need to release it below
2775         //
2776
2777         ulFileAccess = stOpenResultCB.FileAccess;
2778
2779         //
2780         // Check if there is a conflict
2781         //
2782
2783         if( !AFSCheckAccess( *pDesiredAccess,
2784                              stOpenResultCB.GrantedAccess,
2785                              BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2786         {
2787
2788             ntStatus = STATUS_ACCESS_DENIED;
2789
2790             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2791                           AFS_TRACE_LEVEL_ERROR,
2792                           "AFSProcessOpen (%p) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2793                           Irp,
2794                           *pDesiredAccess,
2795                           stOpenResultCB.GrantedAccess,
2796                           &DirectoryCB->NameInformation.FileName,
2797                           ntStatus);
2798
2799             try_return( ntStatus);
2800         }
2801
2802         //
2803         // Initialize the Ccb for the file.
2804         //
2805
2806         ntStatus = AFSInitCcb( Ccb,
2807                                DirectoryCB,
2808                                *pDesiredAccess,
2809                                ulFileAccess);
2810
2811         if( !NT_SUCCESS( ntStatus))
2812         {
2813
2814             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2815                           AFS_TRACE_LEVEL_ERROR,
2816                           "AFSProcessOpen (%p) Failed to initialize ccb %wZ Status %08lX\n",
2817                           Irp,
2818                           &DirectoryCB->NameInformation.FileName,
2819                           ntStatus);
2820
2821             try_return( ntStatus);
2822         }
2823
2824         bAllocatedCcb = TRUE;
2825
2826         //
2827         // Perform the access check on the target if this is a mount point or symlink
2828         //
2829
2830         if( pObjectInfo->Fcb->OpenHandleCount > 0)
2831         {
2832
2833             IoUpdateShareAccess( pFileObject,
2834                                  &pObjectInfo->Fcb->ShareAccess);
2835         }
2836         else
2837         {
2838
2839             //
2840             // Set the access
2841             //
2842
2843             IoSetShareAccess( *pDesiredAccess,
2844                               usShareAccess,
2845                               pFileObject,
2846                               &pObjectInfo->Fcb->ShareAccess);
2847         }
2848
2849         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2850
2851         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2852                       AFS_TRACE_LEVEL_VERBOSE,
2853                       "AFSProcessOpen Increment handle count on Fcb %p Cnt %d\n",
2854                       pObjectInfo->Fcb,
2855                       lCount);
2856
2857         //
2858         // Increment the open reference and handle on the parent node
2859         //
2860
2861         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2862
2863         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2864                       AFS_TRACE_LEVEL_VERBOSE,
2865                       "AFSProcessOpen Increment child open handle count on Parent object %p Cnt %d\n",
2866                       pParentObjectInfo,
2867                       lCount);
2868
2869         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2870
2871         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2872                       AFS_TRACE_LEVEL_VERBOSE,
2873                       "AFSProcessOpen Increment child open ref count on Parent object %p Cnt %d\n",
2874                       pParentObjectInfo,
2875                       lCount);
2876
2877         if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2878         {
2879
2880             //
2881             // Mark it for delete on close
2882             //
2883
2884             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2885                           AFS_TRACE_LEVEL_VERBOSE,
2886                           "AFSProcessOpen (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2887                           Irp,
2888                           DirectoryCB,
2889                           &DirectoryCB->NameInformation.FileName);
2890
2891             SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2892         }
2893
2894         //
2895         // Indicate the object is held
2896         //
2897
2898         SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2899
2900         //
2901         // Return the open result for this file
2902         //
2903
2904         Irp->IoStatus.Information = FILE_OPENED;
2905
2906         *Fcb = pObjectInfo->Fcb;
2907
2908 try_exit:
2909
2910         if( bReleaseFcb)
2911         {
2912
2913             if( !NT_SUCCESS( ntStatus))
2914             {
2915                 //
2916                 // Decrement the open count on this Fcb
2917                 //
2918
2919                 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2920
2921                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2922                               AFS_TRACE_LEVEL_VERBOSE,
2923                               "AFSProcessOpen Decrement2 count on Fcb %p Cnt %d\n",
2924                               pObjectInfo->Fcb,
2925                               lCount);
2926             }
2927
2928             AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2929         }
2930
2931         if( !NT_SUCCESS( ntStatus))
2932         {
2933
2934             if ( ulFileAccess > 0)
2935             {
2936
2937                 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2938
2939                 stReleaseFileAccess.FileAccess = ulFileAccess;
2940
2941                 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2942
2943                 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2944                                    AFS_REQUEST_FLAG_SYNCHRONOUS,
2945                                    AuthGroup,
2946                                    &DirectoryCB->NameInformation.FileName,
2947                                    &pObjectInfo->FileId,
2948                                    pObjectInfo->VolumeCB->VolumeInformation.Cell,
2949                                    pObjectInfo->VolumeCB->VolumeInformation.CellLength,
2950                                    (void *)&stReleaseFileAccess,
2951                                    sizeof( AFSFileAccessReleaseCB),
2952                                    NULL,
2953                                    NULL);
2954             }
2955
2956             if( bAllocatedCcb)
2957             {
2958
2959                 AFSRemoveCcb( NULL,
2960                               *Ccb);
2961             }
2962
2963             *Ccb = NULL;
2964
2965             //
2966             // Fcb will be freed by AFSPrimaryVolumeWorker thread
2967             //
2968
2969             *Fcb = NULL;
2970         }
2971     }
2972
2973     return ntStatus;
2974 }
2975
2976 NTSTATUS
2977 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
2978                               IN PIRP           Irp,
2979                               IN AFSVolumeCB   *VolumeCB,
2980                               IN GUID          *AuthGroup,
2981                               IN AFSDirectoryCB *ParentDirCB,
2982                               IN AFSDirectoryCB *DirectoryCB,
2983                               OUT AFSFcb       **Fcb,
2984                               OUT AFSCcb       **Ccb)
2985 {
2986     UNREFERENCED_PARAMETER(DeviceObject);
2987     NTSTATUS ntStatus = STATUS_SUCCESS;
2988     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2989     PFILE_OBJECT pFileObject = NULL;
2990     LARGE_INTEGER liZero = {0,0};
2991     BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
2992     ULONG   ulAttributes = 0;
2993     ULONG ulCreateDisposition = 0;
2994     BOOLEAN bAllocatedCcb = FALSE;
2995     BOOLEAN bUserMapped = FALSE;
2996     PACCESS_MASK pDesiredAccess = NULL;
2997     USHORT usShareAccess;
2998     AFSObjectInfoCB *pParentObjectInfo = NULL;
2999     AFSObjectInfoCB *pObjectInfo = NULL;
3000     LONG lCount;
3001     LARGE_INTEGER liSaveSize;
3002     LARGE_INTEGER liSaveVDL;
3003     LARGE_INTEGER liSaveAlloc;
3004
3005     __Enter
3006     {
3007
3008         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3009
3010         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
3011
3012         pFileObject = pIrpSp->FileObject;
3013
3014         ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
3015
3016         ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
3017
3018         if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
3019         {
3020
3021             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3022                           AFS_TRACE_LEVEL_ERROR,
3023                           "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3024                           Irp,
3025                           &DirectoryCB->NameInformation.FileName);
3026
3027             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3028         }
3029
3030         pParentObjectInfo = ParentDirCB->ObjectInformation;
3031
3032         pObjectInfo = DirectoryCB->ObjectInformation;
3033
3034         ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3035                 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
3036
3037         //
3038         // Check if we should go and retrieve updated information for the node
3039         //
3040
3041         ntStatus = AFSValidateEntry( DirectoryCB,
3042                                      AuthGroup,
3043                                      FALSE,
3044                                      TRUE);
3045
3046         if( !NT_SUCCESS( ntStatus))
3047         {
3048
3049             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3050                           AFS_TRACE_LEVEL_ERROR,
3051                           "AFSProcessOverwriteSupersede (%p) Failed to validate entry %wZ Status %08lX\n",
3052                           Irp,
3053                           &DirectoryCB->NameInformation.FileName,
3054                           ntStatus);
3055
3056             try_return( ntStatus);
3057         }
3058
3059         //
3060         // Be sure we have an Fcb for the object block
3061         //
3062
3063         ntStatus = AFSInitFcb( DirectoryCB);
3064
3065         *Fcb = pObjectInfo->Fcb;
3066
3067         if( !NT_SUCCESS( ntStatus))
3068         {
3069
3070             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3071                           AFS_TRACE_LEVEL_ERROR,
3072                           "AFSProcessOverwriteSupersede (%p) Failed to initialize fcb %wZ Status %08lX\n",
3073                           Irp,
3074                           &DirectoryCB->NameInformation.FileName,
3075                           ntStatus);
3076
3077             try_return( ntStatus);
3078         }
3079
3080         ntStatus = STATUS_SUCCESS;
3081
3082         //
3083         // Increment the open count on this Fcb.
3084         //
3085
3086         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3087
3088         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3089                       AFS_TRACE_LEVEL_VERBOSE,
3090                       "AFSProcessOverwriteSupersede Increment2 count on Fcb %p Cnt %d\n",
3091                       pObjectInfo->Fcb,
3092                       lCount);
3093
3094         bReleaseFcb = TRUE;
3095
3096         //
3097         // Check access on the entry
3098         //
3099
3100         if( pObjectInfo->Fcb->OpenHandleCount > 0)
3101         {
3102
3103             ntStatus = IoCheckShareAccess( *pDesiredAccess,
3104                                            usShareAccess,
3105                                            pFileObject,
3106                                            &pObjectInfo->Fcb->ShareAccess,
3107                                            FALSE);
3108
3109             if( !NT_SUCCESS( ntStatus))
3110             {
3111
3112                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3113                               AFS_TRACE_LEVEL_ERROR,
3114                               "AFSProcessOverwriteSupersede (%p) Access check failure %wZ Status %08lX\n",
3115                               Irp,
3116                               &DirectoryCB->NameInformation.FileName,
3117                               ntStatus);
3118
3119                 try_return( ntStatus);
3120             }
3121         }
3122
3123         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3124                       AFS_TRACE_LEVEL_VERBOSE,
3125                       "AFSProcessOverwriteSupercede Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3126                       &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3127                       PsGetCurrentThread());
3128
3129         AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3130                         TRUE);
3131
3132         //
3133         //  Before we actually truncate, check to see if the purge
3134         //  is going to fail.
3135         //
3136
3137         bUserMapped = !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3138                                              &liZero);
3139
3140         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3141                       AFS_TRACE_LEVEL_VERBOSE,
3142                       "AFSProcessOverwriteSupercede Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3143                       &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3144                       PsGetCurrentThread());
3145
3146         AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3147
3148         if( bUserMapped)
3149         {
3150
3151             ntStatus = STATUS_USER_MAPPED_FILE;
3152
3153             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3154                           AFS_TRACE_LEVEL_ERROR,
3155                           "AFSProcessOverwriteSupersede (%p) File user mapped %wZ Status %08lX\n",
3156                           Irp,
3157                           &DirectoryCB->NameInformation.FileName,
3158                           ntStatus);
3159
3160             try_return( ntStatus);
3161         }
3162
3163         //
3164         // Initialize the Ccb for the file.
3165         //
3166
3167         ntStatus = AFSInitCcb( Ccb,
3168                                DirectoryCB,
3169                                *pDesiredAccess,
3170                                0);
3171
3172         if( !NT_SUCCESS( ntStatus))
3173         {
3174
3175             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3176                           AFS_TRACE_LEVEL_ERROR,
3177                           "AFSProcessOverwriteSupersede (%p) Failed to initialize ccb %wZ Status %08lX\n",
3178                           Irp,
3179                           &DirectoryCB->NameInformation.FileName,
3180                           ntStatus);
3181
3182             try_return( ntStatus);
3183         }
3184
3185         bAllocatedCcb = TRUE;
3186
3187         //
3188         // Set the file length to zero
3189         //
3190
3191         AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3192                         TRUE);
3193
3194         bReleasePaging = TRUE;
3195
3196         liSaveSize = pObjectInfo->Fcb->Header.FileSize;
3197         liSaveAlloc = pObjectInfo->Fcb->Header.AllocationSize;
3198         liSaveVDL = pObjectInfo->Fcb->Header.ValidDataLength;
3199
3200         pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3201         pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3202         pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3203
3204         pObjectInfo->EndOfFile.QuadPart = 0;
3205         pObjectInfo->AllocationSize.QuadPart = 0;
3206
3207         //
3208         // Trim down the extents. We do this BEFORE telling the service
3209         // the file is truncated since there is a potential race between
3210         // a worker thread releasing extents and us trimming
3211         //
3212
3213         AFSTrimExtents( pObjectInfo->Fcb,
3214                         &pObjectInfo->Fcb->Header.FileSize);
3215
3216         KeQuerySystemTime( &pObjectInfo->ChangeTime);
3217
3218         KeQuerySystemTime( &pObjectInfo->LastAccessTime);
3219
3220         KeQuerySystemTime( &pObjectInfo->LastWriteTime);
3221
3222         //
3223         // Set the update flag accordingly
3224         //
3225
3226         SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
3227                                           AFS_FCB_FLAG_UPDATE_CREATE_TIME |
3228                                           AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
3229                                           AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
3230                                           AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
3231
3232         ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
3233                                              pObjectInfo,
3234                                              AuthGroup);
3235
3236         if( !NT_SUCCESS( ntStatus))
3237         {
3238
3239             pObjectInfo->Fcb->Header.ValidDataLength = liSaveVDL;
3240             pObjectInfo->Fcb->Header.FileSize = liSaveSize;
3241             pObjectInfo->Fcb->Header.AllocationSize = liSaveAlloc;
3242             pObjectInfo->Fcb->ObjectInformation->EndOfFile = liSaveSize;
3243             pObjectInfo->Fcb->ObjectInformation->AllocationSize = liSaveAlloc;
3244
3245             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3246                           AFS_TRACE_LEVEL_ERROR,
3247                           "AFSProcessOverwriteSupersede (%p) Failed to update file information %wZ Status %08lX\n",
3248                           Irp,
3249                           &DirectoryCB->NameInformation.FileName,
3250                           ntStatus);
3251
3252             try_return( ntStatus);
3253         }
3254
3255         ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
3256
3257         if( ulCreateDisposition == FILE_SUPERSEDE)
3258         {
3259
3260             pObjectInfo->FileAttributes = ulAttributes;
3261
3262         }
3263         else
3264         {
3265
3266             pObjectInfo->FileAttributes |= ulAttributes;
3267         }
3268
3269         //
3270         // Save off the access for the open
3271         //
3272
3273         if( pObjectInfo->Fcb->OpenHandleCount > 0)
3274         {
3275
3276             IoUpdateShareAccess( pFileObject,
3277                                  &pObjectInfo->Fcb->ShareAccess);
3278         }
3279         else
3280         {
3281
3282             //
3283             // Set the access
3284             //
3285
3286             IoSetShareAccess( *pDesiredAccess,
3287                               usShareAccess,
3288                               pFileObject,
3289                               &pObjectInfo->Fcb->ShareAccess);
3290         }
3291
3292         //
3293         // Return the correct action
3294         //
3295
3296         if( ulCreateDisposition == FILE_SUPERSEDE)
3297         {
3298
3299             Irp->IoStatus.Information = FILE_SUPERSEDED;
3300         }
3301         else
3302         {
3303
3304             Irp->IoStatus.Information = FILE_OVERWRITTEN;
3305         }
3306
3307         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
3308
3309         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3310                       AFS_TRACE_LEVEL_VERBOSE,
3311                       "AFSProcessOverwriteSupersede Increment handle count on Fcb %p Cnt %d\n",
3312                       pObjectInfo->Fcb,
3313                       lCount);
3314
3315         //
3316         // Increment the open reference and handle on the parent node
3317         //
3318
3319         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3320
3321         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3322                       AFS_TRACE_LEVEL_VERBOSE,
3323                       "AFSProcessOverwriteSupersede Increment child open handle count on Parent object %p Cnt %d\n",
3324                       pParentObjectInfo,
3325                       lCount);
3326
3327         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3328
3329         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3330                       AFS_TRACE_LEVEL_VERBOSE,
3331                       "AFSProcessOverwriteSupersede Increment child open ref count on Parent object %p Cnt %d\n",
3332                       pParentObjectInfo,
3333                       lCount);
3334
3335         AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3336
3337         bReleaseFcb = FALSE;
3338
3339         *Fcb = pObjectInfo->Fcb;
3340
3341         //
3342         // Now that the Fcb->Resource has been dropped
3343         // we can call CcSetFileSizes.  We are still holding
3344         // the PagingIoResource
3345         //
3346
3347         pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
3348
3349         pFileObject->FsContext = (void *)pObjectInfo->Fcb;
3350
3351         pFileObject->FsContext2 = (void *)*Ccb;
3352
3353         CcSetFileSizes( pFileObject,
3354                         (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3355
3356 try_exit:
3357
3358         if( bReleasePaging)
3359         {
3360
3361             AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3362         }
3363
3364         if( bReleaseFcb)
3365         {
3366
3367             if( !NT_SUCCESS( ntStatus))
3368             {
3369                 //
3370                 // Decrement the open count on this Fcb.
3371                 //
3372
3373                 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
3374
3375                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3376                               AFS_TRACE_LEVEL_VERBOSE,
3377                               "AFSProcessOverwriteSupersede Decrement2 count on Fcb %p Cnt %d\n",
3378                               pObjectInfo->Fcb,
3379                               lCount);
3380             }
3381
3382             AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3383         }
3384
3385         if( !NT_SUCCESS( ntStatus))
3386         {
3387
3388             if( bAllocatedCcb)
3389             {
3390
3391                 AFSRemoveCcb( NULL,
3392                               *Ccb);
3393             }
3394
3395             *Ccb = NULL;
3396
3397             //
3398             // Fcb will be freed by AFSPrimaryVolumeWorker thread
3399             //
3400
3401             *Fcb = NULL;
3402         }
3403     }
3404
3405     return ntStatus;
3406 }
3407
3408 NTSTATUS
3409 AFSControlDeviceCreate( IN PIRP Irp)
3410 {
3411
3412     NTSTATUS ntStatus = STATUS_SUCCESS;
3413
3414     __Enter
3415     {
3416
3417         if ( KernelMode == Irp->RequestorMode) {
3418             //
3419             // For now, just let the open happen
3420             //
3421             Irp->IoStatus.Information = FILE_OPENED;
3422         }
3423         else
3424         {
3425             //
3426             // Not from usermode, All access must be via
3427             // the FS component (which will do the
3428             // security check)
3429             //
3430             ntStatus = STATUS_ACCESS_DENIED;
3431         }
3432     }
3433
3434     return ntStatus;
3435 }
3436
3437 //
3438 // AFSOpenIOCtlFcb does not release a DirOpenReferenceCount on
3439 // the ParentDirCB.
3440 //
3441
3442 NTSTATUS
3443 AFSOpenIOCtlFcb( IN PIRP Irp,
3444                  IN GUID *AuthGroup,
3445                  IN AFSDirectoryCB *ParentDirCB,
3446                  OUT AFSFcb **Fcb,
3447                  OUT AFSCcb **Ccb)
3448 {
3449
3450     NTSTATUS ntStatus = STATUS_SUCCESS;
3451     PFILE_OBJECT pFileObject = NULL;
3452     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3453     BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
3454     AFSPIOCtlOpenCloseRequestCB stPIOCtlOpen;
3455     AFSFileID stFileID;
3456     AFSObjectInfoCB *pParentObjectInfo = NULL;
3457     LONG lCount;
3458
3459     __Enter
3460     {
3461
3462         pFileObject = pIrpSp->FileObject;
3463
3464         pParentObjectInfo = ParentDirCB->ObjectInformation;
3465
3466         //
3467         // If we haven't initialized the PIOCtl DirectoryCB for this directory then do it now
3468         //
3469
3470         if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB == NULL)
3471         {
3472
3473             ntStatus = AFSInitPIOCtlDirectoryCB( pParentObjectInfo);
3474
3475             if( !NT_SUCCESS( ntStatus))
3476             {
3477
3478                 try_return( ntStatus);
3479             }
3480         }
3481
3482         //
3483         // Allocate and initialize the Fcb for the file.
3484         //
3485
3486         ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB);
3487
3488         *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
3489
3490         if( !NT_SUCCESS( ntStatus))
3491         {
3492
3493             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3494                           AFS_TRACE_LEVEL_ERROR,
3495                           "AFSOpenIOCtlFcb (%p) Failed to initialize fcb Status %08lX\n",
3496                           Irp,
3497                           ntStatus);
3498
3499             try_return( ntStatus);
3500         }
3501
3502         ntStatus = STATUS_SUCCESS;
3503
3504         //
3505         // Increment the open reference and handle on the node
3506         //
3507
3508         lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3509
3510         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3511                       AFS_TRACE_LEVEL_VERBOSE,
3512                       "AFSOpenIOCtlFcb Increment count on Fcb %p Cnt %d\n",
3513                       (*Fcb),
3514                       lCount);
3515
3516         bReleaseFcb = TRUE;
3517
3518         //
3519         // Initialize the Ccb for the file.
3520         //
3521
3522         ntStatus = AFSInitCcb( Ccb,
3523                                pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
3524                                0,
3525                                0);
3526
3527         if( !NT_SUCCESS( ntStatus))
3528         {
3529
3530             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3531                           AFS_TRACE_LEVEL_ERROR,
3532                           "AFSOpenIOCtlFcb (%p) Failed to initialize ccb Status %08lX\n",
3533                           Irp,
3534                           ntStatus);
3535
3536             try_return( ntStatus);
3537         }
3538
3539         bAllocatedCcb = TRUE;
3540
3541         //
3542         // Set the PIOCtl index
3543         //
3544
3545         (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3546
3547         RtlZeroMemory( &stPIOCtlOpen,
3548                        sizeof( AFSPIOCtlOpenCloseRequestCB));
3549
3550         stPIOCtlOpen.RequestId = (*Ccb)->RequestID;
3551
3552         stPIOCtlOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3553
3554         RtlZeroMemory( &stFileID,
3555                        sizeof( AFSFileID));
3556
3557         //
3558         // The parent directory FID of the node
3559         //
3560
3561         stFileID = pParentObjectInfo->FileId;
3562
3563         //
3564         // Issue the open request to the service
3565         //
3566
3567         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_OPEN,
3568                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
3569                                       AuthGroup,
3570                                       NULL,
3571                                       &stFileID,
3572                                       NULL,
3573                                       0,
3574                                       (void *)&stPIOCtlOpen,
3575                                       sizeof( AFSPIOCtlOpenCloseRequestCB),
3576                                       NULL,
3577                                       NULL);
3578
3579         if( !NT_SUCCESS( ntStatus))
3580         {
3581
3582             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3583                           AFS_TRACE_LEVEL_ERROR,
3584                           "AFSOpenIOCtlFcb (%p) Failed service open Status %08lX\n",
3585                           Irp,
3586                           ntStatus);
3587
3588             try_return( ntStatus);
3589         }
3590
3591         //
3592         // Increment the handle on the node
3593         //
3594
3595         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3596
3597         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3598                       AFS_TRACE_LEVEL_VERBOSE,
3599                       "AFSOpenIOCtlFcb Increment handle count on Fcb %p Cnt %d\n",
3600                       (*Fcb),
3601                       lCount);
3602
3603         //
3604         // Increment the open reference and handle on the parent node
3605         //
3606
3607         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3608
3609         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3610                       AFS_TRACE_LEVEL_VERBOSE,
3611                       "AFSOpenIOCtlFcb Increment child open handle count on Parent object %p Cnt %d\n",
3612                       pParentObjectInfo,
3613                       lCount);
3614
3615         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3616
3617         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3618                       AFS_TRACE_LEVEL_VERBOSE,
3619                       "AFSOpenIOCtlFcb Increment child open ref count on Parent object %p Cnt %d\n",
3620                       pParentObjectInfo,
3621                       lCount);
3622
3623         //
3624         // Return the open result for this file
3625         //
3626
3627         Irp->IoStatus.Information = FILE_OPENED;
3628
3629 try_exit:
3630
3631         //
3632         // If we created the Fcb we need to release the resources
3633         //
3634
3635         if( bReleaseFcb)
3636         {
3637
3638             if( !NT_SUCCESS( ntStatus))
3639             {
3640                 //
3641                 // Decrement the open reference and handle on the node
3642                 //
3643
3644                 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3645
3646                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3647                               AFS_TRACE_LEVEL_VERBOSE,
3648                               "AFSOpenIOCtlFcb Decrement count on Fcb %p Cnt %d\n",
3649                               (*Fcb),
3650                               lCount);
3651             }
3652
3653             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3654         }
3655
3656         if( !NT_SUCCESS( ntStatus))
3657         {
3658
3659             if( bAllocatedCcb)
3660             {
3661
3662                 AFSRemoveCcb( NULL,
3663                               *Ccb);
3664             }
3665
3666             *Ccb = NULL;
3667
3668             //
3669             // Fcb will be freed by AFSPrimaryVolumeWorker thread
3670             //
3671
3672             *Fcb = NULL;
3673         }
3674     }
3675
3676     return ntStatus;
3677 }
3678
3679 NTSTATUS
3680 AFSOpenSpecialShareFcb( IN PIRP Irp,
3681                         IN GUID *AuthGroup,
3682                         IN AFSDirectoryCB *DirectoryCB,
3683                         OUT AFSFcb **Fcb,
3684                         OUT AFSCcb **Ccb)
3685 {
3686
3687     NTSTATUS ntStatus = STATUS_SUCCESS;
3688     PFILE_OBJECT pFileObject = NULL;
3689     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3690     BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE, bAllocateFcb = FALSE;
3691     AFSObjectInfoCB *pObjectInfo = NULL;
3692     AFSObjectInfoCB *pParentObjectInfo = NULL;
3693     AFSPipeOpenCloseRequestCB stPipeOpen;
3694     LONG lCount;
3695
3696     __Enter
3697     {
3698
3699         pFileObject = pIrpSp->FileObject;
3700
3701         AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3702                       AFS_TRACE_LEVEL_VERBOSE_2,
3703                       "AFSOpenSpecialShareFcb (%p) Processing Share %wZ open\n",
3704                       Irp,
3705                       &DirectoryCB->NameInformation.FileName);
3706
3707         pObjectInfo = DirectoryCB->ObjectInformation;
3708
3709         if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
3710         {
3711
3712             pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
3713                                                    &pObjectInfo->ParentFileId);
3714         }
3715
3716         if( DirectoryCB->ObjectInformation->Fcb == NULL)
3717         {
3718
3719             //
3720             // Allocate and initialize the Fcb for the file.
3721             //
3722
3723             ntStatus = AFSInitFcb( DirectoryCB);
3724
3725             *Fcb = pObjectInfo->Fcb;
3726
3727             if( !NT_SUCCESS( ntStatus))
3728             {
3729
3730                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3731                               AFS_TRACE_LEVEL_ERROR,
3732                               "AFSOpenSpecialShareFcb (%p) Failed to initialize fcb Status %08lX\n",
3733                               Irp,
3734                               ntStatus);
3735
3736                 try_return( ntStatus);
3737             }
3738
3739             if ( ntStatus != STATUS_REPARSE)
3740             {
3741
3742                 bAllocateFcb = TRUE;
3743             }
3744
3745             ntStatus = STATUS_SUCCESS;
3746         }
3747         else
3748         {
3749
3750             *Fcb = pObjectInfo->Fcb;
3751
3752             AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
3753                             TRUE);
3754         }
3755
3756         //
3757         // Increment the open count on this Fcb
3758         //
3759
3760         lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3761
3762         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3763                       AFS_TRACE_LEVEL_VERBOSE,
3764                       "AFSOpenSpecialShareFcb Increment count on Fcb %p Cnt %d\n",
3765                       (*Fcb),
3766                       lCount);
3767
3768         bReleaseFcb = TRUE;
3769
3770         //
3771         // Initialize the Ccb for the file.
3772         //
3773
3774         ntStatus = AFSInitCcb( Ccb,
3775                                DirectoryCB,
3776                                0,
3777                                0);
3778
3779         if( !NT_SUCCESS( ntStatus))
3780         {
3781
3782             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3783                           AFS_TRACE_LEVEL_ERROR,
3784                           "AFSOpenSpecialShareFcb (%p) Failed to initialize ccb Status %08lX\n",
3785                           Irp,
3786                           ntStatus);
3787
3788             try_return( ntStatus);
3789         }
3790
3791         bAllocatedCcb = TRUE;
3792
3793         //
3794         // Call the service to open the share
3795         //
3796
3797         (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3798
3799         RtlZeroMemory( &stPipeOpen,
3800                        sizeof( AFSPipeOpenCloseRequestCB));
3801
3802         stPipeOpen.RequestId = (*Ccb)->RequestID;
3803
3804         stPipeOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3805
3806         //
3807         // Issue the open request to the service
3808         //
3809
3810         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_OPEN,
3811                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
3812                                       AuthGroup,
3813                                       &DirectoryCB->NameInformation.FileName,
3814                                       NULL,
3815                                       NULL,
3816                                       0,
3817                                       (void *)&stPipeOpen,
3818                                       sizeof( AFSPipeOpenCloseRequestCB),
3819                                       NULL,
3820                                       NULL);
3821
3822         if( !NT_SUCCESS( ntStatus))
3823         {
3824
3825             AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3826                           AFS_TRACE_LEVEL_ERROR,
3827                           "AFSOpenSpecialShareFcb (%p) Failed service open Status %08lX\n",
3828                           Irp,
3829                           ntStatus);
3830
3831             try_return( ntStatus);
3832         }
3833
3834         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3835
3836         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3837                       AFS_TRACE_LEVEL_VERBOSE,
3838                       "AFSOpenSpecialShareFcb Increment handle count on Fcb %p Cnt %d\n",
3839                       (*Fcb),
3840                       lCount);
3841
3842         //
3843         // Increment the open reference and handle on the parent node
3844         //
3845
3846         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3847
3848         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3849                       AFS_TRACE_LEVEL_VERBOSE,
3850                       "AFSOpenSpecialShareFcb Increment child open handle count on Parent object %p Cnt %d\n",
3851                       pParentObjectInfo,
3852                       lCount);
3853
3854         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3855
3856         AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3857                       AFS_TRACE_LEVEL_VERBOSE,
3858                       "AFSOpenSpecialShareFcb Increment child open ref count on Parent object %p Cnt %d\n",
3859                       pParentObjectInfo,
3860                       lCount);
3861
3862         //
3863         // Return the open result for this file
3864         //
3865
3866         Irp->IoStatus.Information = FILE_OPENED;
3867
3868 try_exit:
3869
3870         if( bReleaseFcb)
3871         {
3872
3873             if( !NT_SUCCESS( ntStatus))
3874             {
3875                 //
3876                 // Decrement the open count on this Fcb
3877                 //
3878
3879                 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3880
3881                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3882                               AFS_TRACE_LEVEL_VERBOSE,
3883                               "AFSOpenSpecialShareFcb Decrement count on Fcb %p Cnt %d\n",
3884                               (*Fcb),
3885                               lCount);
3886             }
3887
3888             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3889         }
3890
3891         if( !NT_SUCCESS( ntStatus))
3892         {
3893
3894             if( bAllocatedCcb)
3895             {
3896
3897                 AFSRemoveCcb( NULL,
3898                               *Ccb);
3899             }
3900
3901             *Ccb = NULL;
3902
3903             if( bAllocateFcb)
3904             {
3905
3906                 //
3907                 // Need to tear down this Fcb since it is not in the tree for the worker thread
3908                 //
3909
3910                 AFSAcquireExcl( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
3911                                 TRUE);
3912
3913                 AFSRemoveFcb( &DirectoryCB->ObjectInformation->Fcb);
3914
3915                 AFSReleaseResource( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
3916             }
3917
3918             *Fcb = NULL;
3919         }
3920     }
3921
3922     return ntStatus;
3923 }