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