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