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