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