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