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