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