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