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