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