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