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