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