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