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