0fbf686befa7e663e33566bb138c15ffa90a7639
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSCreate.cpp
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3  * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  *   this list of conditions and the following disclaimer.
12  * - Redistributions in binary form must reproduce the above copyright
13  *   notice,
14  *   this list of conditions and the following disclaimer in the
15  *   documentation
16  *   and/or other materials provided with the distribution.
17  * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18  *   nor the names of their contributors may be used to endorse or promote
19  *   products derived from this software without specific prior written
20  *   permission from Kernel Drivers, LLC and Your File System, Inc.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 //
36 // File: AFSCreate.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 //
42 // Function: AFSCreate
43 //
44 // Description:
45 //
46 //      This function is the dispatch handler for the IRP_MJ_CREATE requests. It makes the determination to
47 //      which interface this request is destined.
48 //
49 // Return:
50 //
51 //      A status is returned for the function. The Irp completion processing is handled in the specific
52 //      interface handler.
53 //
54
55 NTSTATUS
56 AFSCreate( IN PDEVICE_OBJECT LibDeviceObject,
57            IN PIRP Irp)
58 {
59
60     NTSTATUS ntStatus = STATUS_SUCCESS;
61     IO_STACK_LOCATION  *pIrpSp;
62     FILE_OBJECT        *pFileObject = NULL;
63
64     __try
65     {
66
67         pIrpSp = IoGetCurrentIrpStackLocation( Irp);
68         pFileObject = pIrpSp->FileObject;
69
70         if( pFileObject == NULL ||
71             pFileObject->FileName.Buffer == NULL)
72         {
73
74             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
75                           AFS_TRACE_LEVEL_VERBOSE,
76                           "AFSCreate (%08lX) Processing control device open request\n",
77                           Irp);
78
79             ntStatus = AFSControlDeviceCreate( Irp);
80
81             try_return( ntStatus);
82         }
83
84         if( AFSRDRDeviceObject == NULL)
85         {
86
87             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
88                           AFS_TRACE_LEVEL_VERBOSE,
89                           "AFSCreate (%08lX) Invalid request to open before library is initialized\n",
90                           Irp);
91
92             try_return( ntStatus = STATUS_DEVICE_NOT_READY);
93         }
94
95         ntStatus = AFSCommonCreate( AFSRDRDeviceObject,
96                                     Irp);
97
98 try_exit:
99
100         NOTHING;
101     }
102     __except( AFSExceptionFilter( __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, uniPathName, 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;
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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) FileObject %08lX 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 (%08lX) Returning with NULL Fcb FileObject %08lX 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 (%08lX) STATUS_REPARSE FileObject %08lX 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
1319         if( !NT_SUCCESS( ntStatus))
1320         {
1321
1322             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1323                           AFS_TRACE_LEVEL_ERROR,
1324                           "AFSOpenAFSRoot (%08lX) Failed to allocate Ccb\n",
1325                           Irp);
1326
1327             try_return( ntStatus);
1328         }
1329
1330         //
1331         // Setup the Ccb
1332         //
1333
1334         (*Ccb)->DirectoryCB = AFSGlobalRoot->DirectoryCB;
1335
1336         //
1337         // Increment the open count on this Fcb
1338         //
1339
1340         lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1341
1342         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1343                       AFS_TRACE_LEVEL_VERBOSE,
1344                       "AFSOpenAFSRoot Increment count on Fcb %08lX Cnt %d\n",
1345                       AFSGlobalRoot->RootFcb,
1346                       lCount);
1347
1348         lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1349
1350         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1351                       AFS_TRACE_LEVEL_VERBOSE,
1352                       "AFSOpenAFSRoot Increment handle count on Fcb %08lX Cnt %d\n",
1353                       AFSGlobalRoot->RootFcb,
1354                       lCount);
1355
1356         *Fcb = AFSGlobalRoot->RootFcb;
1357
1358         //
1359         // Return the open result for this file
1360         //
1361
1362         Irp->IoStatus.Information = FILE_OPENED;
1363
1364 try_exit:
1365
1366         NOTHING;
1367     }
1368
1369     return ntStatus;
1370 }
1371
1372 NTSTATUS
1373 AFSOpenRoot( IN PIRP Irp,
1374              IN AFSVolumeCB *VolumeCB,
1375              IN GUID *AuthGroup,
1376              OUT AFSFcb **RootFcb,
1377              OUT AFSCcb **Ccb)
1378 {
1379
1380     NTSTATUS ntStatus = STATUS_SUCCESS;
1381     PFILE_OBJECT pFileObject = NULL;
1382     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1383     PACCESS_MASK pDesiredAccess = NULL;
1384     USHORT usShareAccess;
1385     ULONG ulOptions;
1386     BOOLEAN bAllocatedCcb = FALSE;
1387     BOOLEAN bReleaseFcb = FALSE;
1388     AFSFileOpenCB   stOpenCB;
1389     AFSFileOpenResultCB stOpenResultCB;
1390     ULONG       ulResultLen = 0;
1391     LONG        lCount;
1392
1393     __Enter
1394     {
1395
1396         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1397         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1398         ulOptions = pIrpSp->Parameters.Create.Options;
1399
1400         pFileObject = pIrpSp->FileObject;
1401
1402         if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1403         {
1404
1405             ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1406
1407             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1408                           AFS_TRACE_LEVEL_ERROR,
1409                           "AFSOpenRoot (%08lX) Attempt to open root as file Status %08lX\n",
1410                           Irp,
1411                           ntStatus);
1412
1413             try_return( ntStatus);
1414         }
1415
1416         //
1417         // Check if we should go and retrieve updated information for the node
1418         //
1419
1420         ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1421                                      AuthGroup,
1422                                      FALSE,
1423                                      TRUE);
1424
1425         if( !NT_SUCCESS( ntStatus))
1426         {
1427
1428             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1429                           AFS_TRACE_LEVEL_ERROR,
1430                           "AFSOpenRoot (%08lX) Failed to validate root entry Status %08lX\n",
1431                           Irp,
1432                           ntStatus);
1433
1434             try_return( ntStatus);
1435         }
1436
1437         //
1438         // Check with the service that we can open the file
1439         //
1440
1441         RtlZeroMemory( &stOpenCB,
1442                        sizeof( AFSFileOpenCB));
1443
1444         stOpenCB.DesiredAccess = *pDesiredAccess;
1445
1446         stOpenCB.ShareAccess = usShareAccess;
1447
1448         stOpenResultCB.GrantedAccess = 0;
1449
1450         ulResultLen = sizeof( AFSFileOpenResultCB);
1451
1452         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1453                                       AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1454                                       AuthGroup,
1455                                       NULL,
1456                                       &VolumeCB->ObjectInformation.FileId,
1457                                       (void *)&stOpenCB,
1458                                       sizeof( AFSFileOpenCB),
1459                                       (void *)&stOpenResultCB,
1460                                       &ulResultLen);
1461
1462         if( !NT_SUCCESS( ntStatus))
1463         {
1464
1465             UNICODE_STRING uniGUID;
1466
1467             uniGUID.Length = 0;
1468             uniGUID.MaximumLength = 0;
1469             uniGUID.Buffer = NULL;
1470
1471             if( AuthGroup != NULL)
1472             {
1473                 RtlStringFromGUID( *AuthGroup,
1474                                    &uniGUID);
1475             }
1476
1477             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1478                           AFS_TRACE_LEVEL_ERROR,
1479                           "AFSOpenRoot (%08lX) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1480                           Irp,
1481                           VolumeCB->ObjectInformation.FileId.Cell,
1482                           VolumeCB->ObjectInformation.FileId.Volume,
1483                           &uniGUID,
1484                           ntStatus);
1485
1486             if( AuthGroup != NULL)
1487             {
1488                 RtlFreeUnicodeString( &uniGUID);
1489             }
1490
1491             try_return( ntStatus);
1492         }
1493
1494         //
1495         // If the entry is not initialized then do it now
1496         //
1497
1498         if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1499         {
1500
1501             AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1502                             TRUE);
1503
1504             if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1505             {
1506
1507                 ntStatus = AFSEnumerateDirectory( AuthGroup,
1508                                                   &VolumeCB->ObjectInformation,
1509                                                   TRUE);
1510
1511                 if( !NT_SUCCESS( ntStatus))
1512                 {
1513
1514                     AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1515
1516                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1517                                   AFS_TRACE_LEVEL_ERROR,
1518                                   "AFSOpenRoot (%08lX) Failed to enumerate directory Status %08lX\n",
1519                                   Irp,
1520                                   ntStatus);
1521
1522                     try_return( ntStatus);
1523                 }
1524
1525                 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1526             }
1527
1528             AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1529         }
1530
1531         //
1532         // If the root fcb has been initialized then check access otherwise
1533         // init the volume fcb
1534         //
1535
1536         if( VolumeCB->RootFcb == NULL)
1537         {
1538
1539             ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1540                                        VolumeCB);
1541
1542             if( !NT_SUCCESS( ntStatus))
1543             {
1544
1545                 try_return( ntStatus);
1546             }
1547         }
1548         else
1549         {
1550
1551             AFSAcquireExcl( VolumeCB->RootFcb->Header.Resource,
1552                             TRUE);
1553         }
1554
1555         bReleaseFcb = TRUE;
1556
1557         //
1558         // If there are current opens on the Fcb, check the access.
1559         //
1560
1561         if( VolumeCB->RootFcb->OpenHandleCount > 0)
1562         {
1563
1564             ntStatus = IoCheckShareAccess( *pDesiredAccess,
1565                                            usShareAccess,
1566                                            pFileObject,
1567                                            &VolumeCB->RootFcb->ShareAccess,
1568                                            FALSE);
1569
1570             if( !NT_SUCCESS( ntStatus))
1571             {
1572
1573                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1574                               AFS_TRACE_LEVEL_ERROR,
1575                               "AFSOpenRoot (%08lX) Access check failure Status %08lX\n",
1576                               Irp,
1577                               ntStatus);
1578
1579                 try_return( ntStatus);
1580             }
1581         }
1582
1583         //
1584         // Initialize the Ccb for the file.
1585         //
1586
1587         ntStatus = AFSInitCcb( Ccb);
1588
1589         if( !NT_SUCCESS( ntStatus))
1590         {
1591
1592             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1593                           AFS_TRACE_LEVEL_ERROR,
1594                           "AFSOpenRoot (%08lX) Failed to allocate Ccb Status %08lX\n",
1595                           Irp,
1596                           ntStatus);
1597
1598             try_return( ntStatus);
1599         }
1600
1601         bAllocatedCcb = TRUE;
1602
1603         //
1604         // Setup the ccb
1605         //
1606
1607         (*Ccb)->DirectoryCB = VolumeCB->DirectoryCB;
1608
1609         (*Ccb)->GrantedAccess = *pDesiredAccess;
1610
1611         //
1612         // OK, update the share access on the fileobject
1613         //
1614
1615         if( VolumeCB->RootFcb->OpenHandleCount > 0)
1616         {
1617
1618             IoUpdateShareAccess( pFileObject,
1619                                  &VolumeCB->RootFcb->ShareAccess);
1620         }
1621         else
1622         {
1623
1624             //
1625             // Set the access
1626             //
1627
1628             IoSetShareAccess( *pDesiredAccess,
1629                               usShareAccess,
1630                               pFileObject,
1631                               &VolumeCB->RootFcb->ShareAccess);
1632         }
1633
1634         //
1635         // Increment the open count on this Fcb
1636         //
1637
1638         lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1639
1640         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1641                       AFS_TRACE_LEVEL_VERBOSE,
1642                       "AFSOpenRoot Increment count on Fcb %08lX Cnt %d\n",
1643                       VolumeCB->RootFcb,
1644                       lCount);
1645
1646         lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1647
1648         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1649                       AFS_TRACE_LEVEL_VERBOSE,
1650                       "AFSOpenRoot Increment handle count on Fcb %08lX Cnt %d\n",
1651                       VolumeCB->RootFcb,
1652                       lCount);
1653
1654         //
1655         // Indicate the object is held
1656         //
1657
1658         SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1659
1660         //
1661         // Return the open result for this file
1662         //
1663
1664         Irp->IoStatus.Information = FILE_OPENED;
1665
1666         *RootFcb = VolumeCB->RootFcb;
1667
1668 try_exit:
1669
1670         if( bReleaseFcb)
1671         {
1672
1673             AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1674         }
1675
1676         if( !NT_SUCCESS( ntStatus))
1677         {
1678
1679             if( bAllocatedCcb)
1680             {
1681
1682                 AFSRemoveCcb( NULL,
1683                               *Ccb);
1684
1685                 *Ccb = NULL;
1686             }
1687
1688             Irp->IoStatus.Information = 0;
1689         }
1690     }
1691
1692     return ntStatus;
1693 }
1694
1695 NTSTATUS
1696 AFSProcessCreate( IN PIRP               Irp,
1697                   IN GUID              *AuthGroup,
1698                   IN AFSVolumeCB       *VolumeCB,
1699                   IN AFSDirectoryCB    *ParentDirCB,
1700                   IN PUNICODE_STRING    FileName,
1701                   IN PUNICODE_STRING    ComponentName,
1702                   IN PUNICODE_STRING    FullFileName,
1703                   OUT AFSFcb          **Fcb,
1704                   OUT AFSCcb          **Ccb)
1705 {
1706
1707     NTSTATUS ntStatus = STATUS_SUCCESS;
1708     PFILE_OBJECT pFileObject = NULL;
1709     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1710     ULONG ulOptions = 0;
1711     ULONG ulShareMode = 0;
1712     ULONG ulAccess = 0;
1713     ULONG ulAttributes = 0;
1714     LARGE_INTEGER   liAllocationSize = {0,0};
1715     BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1716     PACCESS_MASK pDesiredAccess = NULL;
1717     USHORT usShareAccess;
1718     AFSDirectoryCB *pDirEntry = NULL;
1719     AFSObjectInfoCB *pParentObjectInfo = NULL;
1720     AFSObjectInfoCB *pObjectInfo = NULL;
1721     LONG lCount;
1722
1723     __Enter
1724     {
1725
1726         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1727         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1728
1729         pFileObject = pIrpSp->FileObject;
1730
1731         //
1732         // Extract out the options
1733         //
1734
1735         ulOptions = pIrpSp->Parameters.Create.Options;
1736
1737         //
1738         // We pass all attributes they want to apply to the file to the create
1739         //
1740
1741         ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1742
1743         //
1744         // If this is a directory create then set the attribute correctly
1745         //
1746
1747         if( ulOptions & FILE_DIRECTORY_FILE)
1748         {
1749
1750             ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1751         }
1752
1753         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1754                       AFS_TRACE_LEVEL_VERBOSE,
1755                       "AFSProcessCreate (%08lX) Creating file %wZ Attributes %08lX\n",
1756                       Irp,
1757                       FullFileName,
1758                       ulAttributes);
1759
1760         if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1761         {
1762
1763             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1764                           AFS_TRACE_LEVEL_ERROR,
1765                           "AFSProcessCreate Request failed due to read only volume %wZ\n",
1766                           FullFileName);
1767
1768             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
1769         }
1770
1771         pParentObjectInfo = ParentDirCB->ObjectInformation;
1772
1773         //
1774         // Allocate and insert the direntry into the parent node
1775         //
1776
1777         ntStatus = AFSCreateDirEntry( AuthGroup,
1778                                       pParentObjectInfo,
1779                                       ParentDirCB,
1780                                       FileName,
1781                                       ComponentName,
1782                                       ulAttributes,
1783                                       &pDirEntry);
1784
1785         if( !NT_SUCCESS( ntStatus))
1786         {
1787
1788             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1789                           AFS_TRACE_LEVEL_ERROR,
1790                           "AFSProcessCreate (%08lX) Failed to create directory entry %wZ Status %08lX\n",
1791                           Irp,
1792                           FullFileName,
1793                           ntStatus);
1794
1795             try_return( ntStatus);
1796         }
1797
1798         bFileCreated = TRUE;
1799
1800         pObjectInfo = pDirEntry->ObjectInformation;
1801
1802         if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1803             pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1804         {
1805
1806             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1807                           AFS_TRACE_LEVEL_VERBOSE,
1808                           "AFSProcessCreate (%08lX) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1809                           Irp,
1810                           &pDirEntry->NameInformation.FileName,
1811                           pObjectInfo->FileId.Cell,
1812                           pObjectInfo->FileId.Volume,
1813                           pObjectInfo->FileId.Vnode,
1814                           pObjectInfo->FileId.Unique);
1815
1816             ntStatus = AFSEvaluateNode( AuthGroup,
1817                                         pDirEntry);
1818
1819             if( !NT_SUCCESS( ntStatus))
1820             {
1821
1822                 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
1823                 {
1824
1825                     if ( pParentObjectInfo == pObjectInfo->ParentObjectInformation)
1826                     {
1827
1828                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1829                                       AFS_TRACE_LEVEL_ERROR,
1830                                       "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1831                                       Irp,
1832                                       &pDirEntry->NameInformation.FileName,
1833                                       pObjectInfo->FileId.Cell,
1834                                       pObjectInfo->FileId.Volume,
1835                                       pObjectInfo->FileId.Vnode,
1836                                       pObjectInfo->FileId.Unique,
1837                                       pParentObjectInfo->FileId.Cell,
1838                                       pParentObjectInfo->FileId.Volume,
1839                                       pParentObjectInfo->FileId.Vnode,
1840                                       pParentObjectInfo->FileId.Unique,
1841                                       ntStatus);
1842                     }
1843                     else if ( pObjectInfo->ParentObjectInformation == NULL)
1844                     {
1845
1846                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1847                                       AFS_TRACE_LEVEL_ERROR,
1848                                       "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
1849                                       Irp,
1850                                       &pDirEntry->NameInformation.FileName,
1851                                       pObjectInfo->FileId.Cell,
1852                                       pObjectInfo->FileId.Volume,
1853                                       pObjectInfo->FileId.Vnode,
1854                                       pObjectInfo->FileId.Unique,
1855                                       pParentObjectInfo->FileId.Cell,
1856                                       pParentObjectInfo->FileId.Volume,
1857                                       pParentObjectInfo->FileId.Vnode,
1858                                       pParentObjectInfo->FileId.Unique,
1859                                       ntStatus);
1860                     }
1861                     else
1862                     {
1863
1864                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1865                                       AFS_TRACE_LEVEL_ERROR,
1866                                       "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1867                                       Irp,
1868                                       &pDirEntry->NameInformation.FileName,
1869                                       pObjectInfo->FileId.Cell,
1870                                       pObjectInfo->FileId.Volume,
1871                                       pObjectInfo->FileId.Vnode,
1872                                       pObjectInfo->FileId.Unique,
1873                                       pParentObjectInfo->FileId.Cell,
1874                                       pParentObjectInfo->FileId.Volume,
1875                                       pParentObjectInfo->FileId.Vnode,
1876                                       pParentObjectInfo->FileId.Unique,
1877                                       pObjectInfo->ParentObjectInformation->FileId.Cell,
1878                                       pObjectInfo->ParentObjectInformation->FileId.Volume,
1879                                       pObjectInfo->ParentObjectInformation->FileId.Vnode,
1880                                       pObjectInfo->ParentObjectInformation->FileId.Unique,
1881                                       ntStatus);
1882                     }
1883                 }
1884                 else
1885                 {
1886
1887                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1888                                   AFS_TRACE_LEVEL_ERROR,
1889                                   "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1890                                   Irp,
1891                                   &pDirEntry->NameInformation.FileName,
1892                                   pObjectInfo->FileId.Cell,
1893                                   pObjectInfo->FileId.Volume,
1894                                   pObjectInfo->FileId.Vnode,
1895                                   pObjectInfo->FileId.Unique,
1896                                   ntStatus);
1897                 }
1898
1899                 try_return( ntStatus);
1900             }
1901
1902             ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1903         }
1904
1905         //
1906         // We may have raced and the Fcb is already created
1907         //
1908
1909         //
1910         // Allocate and initialize the Fcb for the file.
1911         //
1912
1913         ntStatus = AFSInitFcb( pDirEntry);
1914
1915         *Fcb = pObjectInfo->Fcb;
1916
1917         if( !NT_SUCCESS( ntStatus))
1918         {
1919
1920             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1921                           AFS_TRACE_LEVEL_ERROR,
1922                           "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
1923                           Irp,
1924                           FullFileName,
1925                           ntStatus);
1926
1927             try_return( ntStatus);
1928         }
1929
1930         ntStatus = STATUS_SUCCESS;
1931
1932         //
1933         // Increment the open count on this Fcb
1934         //
1935
1936         lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1937
1938         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1939                       AFS_TRACE_LEVEL_VERBOSE,
1940                       "AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n",
1941                       *Fcb,
1942                       lCount);
1943
1944         bReleaseFcb = TRUE;
1945
1946         //
1947         // Initialize the Ccb for the file.
1948         //
1949
1950         ntStatus = AFSInitCcb( Ccb);
1951
1952         if( !NT_SUCCESS( ntStatus))
1953         {
1954
1955             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1956                           AFS_TRACE_LEVEL_ERROR,
1957                           "AFSProcessCreate (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
1958                           Irp,
1959                           FullFileName,
1960                           ntStatus);
1961
1962             try_return( ntStatus);
1963         }
1964
1965         bAllocatedCcb = TRUE;
1966
1967         //
1968         // Initialize the Ccb
1969         //
1970
1971         (*Ccb)->DirectoryCB = pDirEntry;
1972
1973         (*Ccb)->GrantedAccess = *pDesiredAccess;
1974
1975         //
1976         // If this is a file, update the headers filesizes.
1977         //
1978
1979         if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1980         {
1981
1982             //
1983             // Update the sizes with the information passed in
1984             //
1985
1986             (*Fcb)->Header.AllocationSize.QuadPart  = pObjectInfo->AllocationSize.QuadPart;
1987             (*Fcb)->Header.FileSize.QuadPart        = pObjectInfo->EndOfFile.QuadPart;
1988             (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1989
1990             //
1991             // Notify the system of the addition
1992             //
1993
1994             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1995                                             *Ccb,
1996                                             (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1997                                             (ULONG)FILE_ACTION_ADDED);
1998
1999             (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2000         }
2001         else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2002         {
2003
2004             //
2005             // This is a new directory node so indicate it has been enumerated
2006             //
2007
2008             SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
2009
2010             //
2011             // And the parent directory entry
2012             //
2013
2014             KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2015
2016             //
2017             // Notify the system of the addition
2018             //
2019
2020             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2021                                             *Ccb,
2022                                             (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2023                                             (ULONG)FILE_ACTION_ADDED);
2024         }
2025         else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2026                  (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2027                  (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2028                  (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
2029         {
2030
2031             //
2032             // And the parent directory entry
2033             //
2034
2035             KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2036
2037             //
2038             // Notify the system of the addition
2039             //
2040
2041             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2042                                             *Ccb,
2043                                             (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2044                                             (ULONG)FILE_ACTION_ADDED);
2045         }
2046
2047         //
2048         // Save off the access for the open
2049         //
2050
2051         IoSetShareAccess( *pDesiredAccess,
2052                           usShareAccess,
2053                           pFileObject,
2054                           &(*Fcb)->ShareAccess);
2055
2056         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2057
2058         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2059                       AFS_TRACE_LEVEL_VERBOSE,
2060                       "AFSProcessCreate Increment handle count on Fcb %08lX Cnt %d\n",
2061                       (*Fcb),
2062                       lCount);
2063
2064         //
2065         // Increment the open reference and handle on the parent node
2066         //
2067
2068         lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2069
2070         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2071                       AFS_TRACE_LEVEL_VERBOSE,
2072                       "AFSProcessCreate Increment child open handle count on Parent object %08lX Cnt %d\n",
2073                       pObjectInfo->ParentObjectInformation,
2074                       lCount);
2075
2076         lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2077
2078         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2079                       AFS_TRACE_LEVEL_VERBOSE,
2080                       "AFSProcessCreate Increment child open ref count on Parent object %08lX Cnt %d\n",
2081                       pObjectInfo->ParentObjectInformation,
2082                       lCount);
2083
2084         if( ulOptions & FILE_DELETE_ON_CLOSE)
2085         {
2086
2087             //
2088             // Mark it for delete on close
2089             //
2090
2091             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2092                           AFS_TRACE_LEVEL_VERBOSE,
2093                           "AFSProcessCreate (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2094                           Irp,
2095                           pDirEntry,
2096                           FullFileName);
2097
2098             SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2099         }
2100
2101         //
2102         // Indicate the object is locked in the service
2103         //
2104
2105         SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2106
2107         //
2108         // Return the open result for this file
2109         //
2110
2111         Irp->IoStatus.Information = FILE_CREATED;
2112
2113 try_exit:
2114
2115         //
2116         // If we created the Fcb we need to release the resources
2117         //
2118
2119         if( bReleaseFcb)
2120         {
2121
2122             if( !NT_SUCCESS( ntStatus))
2123             {
2124                 //
2125                 // Decrement the open count on this Fcb
2126                 //
2127
2128                 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2129
2130                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2131                               AFS_TRACE_LEVEL_VERBOSE,
2132                               "AFSProcessCreate Decrement count on Fcb %08lX Cnt %d\n",
2133                               *Fcb,
2134                               lCount);
2135             }
2136
2137             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2138         }
2139
2140         if( !NT_SUCCESS( ntStatus))
2141         {
2142
2143             if( bFileCreated)
2144             {
2145
2146                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2147                               AFS_TRACE_LEVEL_VERBOSE,
2148                               "AFSProcessCreate Create failed, removing DE %p from aprent object %p Status %08lX\n",
2149                               pDirEntry,
2150                               pParentObjectInfo,
2151                               ntStatus);
2152
2153                 //
2154                 // Remove the dir entry from the parent
2155                 //
2156
2157                 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2158                                 TRUE);
2159
2160                 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2161
2162                 AFSNotifyDelete( pDirEntry,
2163                                  AuthGroup,
2164                                  FALSE);
2165
2166                 //
2167                 // Decrement the reference added during initialization of the DE
2168                 //
2169
2170                 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2171
2172                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2173                               AFS_TRACE_LEVEL_VERBOSE,
2174                               "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2175                               &pDirEntry->NameInformation.FileName,
2176                               pDirEntry,
2177                               lCount);
2178
2179                 ASSERT( lCount >= 0);
2180
2181                 //
2182                 // Pull the directory entry from the parent
2183                 //
2184
2185                 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2186                                             pDirEntry,
2187                                             FALSE); // Leave it in the enum list so the worker cleans it up
2188
2189                 //
2190                 // Tag the parent as needing verification
2191                 //
2192
2193                 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2194
2195                 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2196
2197                 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2198             }
2199
2200             if( bAllocatedCcb)
2201             {
2202
2203                 AFSRemoveCcb( NULL,
2204                               *Ccb);
2205             }
2206
2207             //
2208             // Fcb will be freed by AFSPrimaryVolumeWorker thread
2209             //
2210
2211             *Fcb = NULL;
2212
2213             *Ccb = NULL;
2214         }
2215     }
2216
2217     return ntStatus;
2218 }
2219
2220 NTSTATUS
2221 AFSOpenTargetDirectory( IN PIRP Irp,
2222                         IN AFSVolumeCB *VolumeCB,
2223                         IN AFSDirectoryCB *ParentDirectoryCB,
2224                         IN AFSDirectoryCB *TargetDirectoryCB,
2225                         IN UNICODE_STRING *TargetName,
2226                         OUT AFSFcb **Fcb,
2227                         OUT AFSCcb **Ccb)
2228 {
2229
2230     NTSTATUS ntStatus = STATUS_SUCCESS;
2231     PFILE_OBJECT pFileObject = NULL;
2232     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2233     PACCESS_MASK pDesiredAccess = NULL;
2234     USHORT usShareAccess;
2235     BOOLEAN bAllocatedCcb = FALSE;
2236     BOOLEAN bReleaseFcb = FALSE;
2237     AFSObjectInfoCB *pParentObject = NULL, *pTargetObject = NULL;
2238     UNICODE_STRING uniTargetName;
2239     LONG lCount;
2240
2241     __Enter
2242     {
2243
2244         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2245         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2246
2247         pFileObject = pIrpSp->FileObject;
2248
2249         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2250                       AFS_TRACE_LEVEL_VERBOSE,
2251                       "AFSOpenTargetDirectory (%08lX) Processing file %wZ\n",
2252                       Irp,
2253                       TargetName);
2254
2255         pParentObject = ParentDirectoryCB->ObjectInformation;
2256
2257         if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2258         {
2259
2260             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2261         }
2262
2263         //
2264         // Make sure we have an Fcb for the access
2265
2266         //
2267         // Allocate and initialize the Fcb for the file.
2268         //
2269
2270         ntStatus = AFSInitFcb( ParentDirectoryCB);
2271
2272         *Fcb = pParentObject->Fcb;
2273
2274         if( !NT_SUCCESS( ntStatus))
2275         {
2276
2277             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2278                           AFS_TRACE_LEVEL_ERROR,
2279                           "AFSOpenTargetDirectory (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
2280                           Irp,
2281                           &ParentDirectoryCB->NameInformation.FileName,
2282                           ntStatus);
2283
2284             try_return( ntStatus);
2285         }
2286
2287         ntStatus = STATUS_SUCCESS;
2288
2289         //
2290         // Increment the open count on this Fcb
2291         //
2292
2293         lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2294
2295         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2296                       AFS_TRACE_LEVEL_VERBOSE,
2297                       "AFSOpenTargetDirectory Increment count on Fcb %08lX Cnt %d\n",
2298                       pParentObject->Fcb,
2299                       lCount);
2300
2301         bReleaseFcb = TRUE;
2302
2303         //
2304         // If there are current opens on the Fcb, check the access.
2305         //
2306
2307         if( pParentObject->Fcb->OpenHandleCount > 0)
2308         {
2309
2310             ntStatus = IoCheckShareAccess( *pDesiredAccess,
2311                                            usShareAccess,
2312                                            pFileObject,
2313                                            &pParentObject->Fcb->ShareAccess,
2314                                            FALSE);
2315
2316             if( !NT_SUCCESS( ntStatus))
2317             {
2318
2319                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2320                               AFS_TRACE_LEVEL_ERROR,
2321                               "AFSOpenTargetDirectory (%08lX) Access check failure %wZ Status %08lX\n",
2322                               Irp,
2323                               &ParentDirectoryCB->NameInformation.FileName,
2324                               ntStatus);
2325
2326                 try_return( ntStatus);
2327             }
2328         }
2329
2330         //
2331         // Initialize the Ccb for the file.
2332         //
2333
2334         ntStatus = AFSInitCcb( Ccb);
2335
2336         if( !NT_SUCCESS( ntStatus))
2337         {
2338
2339             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2340                           AFS_TRACE_LEVEL_ERROR,
2341                           "AFSOpenTargetDirectory (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2342                           Irp,
2343                           &ParentDirectoryCB->NameInformation.FileName,
2344                           ntStatus);
2345
2346             try_return( ntStatus);
2347         }
2348
2349         bAllocatedCcb = TRUE;
2350
2351         //
2352         // Initialize the Ccb
2353         //
2354
2355         (*Ccb)->DirectoryCB = ParentDirectoryCB;
2356
2357         (*Ccb)->GrantedAccess = *pDesiredAccess;
2358
2359         if( TargetDirectoryCB != NULL &&
2360             FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2361                                 TargetName,
2362                                 FALSE,
2363                                 NULL))
2364         {
2365
2366             Irp->IoStatus.Information = FILE_EXISTS;
2367
2368             uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2369         }
2370         else
2371         {
2372
2373             Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2374
2375             uniTargetName = *TargetName;
2376         }
2377
2378         //
2379         // Update the filename in the fileobject for rename processing
2380         //
2381
2382         RtlCopyMemory( pFileObject->FileName.Buffer,
2383                        uniTargetName.Buffer,
2384                        uniTargetName.Length);
2385
2386         pFileObject->FileName.Length = uniTargetName.Length;
2387
2388         //
2389         // OK, update the share access on the fileobject
2390         //
2391
2392         if( pParentObject->Fcb->OpenHandleCount > 0)
2393         {
2394
2395             IoUpdateShareAccess( pFileObject,
2396                                  &pParentObject->Fcb->ShareAccess);
2397         }
2398         else
2399         {
2400
2401             //
2402             // Set the access
2403             //
2404
2405             IoSetShareAccess( *pDesiredAccess,
2406                               usShareAccess,
2407                               pFileObject,
2408                               &pParentObject->Fcb->ShareAccess);
2409         }
2410
2411         lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2412
2413         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2414                       AFS_TRACE_LEVEL_VERBOSE,
2415                       "AFSOpenTargetDirectory Increment handle count on Fcb %08lX Cnt %d\n",
2416                       pParentObject->Fcb,
2417                       lCount);
2418
2419         //
2420         // Increment the open reference and handle on the parent node
2421         //
2422
2423         if( pParentObject->ParentObjectInformation != NULL)
2424         {
2425
2426             lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2427
2428             AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2429                           AFS_TRACE_LEVEL_VERBOSE,
2430                           "AFSOpenTargetDirectory Increment child open handle count on Parent object %08lX Cnt %d\n",
2431                           pParentObject->ParentObjectInformation,
2432                           lCount);
2433
2434             lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2435
2436             AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2437                           AFS_TRACE_LEVEL_VERBOSE,
2438                           "AFSOpenTargetDirectory Increment child open ref count on Parent object %08lX Cnt %d\n",
2439                           pParentObject->ParentObjectInformation,
2440                           lCount);
2441         }
2442
2443 try_exit:
2444
2445         if( bReleaseFcb)
2446         {
2447
2448             if( !NT_SUCCESS( ntStatus))
2449             {
2450                 //
2451                 // Decrement the open count on this Fcb
2452                 //
2453
2454                 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2455
2456                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2457                               AFS_TRACE_LEVEL_VERBOSE,
2458                               "AFSOpenTargetDirectory Decrement count on Fcb %08lX Cnt %d\n",
2459                               pParentObject->Fcb,
2460                               lCount);
2461             }
2462
2463             AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2464         }
2465
2466         if( !NT_SUCCESS( ntStatus))
2467         {
2468
2469             if( bAllocatedCcb)
2470             {
2471
2472                 AFSRemoveCcb( NULL,
2473                               *Ccb);
2474             }
2475
2476             *Ccb = NULL;
2477
2478             //
2479             // Fcb will be freed by AFSPrimaryVolumeWorker thread
2480             //
2481
2482             *Fcb = NULL;
2483         }
2484     }
2485
2486     return ntStatus;
2487 }
2488
2489 NTSTATUS
2490 AFSProcessOpen( IN PIRP Irp,
2491                 IN GUID *AuthGroup,
2492                 IN AFSVolumeCB *VolumeCB,
2493                 IN AFSDirectoryCB *ParentDirCB,
2494                 IN AFSDirectoryCB *DirectoryCB,
2495                 OUT AFSFcb **Fcb,
2496                 OUT AFSCcb **Ccb)
2497 {
2498
2499     NTSTATUS ntStatus = STATUS_SUCCESS;
2500     PFILE_OBJECT pFileObject = NULL;
2501     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2502     PACCESS_MASK pDesiredAccess = NULL;
2503     USHORT usShareAccess;
2504     BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE;
2505     ULONG ulAdditionalFlags = 0, ulOptions = 0;
2506     AFSFileOpenCB   stOpenCB;
2507     AFSFileOpenResultCB stOpenResultCB;
2508     ULONG       ulResultLen = 0;
2509     AFSObjectInfoCB *pParentObjectInfo = NULL;
2510     AFSObjectInfoCB *pObjectInfo = NULL;
2511     ULONG       ulFileAccess = 0;
2512     AFSFileAccessReleaseCB stReleaseFileAccess;
2513     LONG lCount;
2514
2515     __Enter
2516     {
2517
2518         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2519         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2520
2521         pFileObject = pIrpSp->FileObject;
2522
2523         pParentObjectInfo = ParentDirCB->ObjectInformation;
2524
2525         pObjectInfo = DirectoryCB->ObjectInformation;
2526
2527         //
2528         // Check if the entry is pending a deletion
2529         //
2530
2531         if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2532         {
2533
2534             ntStatus = STATUS_DELETE_PENDING;
2535
2536             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2537                           AFS_TRACE_LEVEL_ERROR,
2538                           "AFSProcessOpen (%08lX) Entry pending delete %wZ Status %08lX\n",
2539                           Irp,
2540                           &DirectoryCB->NameInformation.FileName,
2541                           ntStatus);
2542
2543             try_return( ntStatus);
2544         }
2545
2546         //
2547         // Extract out the options
2548         //
2549
2550         ulOptions = pIrpSp->Parameters.Create.Options;
2551
2552         //
2553         // Check if we should go and retrieve updated information for the node
2554         //
2555
2556         ntStatus = AFSValidateEntry( DirectoryCB,
2557                                      AuthGroup,
2558                                      FALSE,
2559                                      TRUE);
2560
2561         if( !NT_SUCCESS( ntStatus))
2562         {
2563
2564             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2565                           AFS_TRACE_LEVEL_ERROR,
2566                           "AFSProcessOpen (%08lX) Failed to validate entry %wZ Status %08lX\n",
2567                           Irp,
2568                           &DirectoryCB->NameInformation.FileName,
2569                           ntStatus);
2570
2571             try_return( ntStatus);
2572         }
2573
2574         //
2575         // If this is marked for delete on close then be sure we can delete the entry
2576         //
2577
2578         if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2579         {
2580
2581             ntStatus = AFSNotifyDelete( DirectoryCB,
2582                                         AuthGroup,
2583                                         TRUE);
2584
2585             if( !NT_SUCCESS( ntStatus))
2586             {
2587
2588                 ntStatus = STATUS_CANNOT_DELETE;
2589
2590                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2591                               AFS_TRACE_LEVEL_ERROR,
2592                               "AFSProcessOpen (%08lX) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2593                               Irp,
2594                               &DirectoryCB->NameInformation.FileName,
2595                               ntStatus);
2596
2597                 try_return( ntStatus);
2598             }
2599         }
2600
2601         //
2602         // Be sure we have an Fcb for the current object
2603         //
2604
2605         ntStatus = AFSInitFcb( DirectoryCB);
2606
2607         if( !NT_SUCCESS( ntStatus))
2608         {
2609
2610             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2611                           AFS_TRACE_LEVEL_ERROR,
2612                           "AFSProcessOpen (%08lX) Failed to init fcb on %wZ Status %08lX\n",
2613                           Irp,
2614                           &DirectoryCB->NameInformation.FileName,
2615                           ntStatus);
2616
2617             try_return( ntStatus);
2618         }
2619
2620         ntStatus = STATUS_SUCCESS;
2621
2622         //
2623         // AFSInitFcb returns the Fcb resource held
2624         //
2625
2626         bReleaseFcb = TRUE;
2627
2628         //
2629         // Increment the open count on this Fcb
2630         //
2631
2632         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2633
2634         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2635                       AFS_TRACE_LEVEL_VERBOSE,
2636                       "AFSProcessOpen Increment2 count on Fcb %08lX Cnt %d\n",
2637                       pObjectInfo->Fcb,
2638                       lCount);
2639
2640         //
2641         // Check access on the entry
2642         //
2643
2644         if( pObjectInfo->Fcb->OpenHandleCount > 0)
2645         {
2646
2647             ntStatus = IoCheckShareAccess( *pDesiredAccess,
2648                                            usShareAccess,
2649                                            pFileObject,
2650                                            &pObjectInfo->Fcb->ShareAccess,
2651                                            FALSE);
2652
2653             if( !NT_SUCCESS( ntStatus))
2654             {
2655
2656                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2657                               AFS_TRACE_LEVEL_ERROR,
2658                               "AFSProcessOpen (%08lX) Failed to check share access on %wZ Status %08lX\n",
2659                               Irp,
2660                               &DirectoryCB->NameInformation.FileName,
2661                               ntStatus);
2662
2663                 try_return( ntStatus);
2664             }
2665         }
2666
2667         //
2668         // Additional checks
2669         //
2670
2671         if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2672         {
2673
2674             //
2675             // If the caller is asking for write access then try to flush the image section
2676             //
2677
2678             if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2679                 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2680             {
2681
2682                 if( !MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2683                                           MmFlushForWrite))
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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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 (%08lX) 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
2825         if( !NT_SUCCESS( ntStatus))
2826         {
2827
2828             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2829                           AFS_TRACE_LEVEL_ERROR,
2830                           "AFSProcessOpen (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2831                           Irp,
2832                           &DirectoryCB->NameInformation.FileName,
2833                           ntStatus);
2834
2835             try_return( ntStatus);
2836         }
2837
2838         bAllocatedCcb = TRUE;
2839
2840         (*Ccb)->DirectoryCB = DirectoryCB;
2841
2842         (*Ccb)->FileAccess = ulFileAccess;
2843
2844         (*Ccb)->GrantedAccess = *pDesiredAccess;
2845
2846         //
2847         // Perform the access check on the target if this is a mount point or symlink
2848         //
2849
2850         if( pObjectInfo->Fcb->OpenHandleCount > 0)
2851         {
2852
2853             IoUpdateShareAccess( pFileObject,
2854                                  &pObjectInfo->Fcb->ShareAccess);
2855         }
2856         else
2857         {
2858
2859             //
2860             // Set the access
2861             //
2862
2863             IoSetShareAccess( *pDesiredAccess,
2864                               usShareAccess,
2865                               pFileObject,
2866                               &pObjectInfo->Fcb->ShareAccess);
2867         }
2868
2869         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2870
2871         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2872                       AFS_TRACE_LEVEL_VERBOSE,
2873                       "AFSProcessOpen Increment handle count on Fcb %08lX Cnt %d\n",
2874                       pObjectInfo->Fcb,
2875                       lCount);
2876
2877         //
2878         // Increment the open reference and handle on the parent node
2879         //
2880
2881         lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2882
2883         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2884                       AFS_TRACE_LEVEL_VERBOSE,
2885                       "AFSProcessOpen Increment child open handle count on Parent object %08lX Cnt %d\n",
2886                       pObjectInfo->ParentObjectInformation,
2887                       lCount);
2888
2889         lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2890
2891         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2892                       AFS_TRACE_LEVEL_VERBOSE,
2893                       "AFSProcessOpen Increment child open ref count on Parent object %08lX Cnt %d\n",
2894                       pObjectInfo->ParentObjectInformation,
2895                       lCount);
2896
2897         if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2898         {
2899
2900             //
2901             // Mark it for delete on close
2902             //
2903
2904             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2905                           AFS_TRACE_LEVEL_VERBOSE,
2906                           "AFSProcessOpen (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2907                           Irp,
2908                           DirectoryCB,
2909                           &DirectoryCB->NameInformation.FileName);
2910
2911             SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2912         }
2913
2914         //
2915         // Indicate the object is held
2916         //
2917
2918         SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2919
2920         //
2921         // Return the open result for this file
2922         //
2923
2924         Irp->IoStatus.Information = FILE_OPENED;
2925
2926         *Fcb = pObjectInfo->Fcb;
2927
2928 try_exit:
2929
2930         if( bReleaseFcb)
2931         {
2932
2933             if( !NT_SUCCESS( ntStatus))
2934             {
2935                 //
2936                 // Decrement the open count on this Fcb
2937                 //
2938
2939                 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2940
2941                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2942                               AFS_TRACE_LEVEL_VERBOSE,
2943                               "AFSProcessOpen Decrement2 count on Fcb %08lX Cnt %d\n",
2944                               pObjectInfo->Fcb,
2945                               lCount);
2946             }
2947
2948             AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2949         }
2950
2951         if( !NT_SUCCESS( ntStatus))
2952         {
2953
2954             if ( ulFileAccess > 0)
2955             {
2956
2957                 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2958
2959                 stReleaseFileAccess.FileAccess = ulFileAccess;
2960
2961                 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2962
2963                 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2964                                    AFS_REQUEST_FLAG_SYNCHRONOUS,
2965                                    AuthGroup,
2966                                    &DirectoryCB->NameInformation.FileName,
2967                                    &pObjectInfo->FileId,
2968                                    (void *)&stReleaseFileAccess,
2969                                    sizeof( AFSFileAccessReleaseCB),
2970                                    NULL,
2971                                    NULL);
2972             }
2973
2974             if( bAllocatedCcb)
2975             {
2976
2977                 AFSRemoveCcb( NULL,
2978                               *Ccb);
2979             }
2980
2981             *Ccb = NULL;
2982
2983             //
2984             // Fcb will be freed by AFSPrimaryVolumeWorker thread
2985             //
2986
2987             *Fcb = NULL;
2988         }
2989     }
2990
2991     return ntStatus;
2992 }
2993
2994 NTSTATUS
2995 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
2996                               IN PIRP           Irp,
2997                               IN AFSVolumeCB   *VolumeCB,
2998                               IN GUID          *AuthGroup,
2999                               IN AFSDirectoryCB *ParentDirCB,
3000                               IN AFSDirectoryCB *DirectoryCB,
3001                               OUT AFSFcb       **Fcb,
3002                               OUT AFSCcb       **Ccb)
3003 {
3004
3005     NTSTATUS ntStatus = STATUS_SUCCESS;
3006     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3007     PFILE_OBJECT pFileObject = NULL;
3008     LARGE_INTEGER liZero = {0,0};
3009     BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
3010     ULONG   ulAttributes = 0;
3011     LARGE_INTEGER liTime;
3012     ULONG ulCreateDisposition = 0;
3013     BOOLEAN bAllocatedCcb = FALSE;
3014     PACCESS_MASK pDesiredAccess = NULL;
3015     USHORT usShareAccess;
3016     AFSObjectInfoCB *pParentObjectInfo = NULL;
3017     AFSObjectInfoCB *pObjectInfo = NULL;
3018     LONG lCount;
3019     LARGE_INTEGER liSaveSize;
3020     LARGE_INTEGER liSaveVDL;
3021     LARGE_INTEGER liSaveAlloc;
3022
3023     __Enter
3024     {
3025
3026         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3027
3028         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
3029
3030         pFileObject = pIrpSp->FileObject;
3031
3032         ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
3033
3034         ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
3035
3036         if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
3037         {
3038
3039             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3040                           AFS_TRACE_LEVEL_ERROR,
3041                           "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3042                           Irp,
3043                           &DirectoryCB->NameInformation.FileName);
3044
3045             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3046         }
3047
3048         pParentObjectInfo = ParentDirCB->ObjectInformation;
3049
3050         pObjectInfo = DirectoryCB->ObjectInformation;
3051
3052         //
3053         // Check if we should go and retrieve updated information for the node
3054         //
3055
3056         ntStatus = AFSValidateEntry( DirectoryCB,
3057                                      AuthGroup,
3058                                      FALSE,
3059                                      TRUE);
3060
3061         if( !NT_SUCCESS( ntStatus))
3062         {
3063
3064             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3065                           AFS_TRACE_LEVEL_ERROR,
3066                           "AFSProcessOverwriteSupersede (%08lX) Failed to validate entry %wZ Status %08lX\n",
3067                           Irp,
3068                           &DirectoryCB->NameInformation.FileName,
3069                           ntStatus);
3070
3071             try_return( ntStatus);
3072         }
3073
3074         //
3075         // Be sure we have an Fcb for the object block
3076         //
3077
3078         ntStatus = AFSInitFcb( DirectoryCB);
3079
3080         *Fcb = pObjectInfo->Fcb;
3081
3082         if( !NT_SUCCESS( ntStatus))
3083         {
3084
3085             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3086                           AFS_TRACE_LEVEL_ERROR,
3087                           "AFSProcessOverwriteSupersede (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
3088                           Irp,
3089                           &DirectoryCB->NameInformation.FileName,
3090                           ntStatus);
3091
3092             try_return( ntStatus);
3093         }
3094
3095         ntStatus = STATUS_SUCCESS;
3096
3097         //
3098         // Increment the open count on this Fcb.
3099         //
3100
3101         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3102
3103         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3104                       AFS_TRACE_LEVEL_VERBOSE,
3105                       "AFSProcessOverwriteSupersede Increment2 count on Fcb %08lX Cnt %d\n",
3106                       pObjectInfo->Fcb,
3107                       lCount);
3108
3109         bReleaseFcb = TRUE;
3110
3111         //
3112         // Check access on the entry
3113         //
3114
3115         if( pObjectInfo->Fcb->OpenHandleCount > 0)
3116         {
3117
3118             ntStatus = IoCheckShareAccess( *pDesiredAccess,
3119                                            usShareAccess,
3120                                            pFileObject,
3121                                            &pObjectInfo->Fcb->ShareAccess,
3122                                            FALSE);
3123
3124             if( !NT_SUCCESS( ntStatus))
3125             {
3126
3127                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3128                               AFS_TRACE_LEVEL_ERROR,
3129                               "AFSProcessOverwriteSupersede (%08lX) Access check failure %wZ Status %08lX\n",
3130                               Irp,
3131                               &DirectoryCB->NameInformation.FileName,
3132                               ntStatus);
3133
3134                 try_return( ntStatus);
3135             }
3136         }
3137
3138         //
3139         //  Before we actually truncate, check to see if the purge
3140         //  is going to fail.
3141         //
3142
3143         if( !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3144                                    &liZero))
3145         {
3146
3147             ntStatus = STATUS_USER_MAPPED_FILE;
3148
3149             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3150                           AFS_TRACE_LEVEL_ERROR,
3151                           "AFSProcessOverwriteSupersede (%08lX) File user mapped %wZ Status %08lX\n",
3152                           Irp,
3153                           &DirectoryCB->NameInformation.FileName,
3154                           ntStatus);
3155
3156             try_return( ntStatus);
3157         }
3158
3159         //
3160         // Initialize the Ccb for the file.
3161         //
3162
3163         ntStatus = AFSInitCcb( Ccb);
3164
3165         if( !NT_SUCCESS( ntStatus))
3166         {
3167
3168             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3169                           AFS_TRACE_LEVEL_ERROR,
3170                           "AFSProcessOverwriteSupersede (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
3171                           Irp,
3172                           &DirectoryCB->NameInformation.FileName,
3173                           ntStatus);
3174
3175             try_return( ntStatus);
3176         }
3177
3178         bAllocatedCcb = TRUE;
3179
3180         //
3181         // Initialize the Ccb
3182         //
3183
3184         (*Ccb)->DirectoryCB = DirectoryCB;
3185
3186         (*Ccb)->GrantedAccess = *pDesiredAccess;
3187
3188         //
3189         // Set the file length to zero
3190         //
3191
3192         AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3193                         TRUE);
3194
3195         bReleasePaging = TRUE;
3196
3197         liSaveSize = pObjectInfo->Fcb->Header.FileSize;
3198         liSaveAlloc = pObjectInfo->Fcb->Header.AllocationSize;
3199         liSaveVDL = pObjectInfo->Fcb->Header.ValidDataLength;
3200
3201         pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3202         pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3203         pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3204
3205         pObjectInfo->EndOfFile.QuadPart = 0;
3206         pObjectInfo->AllocationSize.QuadPart = 0;
3207
3208         //
3209         // Trim down the extents. We do this BEFORE telling the service
3210         // the file is truncated since there is a potential race between
3211         // a worker thread releasing extents and us trimming
3212         //
3213
3214         AFSTrimExtents( pObjectInfo->Fcb,
3215                         &pObjectInfo->Fcb->Header.FileSize);
3216
3217         KeQuerySystemTime( &pObjectInfo->ChangeTime);
3218
3219         KeQuerySystemTime( &pObjectInfo->LastAccessTime);
3220
3221         KeQuerySystemTime( &pObjectInfo->LastWriteTime);
3222
3223         //
3224         // Set the update flag accordingly
3225         //
3226
3227         SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
3228                                           AFS_FCB_FLAG_UPDATE_CREATE_TIME |
3229                                           AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
3230                                           AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
3231                                           AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
3232
3233         ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
3234                                              pObjectInfo,
3235                                              AuthGroup);
3236
3237         if( !NT_SUCCESS( ntStatus))
3238         {
3239
3240             pObjectInfo->Fcb->Header.ValidDataLength = liSaveVDL;
3241             pObjectInfo->Fcb->Header.FileSize = liSaveSize;
3242             pObjectInfo->Fcb->Header.AllocationSize = liSaveAlloc;
3243             pObjectInfo->Fcb->ObjectInformation->EndOfFile = liSaveSize;
3244             pObjectInfo->Fcb->ObjectInformation->AllocationSize = liSaveAlloc;
3245
3246             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3247                           AFS_TRACE_LEVEL_ERROR,
3248                           "AFSProcessOverwriteSupersede (%08lX) Failed to update file information %wZ Status %08lX\n",
3249                           Irp,
3250                           &DirectoryCB->NameInformation.FileName,
3251                           ntStatus);
3252
3253             try_return( ntStatus);
3254         }
3255
3256         ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
3257
3258         if( ulCreateDisposition == FILE_SUPERSEDE)
3259         {
3260
3261             pObjectInfo->FileAttributes = ulAttributes;
3262
3263         }
3264         else
3265         {
3266
3267             pObjectInfo->FileAttributes |= ulAttributes;
3268         }
3269
3270         //
3271         // Save off the access for the open
3272         //
3273
3274         if( pObjectInfo->Fcb->OpenHandleCount > 0)
3275         {
3276
3277             IoUpdateShareAccess( pFileObject,
3278                                  &pObjectInfo->Fcb->ShareAccess);
3279         }
3280         else
3281         {
3282
3283             //
3284             // Set the access
3285             //
3286
3287             IoSetShareAccess( *pDesiredAccess,
3288                               usShareAccess,
3289                               pFileObject,
3290                               &pObjectInfo->Fcb->ShareAccess);
3291         }
3292
3293         //
3294         // Return the correct action
3295         //
3296
3297         if( ulCreateDisposition == FILE_SUPERSEDE)
3298         {
3299
3300             Irp->IoStatus.Information = FILE_SUPERSEDED;
3301         }
3302         else
3303         {
3304
3305             Irp->IoStatus.Information = FILE_OVERWRITTEN;
3306         }
3307
3308         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
3309
3310         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3311                       AFS_TRACE_LEVEL_VERBOSE,
3312                       "AFSProcessOverwriteSupersede Increment handle count on Fcb %08lX Cnt %d\n",
3313                       pObjectInfo->Fcb,
3314                       lCount);
3315
3316         //
3317         // Increment the open reference and handle on the parent node
3318         //
3319
3320         lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
3321
3322         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3323                       AFS_TRACE_LEVEL_VERBOSE,
3324                       "AFSProcessOverwriteSupersede Increment child open handle count on Parent object %08lX Cnt %d\n",
3325                       pObjectInfo->ParentObjectInformation,
3326                       lCount);
3327
3328         lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
3329
3330         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3331                       AFS_TRACE_LEVEL_VERBOSE,
3332                       "AFSProcessOverwriteSupersede Increment child open ref count on Parent object %08lX Cnt %d\n",
3333                       pObjectInfo->ParentObjectInformation,
3334                       lCount);
3335
3336         AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3337
3338         bReleaseFcb = FALSE;
3339
3340         *Fcb = pObjectInfo->Fcb;
3341
3342         //
3343         // Now that the Fcb->Resource has been dropped
3344         // we can call CcSetFileSizes.  We are still holding
3345         // the PagingIoResource
3346         //
3347
3348         pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
3349
3350         pFileObject->FsContext = (void *)pObjectInfo->Fcb;
3351
3352         pFileObject->FsContext2 = (void *)*Ccb;
3353
3354         CcSetFileSizes( pFileObject,
3355                         (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3356
3357 try_exit:
3358
3359         if( bReleasePaging)
3360         {
3361
3362             AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3363         }
3364
3365         if( bReleaseFcb)
3366         {
3367
3368             if( !NT_SUCCESS( ntStatus))
3369             {
3370                 //
3371                 // Decrement the open count on this Fcb.
3372                 //
3373
3374                 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
3375
3376                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3377                               AFS_TRACE_LEVEL_VERBOSE,
3378                               "AFSProcessOverwriteSupersede Decrement2 count on Fcb %08lX Cnt %d\n",
3379                               pObjectInfo->Fcb,
3380                               lCount);
3381             }
3382
3383             AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3384         }
3385
3386         if( !NT_SUCCESS( ntStatus))
3387         {
3388
3389             if( bAllocatedCcb)
3390             {
3391
3392                 AFSRemoveCcb( NULL,
3393                               *Ccb);
3394             }
3395
3396             *Ccb = NULL;
3397
3398             //
3399             // Fcb will be freed by AFSPrimaryVolumeWorker thread
3400             //
3401
3402             *Fcb = NULL;
3403         }
3404     }
3405
3406     return ntStatus;
3407 }
3408
3409 NTSTATUS
3410 AFSControlDeviceCreate( IN PIRP Irp)
3411 {
3412
3413     NTSTATUS ntStatus = STATUS_SUCCESS;
3414
3415     __Enter
3416     {
3417
3418         //
3419         // For now, jsut let the open happen
3420         //
3421
3422         Irp->IoStatus.Information = FILE_OPENED;
3423     }
3424
3425     return ntStatus;
3426 }
3427
3428 NTSTATUS
3429 AFSOpenIOCtlFcb( IN PIRP Irp,
3430                  IN GUID *AuthGroup,
3431                  IN AFSDirectoryCB *ParentDirCB,
3432                  OUT AFSFcb **Fcb,
3433                  OUT AFSCcb **Ccb)
3434 {
3435
3436     NTSTATUS ntStatus = STATUS_SUCCESS;
3437     PFILE_OBJECT pFileObject = NULL;
3438     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3439     BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
3440     UNICODE_STRING uniFullFileName;
3441     AFSPIOCtlOpenCloseRequestCB stPIOCtlOpen;
3442     AFSFileID stFileID;
3443     AFSObjectInfoCB *pParentObjectInfo = NULL;
3444     LONG lCount;
3445
3446     __Enter
3447     {
3448
3449         pFileObject = pIrpSp->FileObject;
3450
3451         pParentObjectInfo = ParentDirCB->ObjectInformation;
3452
3453         //
3454         // If we haven't initialized the PIOCtl DirectoryCB for this directory then do it now
3455         //
3456
3457         if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB == NULL)
3458         {
3459
3460             ntStatus = AFSInitPIOCtlDirectoryCB( pParentObjectInfo);
3461
3462             if( !NT_SUCCESS( ntStatus))
3463             {
3464
3465                 try_return( ntStatus);
3466             }
3467         }
3468
3469         //
3470         // Allocate and initialize the Fcb for the file.
3471         //
3472
3473         ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB);
3474
3475         *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
3476
3477         if( !NT_SUCCESS( ntStatus))
3478         {
3479
3480             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3481                           AFS_TRACE_LEVEL_ERROR,
3482                           "AFSOpenIOCtlFcb (%08lX) Failed to initialize fcb Status %08lX\n",
3483                           Irp,
3484                           ntStatus);
3485
3486             try_return( ntStatus);
3487         }
3488
3489         ntStatus = STATUS_SUCCESS;
3490
3491         //
3492         // Increment the open reference and handle on the node
3493         //
3494
3495         lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3496
3497         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3498                       AFS_TRACE_LEVEL_VERBOSE,
3499                       "AFSOpenIOCtlFcb Increment count on Fcb %08lX Cnt %d\n",
3500                       (*Fcb),
3501                       lCount);
3502
3503         bReleaseFcb = TRUE;
3504
3505         //
3506         // Initialize the Ccb for the file.
3507         //
3508
3509         ntStatus = AFSInitCcb( Ccb);
3510
3511         if( !NT_SUCCESS( ntStatus))
3512         {
3513
3514             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3515                           AFS_TRACE_LEVEL_ERROR,
3516                           "AFSOpenIOCtlFcb (%08lX) Failed to initialize ccb Status %08lX\n",
3517                           Irp,
3518                           ntStatus);
3519
3520             try_return( ntStatus);
3521         }
3522
3523         bAllocatedCcb = TRUE;
3524
3525         //
3526         // Setup the Ccb
3527         //
3528
3529         (*Ccb)->DirectoryCB = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB;
3530
3531         //
3532         // Set the PIOCtl index
3533         //
3534
3535         (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3536
3537         RtlZeroMemory( &stPIOCtlOpen,
3538                        sizeof( AFSPIOCtlOpenCloseRequestCB));
3539
3540         stPIOCtlOpen.RequestId = (*Ccb)->RequestID;
3541
3542         stPIOCtlOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3543
3544         RtlZeroMemory( &stFileID,
3545                        sizeof( AFSFileID));
3546
3547         //
3548         // The parent directory FID of the node
3549         //
3550
3551         stFileID = pParentObjectInfo->FileId;
3552
3553         //
3554         // Issue the open request to the service
3555         //
3556
3557         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_OPEN,
3558                                       AFS_REQUEST_FLAG_SYNCHRONOUS,
3559                                       AuthGroup,
3560                                       NULL,
3561                                       &stFileID,
3562                                       (void *)&stPIOCtlOpen,
3563                                       sizeof( AFSPIOCtlOpenCloseRequestCB),
3564                                       NULL,
3565                                       NULL);
3566
3567         if( !NT_SUCCESS( ntStatus))
3568         {
3569
3570             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3571                           AFS_TRACE_LEVEL_ERROR,
3572                           "AFSOpenIOCtlFcb (%08lX) Failed service open Status %08lX\n",
3573                           Irp,
3574                           ntStatus);
3575
3576             try_return( ntStatus);
3577         }
3578
3579         //
3580         // Reference the directory entry
3581         //
3582
3583         lCount = InterlockedIncrement( &((*Ccb)->DirectoryCB->DirOpenReferenceCount));
3584
3585         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3586                       AFS_TRACE_LEVEL_VERBOSE,
3587                       "AFSOpenIOCtlFcb Increment count on %wZ DE %p Ccb %p Cnt %d\n",
3588                       &(*Ccb)->DirectoryCB->NameInformation.FileName,
3589                       (*Ccb)->DirectoryCB,
3590                       (*Ccb),
3591                       lCount);
3592
3593         //
3594         // Increment the handle on the node
3595         //
3596
3597         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3598
3599         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3600                       AFS_TRACE_LEVEL_VERBOSE,
3601                       "AFSOpenIOCtlFcb Increment handle count on Fcb %08lX Cnt %d\n",
3602                       (*Fcb),
3603                       lCount);
3604
3605         //
3606         // Increment the open reference and handle on the parent node
3607         //
3608
3609         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3610
3611         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3612                       AFS_TRACE_LEVEL_VERBOSE,
3613                       "AFSOpenIOCtlFcb Increment child open handle count on Parent object %08lX Cnt %d\n",
3614                       pParentObjectInfo,
3615                       lCount);
3616
3617         lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3618
3619         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3620                       AFS_TRACE_LEVEL_VERBOSE,
3621                       "AFSOpenIOCtlFcb Increment child open ref count on Parent object %08lX Cnt %d\n",
3622                       pParentObjectInfo,
3623                       lCount);
3624
3625         //
3626         // Return the open result for this file
3627         //
3628
3629         Irp->IoStatus.Information = FILE_OPENED;
3630
3631 try_exit:
3632
3633         //
3634         //Dereference the passed in parent since the returned dir entry
3635         // is already referenced
3636         //
3637
3638         lCount = InterlockedDecrement( &ParentDirCB->DirOpenReferenceCount);
3639
3640         AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3641                       AFS_TRACE_LEVEL_VERBOSE,
3642                       "AFSOpenIOCtlFcb Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3643                       &ParentDirCB->NameInformation.FileName,
3644                       ParentDirCB,
3645                       NULL,
3646                       lCount);
3647
3648         ASSERT( lCount >= 0);
3649
3650         //
3651         // If we created the Fcb we need to release the resources
3652         //
3653
3654         if( bReleaseFcb)
3655         {
3656
3657             if( !NT_SUCCESS( ntStatus))
3658             {
3659                 //
3660                 // Decrement the open reference and handle on the node
3661                 //
3662
3663                 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);