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