Windows: Add CCB NonPaged Resource for synchronization
[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->OpenReferenceCount);
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
381             try_return( ntStatus);
382         }
383
384         //
385         // We have a reference on the root volume
386         //
387
388         bReleaseVolume = TRUE;
389
390         //
391         // Attempt to locate the node in the name tree if this is not a target
392         // open and the target is not the root
393         //
394
395         uniComponentName.Length = 0;
396         uniComponentName.Buffer = NULL;
397
398         if( uniFileName.Length > sizeof( WCHAR) ||
399             uniFileName.Buffer[ 0] != L'\\')
400         {
401
402             if( !AFSValidNameFormat( &uniFileName))
403             {
404
405                 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
406
407                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
408                               AFS_TRACE_LEVEL_VERBOSE,
409                               "AFSCommonCreate (%08lX) Invalid name %wZ Status %08lX\n",
410                               Irp,
411                               &uniFileName,
412                               ntStatus);
413
414                 try_return( ntStatus);
415             }
416
417             //
418             // Opening a reparse point directly?
419             //
420
421             ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
422
423             if( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
424             {
425                 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
426                                           AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
427                                           AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
428             }
429
430             uniSubstitutedPathName = uniRootFileName;
431
432             ntStatus = AFSLocateNameEntry( &stAuthGroup,
433                                            pFileObject,
434                                            &uniRootFileName,
435                                            &uniParsedFileName,
436                                            pNameArray,
437                                            ulNameProcessingFlags,
438                                            &pVolumeCB,
439                                            &pParentDirectoryCB,
440                                            &pDirectoryCB,
441                                            &uniComponentName);
442
443             if( !NT_SUCCESS( ntStatus) &&
444                 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
445             {
446
447                 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
448                 {
449                     uniSubstitutedPathName.Buffer = NULL;
450                 }
451
452                 //
453                 // The routine above released the root while walking the
454                 // branch
455                 //
456
457                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
458                               AFS_TRACE_LEVEL_VERBOSE,
459                               "AFSCommonCreate (%08lX) Failed to locate name entry for %wZ Status %08lX\n",
460                               Irp,
461                               &uniFileName,
462                               ntStatus);
463
464                 //
465                 // We released any root volume locks in the above on failure
466                 //
467
468                 bReleaseVolume = FALSE;
469
470                 try_return( ntStatus);
471             }
472
473             //
474             // Check for STATUS_REPARSE
475             //
476
477             if( ntStatus == STATUS_REPARSE)
478             {
479
480                 uniSubstitutedPathName.Buffer = NULL;
481
482                 //
483                 // Update the information and return
484                 //
485
486                 Irp->IoStatus.Information = IO_REPARSE;
487
488                 //
489                 // We released the volume lock above
490                 //
491
492                 bReleaseVolume = FALSE;
493
494                 try_return( ntStatus);
495             }
496
497             //
498             // If we re-allocated the name, then update our substitute name
499             //
500
501             if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
502             {
503
504                 uniSubstitutedPathName = uniRootFileName;
505             }
506             else
507             {
508
509                 uniSubstitutedPathName.Buffer = NULL;
510             }
511
512             //
513             // Check for a symlink access
514             //
515
516             if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
517                 pParentDirectoryCB != NULL)
518             {
519
520                 UNICODE_STRING uniFinalComponent;
521
522                 uniFinalComponent.Length = 0;
523                 uniFinalComponent.MaximumLength = 0;
524                 uniFinalComponent.Buffer = NULL;
525
526                 AFSRetrieveFinalComponent( &uniFileName,
527                                            &uniFinalComponent);
528
529                 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
530                                                   &uniFinalComponent);
531
532                 if( !NT_SUCCESS( ntStatus) &&
533                     ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
534                 {
535
536                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
537                                   AFS_TRACE_LEVEL_VERBOSE,
538                                   "AFSCommonCreate (%08lX) Failing access to symlink %wZ Status %08lX\n",
539                                   Irp,
540                                   &uniFileName,
541                                   ntStatus);
542
543                     try_return( ntStatus);
544                 }
545             }
546         }
547
548         //
549         // If we have no parent then this is a root open, be sure there is a directory entry
550         // for the root
551         //
552
553         else if( pParentDirectoryCB == NULL &&
554                  pDirectoryCB == NULL)
555         {
556
557             pDirectoryCB = pVolumeCB->DirectoryCB;
558         }
559
560         if( bOpenTargetDirectory)
561         {
562
563             //
564             // If we have a directory cb for the entry then dereference it and reference the parent
565             //
566
567             if( pDirectoryCB != NULL)
568             {
569
570                 //
571                 // Perform in this order to prevent thrashing
572                 //
573
574                 lCount = InterlockedIncrement( &pParentDirectoryCB->OpenReferenceCount);
575
576                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
577                               AFS_TRACE_LEVEL_VERBOSE,
578                               "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
579                               &pParentDirectoryCB->NameInformation.FileName,
580                               pParentDirectoryCB,
581                               NULL,
582                               lCount);
583
584                 //
585                 // Do NOT decrement the reference count on the pDirectoryCB yet.
586                 // The BackupEntry below might drop the count to zero leaving
587                 // the entry subject to being deleted and we need some of the
588                 // contents during later processing
589                 //
590
591                 AFSBackupEntry( pNameArray);
592             }
593
594             //
595             // OK, open the target directory
596             //
597
598             if( uniComponentName.Length == 0)
599             {
600                 AFSRetrieveFinalComponent( &uniFileName,
601                                            &uniComponentName);
602             }
603
604             ntStatus = AFSOpenTargetDirectory( Irp,
605                                                pVolumeCB,
606                                                pParentDirectoryCB,
607                                                pDirectoryCB,
608                                                &uniComponentName,
609                                                &pFcb,
610                                                &pCcb);
611             if( pDirectoryCB != NULL)
612             {
613                 //
614                 // It is now safe to drop the Reference Count
615                 //
616                 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
617
618                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
619                               AFS_TRACE_LEVEL_VERBOSE,
620                               "AFSCommonCreate Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
621                               &pDirectoryCB->NameInformation.FileName,
622                               pDirectoryCB,
623                               NULL,
624                               lCount);
625             }
626
627             if( !NT_SUCCESS( ntStatus))
628             {
629
630                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
631                               AFS_TRACE_LEVEL_ERROR,
632                               "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
633                               &pParentDirectoryCB->NameInformation.FileName,
634                               ntStatus);
635
636                 //
637                 // Decrement the reference on the parent
638                 //
639
640                 lCount = InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
641
642                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
643                               AFS_TRACE_LEVEL_VERBOSE,
644                               "AFSCommonCreate Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
645                               &pParentDirectoryCB->NameInformation.FileName,
646                               pParentDirectoryCB,
647                               NULL,
648                               lCount);
649             }
650
651             try_return( ntStatus);
652         }
653
654         if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
655         {
656
657             if( pDirectoryCB == NULL ||
658                 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
659             {
660                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
661                               AFS_TRACE_LEVEL_VERBOSE,
662                               "AFSCommonCreate (%08lX) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
663                               Irp,
664                               &uniFileName,
665                               pDirectoryCB,
666                               pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0);
667             }
668             else
669             {
670                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
671                               AFS_TRACE_LEVEL_VERBOSE,
672                               "AFSCommonCreate (%08lX) Opening as reparse point %wZ Type %08lX\n",
673                               Irp,
674                               &uniFileName,
675                               pDirectoryCB->ObjectInformation->FileType);
676
677                 bOpenedReparsePoint = TRUE;
678             }
679         }
680
681         //
682         // Based on the options passed in, process the file accordingly.
683         //
684
685         if( ulCreateDisposition == FILE_CREATE ||
686             ( ( ulCreateDisposition == FILE_OPEN_IF ||
687                 ulCreateDisposition == FILE_OVERWRITE_IF) &&
688               pDirectoryCB == NULL))
689         {
690
691             if( uniComponentName.Length == 0 ||
692                 pDirectoryCB != NULL)
693             {
694
695                 //
696                 // We traversed the entire path so we found each entry,
697                 // fail with collision
698                 //
699
700                 if( pDirectoryCB != NULL)
701                 {
702
703                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
704                                   AFS_TRACE_LEVEL_VERBOSE,
705                                   "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
706                                   &pDirectoryCB->NameInformation.FileName,
707                                   ntStatus);
708
709                     lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
710
711                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
712                                   AFS_TRACE_LEVEL_VERBOSE,
713                                   "AFSCommonCreate Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
714                                   &pDirectoryCB->NameInformation.FileName,
715                                   pDirectoryCB,
716                                   NULL,
717                                   lCount);
718                 }
719                 else
720                 {
721
722                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
723                                   AFS_TRACE_LEVEL_VERBOSE,
724                                   "AFSCommonCreate Object name collision on create Status %08lX\n",
725                                   ntStatus);
726
727                     InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
728
729                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
730                                   AFS_TRACE_LEVEL_VERBOSE,
731                                   "AFSCommonCreate Decrement5 count on %wZ DE %p Ccb %p Cnt %d\n",
732                                   &pParentDirectoryCB->NameInformation.FileName,
733                                   pParentDirectoryCB,
734                                   NULL,
735                                   pParentDirectoryCB->OpenReferenceCount);
736                 }
737
738                 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
739             }
740
741             //
742             // OK, go and create the node
743             //
744
745             ntStatus = AFSProcessCreate( Irp,
746                                          &stAuthGroup,
747                                          pVolumeCB,
748                                          pParentDirectoryCB,
749                                          &uniFileName,
750                                          &uniComponentName,
751                                          &uniRootFileName,
752                                          &pFcb,
753                                          &pCcb);
754
755             if( !NT_SUCCESS( ntStatus))
756             {
757
758                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
759                               AFS_TRACE_LEVEL_ERROR,
760                               "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
761                               &uniComponentName,
762                               &pParentDirectoryCB->NameInformation.FileName,
763                               ntStatus);
764             }
765
766             //
767             // Dereference the parent entry
768             //
769
770             lCount = InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
771
772             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
773                           AFS_TRACE_LEVEL_VERBOSE,
774                           "AFSCreate Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
775                           &pParentDirectoryCB->NameInformation.FileName,
776                           pParentDirectoryCB,
777                           NULL,
778                           lCount);
779
780             try_return( ntStatus);
781         }
782
783         //
784         // We should not have an extra component except for PIOCtl opens
785         //
786
787         if( uniComponentName.Length > 0)
788         {
789
790             //
791             // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
792             //
793
794             if( RtlCompareUnicodeString( &AFSPIOCtlName,
795                                          &uniComponentName,
796                                          TRUE) == 0)
797             {
798
799                 ntStatus = AFSOpenIOCtlFcb( Irp,
800                                             &stAuthGroup,
801                                             pParentDirectoryCB,
802                                             &pFcb,
803                                             &pCcb);
804
805                 if( !NT_SUCCESS( ntStatus))
806                 {
807
808                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
809                                   AFS_TRACE_LEVEL_ERROR,
810                                   "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
811                                   &uniComponentName,
812                                   ntStatus);
813                 }
814             }
815             else
816             {
817
818                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
819                               AFS_TRACE_LEVEL_VERBOSE,
820                               "AFSCommonCreate (%08lX) File %wZ name not found\n",
821                               Irp,
822                               &uniFileName);
823
824                 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
825             }
826
827             if( !NT_SUCCESS( ntStatus))
828             {
829
830                 //
831                 // Dereference the parent entry
832                 //
833
834                 if( pDirectoryCB != NULL)
835                 {
836
837                     lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
838
839                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
840                                   AFS_TRACE_LEVEL_VERBOSE,
841                                   "AFSCommonCreate Decrement7a count on %wZ DE %p Ccb %p Cnt %d\n",
842                                   &pDirectoryCB->NameInformation.FileName,
843                                   pDirectoryCB,
844                                   NULL,
845                                   lCount);
846                 }
847                 else
848                 {
849
850                     lCount = InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
851
852                     AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
853                                   AFS_TRACE_LEVEL_VERBOSE,
854                                   "AFSCommonCreate Decrement7b count on %wZ DE %p Ccb %p Cnt %d\n",
855                                   &pParentDirectoryCB->NameInformation.FileName,
856                                   pParentDirectoryCB,
857                                   NULL,
858                                   lCount);
859                 }
860             }
861
862             try_return( ntStatus);
863         }
864
865         //
866         // For root opens the parent will be NULL
867         //
868
869         if( pParentDirectoryCB == NULL)
870         {
871
872             //
873             // Check for the delete on close flag for the root
874             //
875
876             if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
877             {
878
879                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
880                               AFS_TRACE_LEVEL_ERROR,
881                               "AFSCommonCreate (%08lX) Attempt to open root as delete on close\n",
882                               Irp);
883
884                 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
885
886                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
887                               AFS_TRACE_LEVEL_VERBOSE,
888                               "AFSCommonCreate Decrement8 count on %wZ DE %p Ccb %p Cnt %d\n",
889                               &pDirectoryCB->NameInformation.FileName,
890                               pDirectoryCB,
891                               NULL,
892                               lCount);
893
894                 try_return( ntStatus = STATUS_CANNOT_DELETE);
895             }
896
897             //
898             // If this is the target directory, then bail
899             //
900
901             if( bOpenTargetDirectory)
902             {
903
904                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
905                               AFS_TRACE_LEVEL_ERROR,
906                               "AFSCommonCreate (%08lX) Attempt to open root as target directory\n",
907                               Irp);
908
909                 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
910
911                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
912                               AFS_TRACE_LEVEL_VERBOSE,
913                               "AFSCommonCreate Decrement9 count on %wZ DE %p Ccb %p Cnt %d\n",
914                               &pDirectoryCB->NameInformation.FileName,
915                               pDirectoryCB,
916                               NULL,
917                               lCount);
918
919                 try_return( ntStatus = STATUS_INVALID_PARAMETER);
920             }
921
922             //
923             // Go and open the root of the volume
924             //
925
926             ntStatus = AFSOpenRoot( Irp,
927                                     pVolumeCB,
928                                     &stAuthGroup,
929                                     &pFcb,
930                                     &pCcb);
931
932             if( !NT_SUCCESS( ntStatus))
933             {
934
935                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
936                               AFS_TRACE_LEVEL_ERROR,
937                               "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
938                               pVolumeCB->ObjectInformation.FileId.Cell,
939                               pVolumeCB->ObjectInformation.FileId.Volume,
940                               ntStatus);
941
942                 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
943
944                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
945                               AFS_TRACE_LEVEL_VERBOSE,
946                               "AFSCommonCreate Decrement10 count on %wZ DE %p Ccb %p Cnt %d\n",
947                               &pDirectoryCB->NameInformation.FileName,
948                               pDirectoryCB,
949                               NULL,
950                               lCount);
951             }
952
953             try_return( ntStatus);
954         }
955
956         //
957         // At this point if we have no pDirectoryCB it was not found.
958         //
959
960         if( pDirectoryCB == NULL)
961         {
962
963             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
964                           AFS_TRACE_LEVEL_ERROR,
965                           "AFSCommonCreate Failing access to %wZ\n",
966                           &uniFileName);
967
968             try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
969         }
970
971         if( ulCreateDisposition == FILE_OVERWRITE ||
972             ulCreateDisposition == FILE_SUPERSEDE ||
973             ulCreateDisposition == FILE_OVERWRITE_IF)
974         {
975
976             //
977             // Go process a file for overwrite or supersede.
978             //
979
980             ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
981                                                      Irp,
982                                                      pVolumeCB,
983                                                      &stAuthGroup,
984                                                      pParentDirectoryCB,
985                                                      pDirectoryCB,
986                                                      &pFcb,
987                                                      &pCcb);
988
989             if( !NT_SUCCESS( ntStatus))
990             {
991
992                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
993                               AFS_TRACE_LEVEL_ERROR,
994                               "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
995                               &pDirectoryCB->NameInformation.FileName,
996                               ntStatus);
997
998                 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
999
1000                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1001                               AFS_TRACE_LEVEL_VERBOSE,
1002                               "AFSCommonCreate Decrement11 count on %wZ DE %p Ccb %p Cnt %d\n",
1003                               &pDirectoryCB->NameInformation.FileName,
1004                               pDirectoryCB,
1005                               NULL,
1006                               lCount);
1007             }
1008
1009             try_return( ntStatus);
1010         }
1011
1012         //
1013         // Trying to open the file
1014         //
1015
1016         ntStatus = AFSProcessOpen( Irp,
1017                                    &stAuthGroup,
1018                                    pVolumeCB,
1019                                    pParentDirectoryCB,
1020                                    pDirectoryCB,
1021                                    &pFcb,
1022                                    &pCcb);
1023
1024         if( !NT_SUCCESS( ntStatus))
1025         {
1026
1027             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1028                           AFS_TRACE_LEVEL_ERROR,
1029                           "AFSCommonCreate Failed open on %wZ Status %08lX\n",
1030                           &pDirectoryCB->NameInformation.FileName,
1031                           ntStatus);
1032
1033             lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
1034
1035             AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1036                           AFS_TRACE_LEVEL_VERBOSE,
1037                           "AFSCommonCreate Decrement12 count on %wZ DE %p Ccb %p Cnt %d\n",
1038                           &pDirectoryCB->NameInformation.FileName,
1039                           pDirectoryCB,
1040                           NULL,
1041                           lCount);
1042         }
1043
1044 try_exit:
1045
1046         if( NT_SUCCESS( ntStatus) &&
1047             ntStatus != STATUS_REPARSE)
1048         {
1049
1050             if( pCcb != NULL)
1051             {
1052
1053                 AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
1054                                 TRUE);
1055
1056                 RtlCopyMemory( &pCcb->AuthGroup,
1057                                &stAuthGroup,
1058                                sizeof( GUID));
1059
1060                 //
1061                 // If we have a substitute name, then use it
1062                 //
1063
1064                 if( uniSubstitutedPathName.Buffer != NULL)
1065                 {
1066
1067                     pCcb->FullFileName = uniSubstitutedPathName;
1068
1069                     SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1070
1071                     ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1072                 }
1073                 else
1074                 {
1075
1076                     pCcb->FullFileName = uniRootFileName;
1077
1078                     if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1079                     {
1080
1081                         SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1082
1083                         ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1084                     }
1085                 }
1086
1087                 if( bOpenedReparsePoint)
1088                 {
1089                     SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1090                 }
1091
1092                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1093                               AFS_TRACE_LEVEL_VERBOSE,
1094                               "AFSCommonCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1095                               &pCcb->DirectoryCB->NameInformation.FileName,
1096                               pCcb->DirectoryCB,
1097                               pCcb,
1098                               pCcb->DirectoryCB->OpenReferenceCount);
1099
1100                 ASSERT( pCcb->DirectoryCB->OpenReferenceCount > 0);
1101
1102                 pCcb->CurrentDirIndex = 0;
1103
1104                 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1105                 {
1106
1107                     SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1108                 }
1109
1110                 //
1111                 // Save off the name array for this instance
1112                 //
1113
1114                 pCcb->NameArray = pNameArray;
1115
1116                 pNameArray = NULL;
1117
1118                 AFSReleaseResource( &pCcb->NPCcb->CcbLock);
1119             }
1120
1121             //
1122             // If we make it here then init the FO for the request.
1123             //
1124
1125             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1126                           AFS_TRACE_LEVEL_VERBOSE_2,
1127                           "AFSCommonCreate (%08lX) FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1128                           Irp,
1129                           pFileObject,
1130                           pFcb,
1131                           pCcb);
1132
1133             pFileObject->FsContext = (void *)pFcb;
1134
1135             pFileObject->FsContext2 = (void *)pCcb;
1136
1137             if( pFcb != NULL)
1138             {
1139
1140                 ASSERT( pFcb->OpenHandleCount > 0);
1141
1142                 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1143
1144                 //
1145                 // For files perform additional processing
1146                 //
1147
1148                 switch( pFcb->Header.NodeTypeCode)
1149                 {
1150
1151                     case AFS_FILE_FCB:
1152                     case AFS_IOCTL_FCB:
1153                     {
1154
1155                         pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1156                     }
1157                 }
1158
1159                 //
1160                 // If the user did not request nobuffering then mark the FO as cacheable
1161                 //
1162
1163                 if( bNoIntermediateBuffering)
1164                 {
1165
1166                     pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1167                 }
1168                 else
1169                 {
1170
1171                     pFileObject->Flags |= FO_CACHE_SUPPORTED;
1172                 }
1173
1174                 //
1175                 // If the file was opened for execution then we need to set the bit in the FO
1176                 //
1177
1178                 if( BooleanFlagOn( *pDesiredAccess,
1179                                    FILE_EXECUTE))
1180                 {
1181
1182                     SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1183                 }
1184
1185                 //
1186                 // Update the last access time
1187                 //
1188
1189                 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1190
1191                 if( pCcb != NULL)
1192                 {
1193                     AFSInsertCcb( pFcb,
1194                                   pCcb);
1195                 }
1196             }
1197             else
1198             {
1199
1200                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1201                               AFS_TRACE_LEVEL_ERROR,
1202                               "AFSCommonCreate (%08lX) Returning with NULL Fcb FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1203                               Irp,
1204                               pFileObject,
1205                               pFcb,
1206                               pCcb);
1207             }
1208         }
1209         else
1210         {
1211             if( NT_SUCCESS( ntStatus) &&
1212                 ntStatus == STATUS_REPARSE)
1213             {
1214
1215                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1216                               AFS_TRACE_LEVEL_ERROR,
1217                               "AFSCommonCreate (%08lX) STATUS_REPARSE FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1218                               Irp,
1219                               pFileObject,
1220                               pFcb,
1221                               pCcb);
1222             }
1223
1224             //
1225             // Free up the sub name if we have one
1226             //
1227
1228             if( uniSubstitutedPathName.Buffer != NULL)
1229             {
1230
1231                 AFSExFreePool( uniSubstitutedPathName.Buffer);
1232
1233                 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1234             }
1235         }
1236
1237         //
1238         // Free up the name array ...
1239         //
1240
1241         if( pNameArray != NULL)
1242         {
1243
1244             AFSFreeNameArray( pNameArray);
1245         }
1246
1247         if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1248         {
1249
1250             AFSExFreePool( uniRootFileName.Buffer);
1251         }
1252
1253         if( bReleaseVolume)
1254         {
1255
1256             lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1257
1258             AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1259                           AFS_TRACE_LEVEL_VERBOSE,
1260                           "AFSCommonCreate Decrement count on Volume %08lX Cnt %d\n",
1261                           pVolumeCB,
1262                           lCount);
1263         }
1264
1265         //
1266         // Setup the Irp for completion, the Information has been set previously
1267         //
1268
1269         Irp->IoStatus.Status = ntStatus;
1270     }
1271
1272     return ntStatus;
1273 }
1274
1275 NTSTATUS
1276 AFSOpenAFSRoot( IN PIRP Irp,
1277                 IN AFSFcb **Fcb,
1278                 IN AFSCcb **Ccb)
1279 {
1280
1281     NTSTATUS ntStatus = STATUS_SUCCESS;
1282     LONG lCount;
1283
1284     __Enter
1285     {
1286
1287         //
1288         // Initialize the Ccb for the file.
1289         //
1290
1291         ntStatus = AFSInitCcb( Ccb);
1292
1293         if( !NT_SUCCESS( ntStatus))
1294         {
1295
1296             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1297                           AFS_TRACE_LEVEL_ERROR,
1298                           "AFSOpenAFSRoot (%08lX) Failed to allocate Ccb\n",
1299                           Irp);
1300
1301             try_return( ntStatus);
1302         }
1303
1304         //
1305         // Setup the Ccb
1306         //
1307
1308         (*Ccb)->DirectoryCB = AFSGlobalRoot->DirectoryCB;
1309
1310         //
1311         // Increment the open count on this Fcb
1312         //
1313
1314         lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1315
1316         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1317                       AFS_TRACE_LEVEL_VERBOSE,
1318                       "AFSOpenAFSRoot Increment count on Fcb %08lX Cnt %d\n",
1319                       AFSGlobalRoot->RootFcb,
1320                       lCount);
1321
1322         lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1323
1324         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1325                       AFS_TRACE_LEVEL_VERBOSE,
1326                       "AFSOpenAFSRoot Increment handle count on Fcb %08lX Cnt %d\n",
1327                       AFSGlobalRoot->RootFcb,
1328                       lCount);
1329
1330         *Fcb = AFSGlobalRoot->RootFcb;
1331
1332         //
1333         // Return the open result for this file
1334         //
1335
1336         Irp->IoStatus.Information = FILE_OPENED;
1337
1338 try_exit:
1339
1340         NOTHING;
1341     }
1342
1343     return ntStatus;
1344 }
1345
1346 NTSTATUS
1347 AFSOpenRoot( IN PIRP Irp,
1348              IN AFSVolumeCB *VolumeCB,
1349              IN GUID *AuthGroup,
1350              OUT AFSFcb **RootFcb,
1351              OUT AFSCcb **Ccb)
1352 {
1353
1354     NTSTATUS ntStatus = STATUS_SUCCESS;
1355     PFILE_OBJECT pFileObject = NULL;
1356     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1357     PACCESS_MASK pDesiredAccess = NULL;
1358     USHORT usShareAccess;
1359     ULONG ulOptions;
1360     BOOLEAN bAllocatedCcb = FALSE;
1361     BOOLEAN bReleaseFcb = FALSE;
1362     AFSFileOpenCB   stOpenCB;
1363     AFSFileOpenResultCB stOpenResultCB;
1364     ULONG       ulResultLen = 0;
1365     LONG        lCount;
1366
1367     __Enter
1368     {
1369
1370         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1371         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1372         ulOptions = pIrpSp->Parameters.Create.Options;
1373
1374         pFileObject = pIrpSp->FileObject;
1375
1376         if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1377         {
1378
1379             ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1380
1381             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1382                           AFS_TRACE_LEVEL_ERROR,
1383                           "AFSOpenRoot (%08lX) Attempt to open root as file Status %08lX\n",
1384                           Irp,
1385                           ntStatus);
1386
1387             try_return( ntStatus);
1388         }
1389
1390         //
1391         // Check if we should go and retrieve updated information for the node
1392         //
1393
1394         ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1395                                      AuthGroup,
1396                                      FALSE);
1397
1398         if( !NT_SUCCESS( ntStatus))
1399         {
1400
1401             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1402                           AFS_TRACE_LEVEL_ERROR,
1403                           "AFSOpenRoot (%08lX) Failed to validate root entry Status %08lX\n",
1404                           Irp,
1405                           ntStatus);
1406
1407             try_return( ntStatus);
1408         }
1409
1410         //
1411         // Check with the service that we can open the file
1412         //
1413
1414         RtlZeroMemory( &stOpenCB,
1415                        sizeof( AFSFileOpenCB));
1416
1417         stOpenCB.DesiredAccess = *pDesiredAccess;
1418
1419         stOpenCB.ShareAccess = usShareAccess;
1420
1421         stOpenResultCB.GrantedAccess = 0;
1422
1423         ulResultLen = sizeof( AFSFileOpenResultCB);
1424
1425         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1426                                       AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1427                                       AuthGroup,
1428                                       NULL,
1429                                       &VolumeCB->ObjectInformation.FileId,
1430                                       (void *)&stOpenCB,
1431                                       sizeof( AFSFileOpenCB),
1432                                       (void *)&stOpenResultCB,
1433                                       &ulResultLen);
1434
1435         if( !NT_SUCCESS( ntStatus))
1436         {
1437
1438             UNICODE_STRING uniGUID;
1439
1440             uniGUID.Length = 0;
1441             uniGUID.MaximumLength = 0;
1442             uniGUID.Buffer = NULL;
1443
1444             if( AuthGroup != NULL)
1445             {
1446                 RtlStringFromGUID( *AuthGroup,
1447                                    &uniGUID);
1448             }
1449
1450             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1451                           AFS_TRACE_LEVEL_ERROR,
1452                           "AFSOpenRoot (%08lX) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1453                           Irp,
1454                           VolumeCB->ObjectInformation.FileId.Cell,
1455                           VolumeCB->ObjectInformation.FileId.Volume,
1456                           &uniGUID,
1457                           ntStatus);
1458
1459             if( AuthGroup != NULL)
1460             {
1461                 RtlFreeUnicodeString( &uniGUID);
1462             }
1463
1464             try_return( ntStatus);
1465         }
1466
1467         //
1468         // If the entry is not initialized then do it now
1469         //
1470
1471         if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1472         {
1473
1474             AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1475                             TRUE);
1476
1477             if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1478             {
1479
1480                 ntStatus = AFSEnumerateDirectory( AuthGroup,
1481                                                   &VolumeCB->ObjectInformation,
1482                                                   TRUE);
1483
1484                 if( !NT_SUCCESS( ntStatus))
1485                 {
1486
1487                     AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1488
1489                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1490                                   AFS_TRACE_LEVEL_ERROR,
1491                                   "AFSOpenRoot (%08lX) Failed to enumerate directory Status %08lX\n",
1492                                   Irp,
1493                                   ntStatus);
1494
1495                     try_return( ntStatus);
1496                 }
1497
1498                 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1499             }
1500
1501             AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1502         }
1503
1504         //
1505         // If the root fcb has been initialized then check access otherwise
1506         // init the volume fcb
1507         //
1508
1509         if( VolumeCB->RootFcb == NULL)
1510         {
1511
1512             ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1513                                        VolumeCB);
1514
1515             if( !NT_SUCCESS( ntStatus))
1516             {
1517
1518                 try_return( ntStatus);
1519             }
1520         }
1521         else
1522         {
1523
1524             AFSAcquireExcl( VolumeCB->RootFcb->Header.Resource,
1525                             TRUE);
1526         }
1527
1528         bReleaseFcb = TRUE;
1529
1530         //
1531         // If there are current opens on the Fcb, check the access.
1532         //
1533
1534         if( VolumeCB->RootFcb->OpenHandleCount > 0)
1535         {
1536
1537             ntStatus = IoCheckShareAccess( *pDesiredAccess,
1538                                            usShareAccess,
1539                                            pFileObject,
1540                                            &VolumeCB->RootFcb->ShareAccess,
1541                                            FALSE);
1542
1543             if( !NT_SUCCESS( ntStatus))
1544             {
1545
1546                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1547                               AFS_TRACE_LEVEL_ERROR,
1548                               "AFSOpenRoot (%08lX) Access check failure Status %08lX\n",
1549                               Irp,
1550                               ntStatus);
1551
1552                 try_return( ntStatus);
1553             }
1554         }
1555
1556         //
1557         // Initialize the Ccb for the file.
1558         //
1559
1560         ntStatus = AFSInitCcb( Ccb);
1561
1562         if( !NT_SUCCESS( ntStatus))
1563         {
1564
1565             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1566                           AFS_TRACE_LEVEL_ERROR,
1567                           "AFSOpenRoot (%08lX) Failed to allocate Ccb Status %08lX\n",
1568                           Irp,
1569                           ntStatus);
1570
1571             try_return( ntStatus);
1572         }
1573
1574         bAllocatedCcb = TRUE;
1575
1576         //
1577         // Setup the ccb
1578         //
1579
1580         (*Ccb)->DirectoryCB = VolumeCB->DirectoryCB;
1581
1582         (*Ccb)->GrantedAccess = *pDesiredAccess;
1583
1584         //
1585         // OK, update the share access on the fileobject
1586         //
1587
1588         if( VolumeCB->RootFcb->OpenHandleCount > 0)
1589         {
1590
1591             IoUpdateShareAccess( pFileObject,
1592                                  &VolumeCB->RootFcb->ShareAccess);
1593         }
1594         else
1595         {
1596
1597             //
1598             // Set the access
1599             //
1600
1601             IoSetShareAccess( *pDesiredAccess,
1602                               usShareAccess,
1603                               pFileObject,
1604                               &VolumeCB->RootFcb->ShareAccess);
1605         }
1606
1607         //
1608         // Increment the open count on this Fcb
1609         //
1610
1611         lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1612
1613         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1614                       AFS_TRACE_LEVEL_VERBOSE,
1615                       "AFSOpenRoot Increment count on Fcb %08lX Cnt %d\n",
1616                       VolumeCB->RootFcb,
1617                       lCount);
1618
1619         lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1620
1621         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1622                       AFS_TRACE_LEVEL_VERBOSE,
1623                       "AFSOpenRoot Increment handle count on Fcb %08lX Cnt %d\n",
1624                       VolumeCB->RootFcb,
1625                       lCount);
1626
1627         //
1628         // Indicate the object is held
1629         //
1630
1631         SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1632
1633         //
1634         // Return the open result for this file
1635         //
1636
1637         Irp->IoStatus.Information = FILE_OPENED;
1638
1639         *RootFcb = VolumeCB->RootFcb;
1640
1641 try_exit:
1642
1643         if( bReleaseFcb)
1644         {
1645
1646             AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1647         }
1648
1649         if( !NT_SUCCESS( ntStatus))
1650         {
1651
1652             if( bAllocatedCcb)
1653             {
1654
1655                 AFSRemoveCcb( NULL,
1656                               *Ccb);
1657
1658                 *Ccb = NULL;
1659             }
1660
1661             Irp->IoStatus.Information = 0;
1662         }
1663     }
1664
1665     return ntStatus;
1666 }
1667
1668 NTSTATUS
1669 AFSProcessCreate( IN PIRP               Irp,
1670                   IN GUID              *AuthGroup,
1671                   IN AFSVolumeCB       *VolumeCB,
1672                   IN AFSDirectoryCB    *ParentDirCB,
1673                   IN PUNICODE_STRING    FileName,
1674                   IN PUNICODE_STRING    ComponentName,
1675                   IN PUNICODE_STRING    FullFileName,
1676                   OUT AFSFcb          **Fcb,
1677                   OUT AFSCcb          **Ccb)
1678 {
1679
1680     NTSTATUS ntStatus = STATUS_SUCCESS;
1681     PFILE_OBJECT pFileObject = NULL;
1682     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1683     ULONG ulOptions = 0;
1684     ULONG ulShareMode = 0;
1685     ULONG ulAccess = 0;
1686     ULONG ulAttributes = 0;
1687     LARGE_INTEGER   liAllocationSize = {0,0};
1688     BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1689     BOOLEAN bAllocatedFcb = FALSE;
1690     PACCESS_MASK pDesiredAccess = NULL;
1691     USHORT usShareAccess;
1692     AFSDirectoryCB *pDirEntry = NULL;
1693     AFSObjectInfoCB *pParentObjectInfo = NULL;
1694     AFSObjectInfoCB *pObjectInfo = NULL;
1695     LONG lCount;
1696
1697     __Enter
1698     {
1699
1700         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1701         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1702
1703         pFileObject = pIrpSp->FileObject;
1704
1705         //
1706         // Extract out the options
1707         //
1708
1709         ulOptions = pIrpSp->Parameters.Create.Options;
1710
1711         //
1712         // We pass all attributes they want to apply to the file to the create
1713         //
1714
1715         ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1716
1717         //
1718         // If this is a directory create then set the attribute correctly
1719         //
1720
1721         if( ulOptions & FILE_DIRECTORY_FILE)
1722         {
1723
1724             ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1725         }
1726
1727         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1728                       AFS_TRACE_LEVEL_VERBOSE,
1729                       "AFSProcessCreate (%08lX) Creating file %wZ Attributes %08lX\n",
1730                       Irp,
1731                       FullFileName,
1732                       ulAttributes);
1733
1734         if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1735         {
1736
1737             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1738                           AFS_TRACE_LEVEL_ERROR,
1739                           "AFSProcessCreate Request failed due to read only volume %wZ\n",
1740                           FullFileName);
1741
1742             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
1743         }
1744
1745         pParentObjectInfo = ParentDirCB->ObjectInformation;
1746
1747         //
1748         // Allocate and insert the direntry into the parent node
1749         //
1750
1751         ntStatus = AFSCreateDirEntry( AuthGroup,
1752                                       pParentObjectInfo,
1753                                       ParentDirCB,
1754                                       FileName,
1755                                       ComponentName,
1756                                       ulAttributes,
1757                                       &pDirEntry);
1758
1759         if( !NT_SUCCESS( ntStatus))
1760         {
1761
1762             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1763                           AFS_TRACE_LEVEL_ERROR,
1764                           "AFSProcessCreate (%08lX) Failed to create directory entry %wZ Status %08lX\n",
1765                           Irp,
1766                           FullFileName,
1767                           ntStatus);
1768
1769             try_return( ntStatus);
1770         }
1771
1772         bFileCreated = TRUE;
1773
1774         pObjectInfo = pDirEntry->ObjectInformation;
1775
1776         if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1777             pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1778         {
1779
1780             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1781                           AFS_TRACE_LEVEL_VERBOSE,
1782                           "AFSProcessCreate (%08lX) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1783                           Irp,
1784                           &pDirEntry->NameInformation.FileName,
1785                           pObjectInfo->FileId.Cell,
1786                           pObjectInfo->FileId.Volume,
1787                           pObjectInfo->FileId.Vnode,
1788                           pObjectInfo->FileId.Unique);
1789
1790             ntStatus = AFSEvaluateNode( AuthGroup,
1791                                         pDirEntry);
1792
1793             if( !NT_SUCCESS( ntStatus))
1794             {
1795
1796                 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
1797                 {
1798
1799                     if ( pParentObjectInfo == pObjectInfo->ParentObjectInformation)
1800                     {
1801
1802                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1803                                       AFS_TRACE_LEVEL_ERROR,
1804                                       "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1805                                       Irp,
1806                                       &pDirEntry->NameInformation.FileName,
1807                                       pObjectInfo->FileId.Cell,
1808                                       pObjectInfo->FileId.Volume,
1809                                       pObjectInfo->FileId.Vnode,
1810                                       pObjectInfo->FileId.Unique,
1811                                       pParentObjectInfo->FileId.Cell,
1812                                       pParentObjectInfo->FileId.Volume,
1813                                       pParentObjectInfo->FileId.Vnode,
1814                                       pParentObjectInfo->FileId.Unique,
1815                                       ntStatus);
1816                     }
1817                     else if ( pObjectInfo->ParentObjectInformation == NULL)
1818                     {
1819
1820                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1821                                       AFS_TRACE_LEVEL_ERROR,
1822                                       "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
1823                                       Irp,
1824                                       &pDirEntry->NameInformation.FileName,
1825                                       pObjectInfo->FileId.Cell,
1826                                       pObjectInfo->FileId.Volume,
1827                                       pObjectInfo->FileId.Vnode,
1828                                       pObjectInfo->FileId.Unique,
1829                                       pParentObjectInfo->FileId.Cell,
1830                                       pParentObjectInfo->FileId.Volume,
1831                                       pParentObjectInfo->FileId.Vnode,
1832                                       pParentObjectInfo->FileId.Unique,
1833                                       ntStatus);
1834                     }
1835                     else
1836                     {
1837
1838                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1839                                       AFS_TRACE_LEVEL_ERROR,
1840                                       "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1841                                       Irp,
1842                                       &pDirEntry->NameInformation.FileName,
1843                                       pObjectInfo->FileId.Cell,
1844                                       pObjectInfo->FileId.Volume,
1845                                       pObjectInfo->FileId.Vnode,
1846                                       pObjectInfo->FileId.Unique,
1847                                       pParentObjectInfo->FileId.Cell,
1848                                       pParentObjectInfo->FileId.Volume,
1849                                       pParentObjectInfo->FileId.Vnode,
1850                                       pParentObjectInfo->FileId.Unique,
1851                                       pObjectInfo->ParentObjectInformation->FileId.Cell,
1852                                       pObjectInfo->ParentObjectInformation->FileId.Volume,
1853                                       pObjectInfo->ParentObjectInformation->FileId.Vnode,
1854                                       pObjectInfo->ParentObjectInformation->FileId.Unique,
1855                                       ntStatus);
1856                     }
1857                 }
1858                 else
1859                 {
1860
1861                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1862                                   AFS_TRACE_LEVEL_ERROR,
1863                                   "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1864                                   Irp,
1865                                   &pDirEntry->NameInformation.FileName,
1866                                   pObjectInfo->FileId.Cell,
1867                                   pObjectInfo->FileId.Volume,
1868                                   pObjectInfo->FileId.Vnode,
1869                                   pObjectInfo->FileId.Unique,
1870                                   ntStatus);
1871                 }
1872
1873                 try_return( ntStatus);
1874             }
1875
1876             ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1877         }
1878
1879         //
1880         // We may have raced and the Fcb is already created
1881         //
1882
1883         if( pObjectInfo->Fcb != NULL)
1884         {
1885
1886             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1887                           AFS_TRACE_LEVEL_VERBOSE,
1888                           "AFSProcessCreate (%08lX) Not allocating Fcb for file %wZ\n",
1889                           Irp,
1890                           FullFileName);
1891
1892             *Fcb = pObjectInfo->Fcb;
1893
1894             AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
1895                             TRUE);
1896         }
1897         else
1898         {
1899
1900             //
1901             // Allocate and initialize the Fcb for the file.
1902             //
1903
1904             ntStatus = AFSInitFcb( pDirEntry);
1905
1906             *Fcb = pObjectInfo->Fcb;
1907
1908             if( !NT_SUCCESS( ntStatus))
1909             {
1910
1911                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1912                               AFS_TRACE_LEVEL_ERROR,
1913                               "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
1914                               Irp,
1915                               FullFileName,
1916                               ntStatus);
1917
1918                 try_return( ntStatus);
1919             }
1920
1921             if ( ntStatus != STATUS_REPARSE)
1922             {
1923
1924                 bAllocatedFcb = TRUE;
1925             }
1926
1927             ntStatus = STATUS_SUCCESS;
1928         }
1929
1930         //
1931         // Increment the open count on this Fcb
1932         //
1933
1934         lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1935
1936         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1937                       AFS_TRACE_LEVEL_VERBOSE,
1938                       "AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n",
1939                       *Fcb,
1940                       lCount);
1941
1942         bReleaseFcb = TRUE;
1943
1944         //
1945         // Initialize the Ccb for the file.
1946         //
1947
1948         ntStatus = AFSInitCcb( Ccb);
1949
1950         if( !NT_SUCCESS( ntStatus))
1951         {
1952
1953             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1954                           AFS_TRACE_LEVEL_ERROR,
1955                           "AFSProcessCreate (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
1956                           Irp,
1957                           FullFileName,
1958                           ntStatus);
1959
1960             try_return( ntStatus);
1961         }
1962
1963         bAllocatedCcb = TRUE;
1964
1965         //
1966         // Initialize the Ccb
1967         //
1968
1969         (*Ccb)->DirectoryCB = pDirEntry;
1970
1971         (*Ccb)->GrantedAccess = *pDesiredAccess;
1972
1973         //
1974         // If this is a file, update the headers filesizes.
1975         //
1976
1977         if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1978         {
1979
1980             //
1981             // Update the sizes with the information passed in
1982             //
1983
1984             (*Fcb)->Header.AllocationSize.QuadPart  = pObjectInfo->AllocationSize.QuadPart;
1985             (*Fcb)->Header.FileSize.QuadPart        = pObjectInfo->EndOfFile.QuadPart;
1986             (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1987
1988             //
1989             // Notify the system of the addition
1990             //
1991
1992             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1993                                             *Ccb,
1994                                             (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1995                                             (ULONG)FILE_ACTION_ADDED);
1996
1997             (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
1998         }
1999         else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2000         {
2001
2002             //
2003             // This is a new directory node so indicate it has been enumerated
2004             //
2005
2006             SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
2007
2008             //
2009             // And the parent directory entry
2010             //
2011
2012             KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2013
2014             //
2015             // Notify the system of the addition
2016             //
2017
2018             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2019                                             *Ccb,
2020                                             (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2021                                             (ULONG)FILE_ACTION_ADDED);
2022         }
2023         else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2024                  (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2025                  (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2026                  (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
2027         {
2028
2029             //
2030             // And the parent directory entry
2031             //
2032
2033             KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2034
2035             //
2036             // Notify the system of the addition
2037             //
2038
2039             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2040                                             *Ccb,
2041                                             (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2042                                             (ULONG)FILE_ACTION_ADDED);
2043         }
2044
2045         //
2046         // Save off the access for the open
2047         //
2048
2049         IoSetShareAccess( *pDesiredAccess,
2050                           usShareAccess,
2051                           pFileObject,
2052                           &(*Fcb)->ShareAccess);
2053
2054         lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2055
2056         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2057                       AFS_TRACE_LEVEL_VERBOSE,
2058                       "AFSProcessCreate Increment handle count on Fcb %08lX Cnt %d\n",
2059                       (*Fcb),
2060                       lCount);
2061
2062         //
2063         // Increment the open reference and handle on the parent node
2064         //
2065
2066         lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2067
2068         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2069                       AFS_TRACE_LEVEL_VERBOSE,
2070                       "AFSProcessCreate Increment child open handle count on Parent object %08lX Cnt %d\n",
2071                       pObjectInfo->ParentObjectInformation,
2072                       lCount);
2073
2074         lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2075
2076         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2077                       AFS_TRACE_LEVEL_VERBOSE,
2078                       "AFSProcessCreate Increment child open ref count on Parent object %08lX Cnt %d\n",
2079                       pObjectInfo->ParentObjectInformation,
2080                       lCount);
2081
2082         if( ulOptions & FILE_DELETE_ON_CLOSE)
2083         {
2084
2085             //
2086             // Mark it for delete on close
2087             //
2088
2089             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2090                           AFS_TRACE_LEVEL_VERBOSE,
2091                           "AFSProcessCreate (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2092                           Irp,
2093                           pDirEntry,
2094                           FullFileName);
2095
2096             SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2097         }
2098
2099         //
2100         // Indicate the object is locked in the service
2101         //
2102
2103         SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2104
2105         //
2106         // Return the open result for this file
2107         //
2108
2109         Irp->IoStatus.Information = FILE_CREATED;
2110
2111 try_exit:
2112
2113         //
2114         // If we created the Fcb we need to release the resources
2115         //
2116
2117         if( bReleaseFcb)
2118         {
2119
2120             if( !NT_SUCCESS( ntStatus))
2121             {
2122                 //
2123                 // Decrement the open count on this Fcb
2124                 //
2125
2126                 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2127
2128                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2129                               AFS_TRACE_LEVEL_VERBOSE,
2130                               "AFSProcessCreate Decrement count on Fcb %08lX Cnt %d\n",
2131                               *Fcb,
2132                               lCount);
2133             }
2134
2135             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2136         }
2137
2138         if( !NT_SUCCESS( ntStatus))
2139         {
2140
2141             if( bFileCreated)
2142             {
2143
2144                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2145                               AFS_TRACE_LEVEL_VERBOSE,
2146                               "AFSProcessCreate Create failed, removing DE %p from aprent object %p Status %08lX\n",
2147                               pDirEntry,
2148                               pParentObjectInfo,
2149                               ntStatus);
2150
2151                 //
2152                 // Remove the dir entry from the parent
2153                 //
2154
2155                 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2156                                 TRUE);
2157
2158                 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2159
2160                 AFSNotifyDelete( pDirEntry,
2161                                  AuthGroup,
2162                                  FALSE);
2163
2164                 //
2165                 // Decrement the reference added during initialization of the DE
2166                 //
2167
2168                 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
2169
2170                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2171                               AFS_TRACE_LEVEL_VERBOSE,
2172                               "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2173                               &pDirEntry->NameInformation.FileName,
2174                               pDirEntry,
2175                               lCount);
2176
2177                 //
2178                 // Pull the directory entry from the parent
2179                 //
2180
2181                 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2182                                             pDirEntry,
2183                                             FALSE); // Leave it in the enum list so the worker cleans it up
2184
2185                 //
2186                 // Tag the parent as needing verification
2187                 //
2188
2189                 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2190
2191                 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2192
2193                 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2194             }
2195
2196             if( bAllocatedCcb)
2197             {
2198
2199                 AFSRemoveCcb( NULL,
2200                               *Ccb);
2201             }
2202
2203             if( bAllocatedFcb)
2204             {
2205
2206                 AFSRemoveFcb( &pObjectInfo->Fcb);
2207             }
2208
2209             *Fcb = NULL;
2210
2211             *Ccb = NULL;
2212         }
2213     }
2214
2215     return ntStatus;
2216 }
2217
2218 NTSTATUS
2219 AFSOpenTargetDirectory( IN PIRP Irp,
2220                         IN AFSVolumeCB *VolumeCB,
2221                         IN AFSDirectoryCB *ParentDirectoryCB,
2222                         IN AFSDirectoryCB *TargetDirectoryCB,
2223                         IN UNICODE_STRING *TargetName,
2224                         OUT AFSFcb **Fcb,
2225                         OUT AFSCcb **Ccb)
2226 {
2227
2228     NTSTATUS ntStatus = STATUS_SUCCESS;
2229     PFILE_OBJECT pFileObject = NULL;
2230     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2231     PACCESS_MASK pDesiredAccess = NULL;
2232     USHORT usShareAccess;
2233     BOOLEAN bAllocatedCcb = FALSE;
2234     BOOLEAN bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2235     AFSObjectInfoCB *pParentObject = NULL, *pTargetObject = NULL;
2236     UNICODE_STRING uniTargetName;
2237     LONG lCount;
2238
2239     __Enter
2240     {
2241
2242         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2243         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2244
2245         pFileObject = pIrpSp->FileObject;
2246
2247         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2248                       AFS_TRACE_LEVEL_VERBOSE,
2249                       "AFSOpenTargetDirectory (%08lX) Processing file %wZ\n",
2250                       Irp,
2251                       TargetName);
2252
2253         pParentObject = ParentDirectoryCB->ObjectInformation;
2254
2255         if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2256         {
2257
2258             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2259         }
2260
2261         //
2262         // Make sure we have an Fcb for the access
2263         //
2264
2265         if( pParentObject->Fcb != NULL)
2266         {
2267
2268             *Fcb = pParentObject->Fcb;
2269
2270             AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
2271                             TRUE);
2272         }
2273         else
2274         {
2275
2276             //
2277             // Allocate and initialize the Fcb for the file.
2278             //
2279
2280             ntStatus = AFSInitFcb( ParentDirectoryCB);
2281
2282             *Fcb = pParentObject->Fcb;
2283
2284             if( !NT_SUCCESS( ntStatus))
2285             {
2286
2287                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2288                               AFS_TRACE_LEVEL_ERROR,
2289                               "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
2290                               Irp,
2291                               &ParentDirectoryCB->NameInformation.FileName,
2292                               ntStatus);
2293
2294                 try_return( ntStatus);
2295             }
2296
2297             if ( ntStatus == STATUS_REPARSE)
2298             {
2299
2300                 bAllocatedFcb = TRUE;
2301             }
2302
2303             ntStatus = STATUS_SUCCESS;
2304         }
2305
2306         //
2307         // Increment the open count on this Fcb
2308         //
2309
2310         lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2311
2312         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2313                       AFS_TRACE_LEVEL_VERBOSE,
2314                       "AFSOpenTargetDirectory Increment count on Fcb %08lX Cnt %d\n",
2315                       pParentObject->Fcb,
2316                       lCount);
2317
2318         bReleaseFcb = TRUE;
2319
2320         //
2321         // If there are current opens on the Fcb, check the access.
2322         //
2323
2324         if( pParentObject->Fcb->OpenHandleCount > 0)
2325         {
2326
2327             ntStatus = IoCheckShareAccess( *pDesiredAccess,
2328                                            usShareAccess,
2329                                            pFileObject,
2330                                            &pParentObject->Fcb->ShareAccess,
2331                                            FALSE);
2332
2333             if( !NT_SUCCESS( ntStatus))
2334             {
2335
2336                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2337                               AFS_TRACE_LEVEL_ERROR,
2338                               "AFSOpenTargetDirectory (%08lX) Access check failure %wZ Status %08lX\n",
2339                               Irp,
2340                               &ParentDirectoryCB->NameInformation.FileName,
2341                               ntStatus);
2342
2343                 try_return( ntStatus);
2344             }
2345         }
2346
2347         //
2348         // Initialize the Ccb for the file.
2349         //
2350
2351         ntStatus = AFSInitCcb( Ccb);
2352
2353         if( !NT_SUCCESS( ntStatus))
2354         {
2355
2356             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2357                           AFS_TRACE_LEVEL_ERROR,
2358                           "AFSOpenTargetDirectory (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2359                           Irp,
2360                           &ParentDirectoryCB->NameInformation.FileName,
2361                           ntStatus);
2362
2363             try_return( ntStatus);
2364         }
2365
2366         bAllocatedCcb = TRUE;
2367
2368         //
2369         // Initialize the Ccb
2370         //
2371
2372         (*Ccb)->DirectoryCB = ParentDirectoryCB;
2373
2374         (*Ccb)->GrantedAccess = *pDesiredAccess;
2375
2376         if( TargetDirectoryCB != NULL &&
2377             FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2378                                 TargetName,
2379                                 FALSE,
2380                                 NULL))
2381         {
2382
2383             Irp->IoStatus.Information = FILE_EXISTS;
2384
2385             uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2386         }
2387         else
2388         {
2389
2390             Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2391
2392             uniTargetName = *TargetName;
2393         }
2394
2395         //
2396         // Update the filename in the fileobject for rename processing
2397         //
2398
2399         RtlCopyMemory( pFileObject->FileName.Buffer,
2400                        uniTargetName.Buffer,
2401                        uniTargetName.Length);
2402
2403         pFileObject->FileName.Length = uniTargetName.Length;
2404
2405         //
2406         // OK, update the share access on the fileobject
2407         //
2408
2409         if( pParentObject->Fcb->OpenHandleCount > 0)
2410         {
2411
2412             IoUpdateShareAccess( pFileObject,
2413                                  &pParentObject->Fcb->ShareAccess);
2414         }
2415         else
2416         {
2417
2418             //
2419             // Set the access
2420             //
2421
2422             IoSetShareAccess( *pDesiredAccess,
2423                               usShareAccess,
2424                               pFileObject,
2425                               &pParentObject->Fcb->ShareAccess);
2426         }
2427
2428         lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2429
2430         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2431                       AFS_TRACE_LEVEL_VERBOSE,
2432                       "AFSOpenTargetDirectory Increment handle count on Fcb %08lX Cnt %d\n",
2433                       pParentObject->Fcb,
2434                       lCount);
2435
2436         //
2437         // Increment the open reference and handle on the parent node
2438         //
2439
2440         if( pParentObject->ParentObjectInformation != NULL)
2441         {
2442
2443             lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2444
2445             AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2446                           AFS_TRACE_LEVEL_VERBOSE,
2447                           "AFSOpenTargetDirectory Increment child open handle count on Parent object %08lX Cnt %d\n",
2448                           pParentObject->ParentObjectInformation,
2449                           lCount);
2450
2451             lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2452
2453             AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2454                           AFS_TRACE_LEVEL_VERBOSE,
2455                           "AFSOpenTargetDirectory Increment child open ref count on Parent object %08lX Cnt %d\n",
2456                           pParentObject->ParentObjectInformation,
2457                           lCount);
2458         }
2459
2460 try_exit:
2461
2462         if( bReleaseFcb)
2463         {
2464
2465             if( !NT_SUCCESS( ntStatus))
2466             {
2467                 //
2468                 // Decrement the open count on this Fcb
2469                 //
2470
2471                 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2472
2473                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2474                               AFS_TRACE_LEVEL_VERBOSE,
2475                               "AFSOpenTargetDirectory Decrement count on Fcb %08lX Cnt %d\n",
2476                               pParentObject->Fcb,
2477                               lCount);
2478             }
2479
2480             AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2481         }
2482
2483         if( !NT_SUCCESS( ntStatus))
2484         {
2485
2486             if( bAllocatedCcb)
2487             {
2488
2489                 AFSRemoveCcb( NULL,
2490                               *Ccb);
2491             }
2492
2493             *Ccb = NULL;
2494
2495             if( bAllocatedFcb)
2496             {
2497
2498                 AFSRemoveFcb( &pParentObject->Fcb);
2499             }
2500
2501             *Fcb = NULL;
2502         }
2503     }
2504
2505     return ntStatus;
2506 }
2507
2508 NTSTATUS
2509 AFSProcessOpen( IN PIRP Irp,
2510                 IN GUID *AuthGroup,
2511                 IN AFSVolumeCB *VolumeCB,
2512                 IN AFSDirectoryCB *ParentDirCB,
2513                 IN AFSDirectoryCB *DirectoryCB,
2514                 OUT AFSFcb **Fcb,
2515                 OUT AFSCcb **Ccb)
2516 {
2517
2518     NTSTATUS ntStatus = STATUS_SUCCESS;
2519     PFILE_OBJECT pFileObject = NULL;
2520     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2521     PACCESS_MASK pDesiredAccess = NULL;
2522     USHORT usShareAccess;
2523     BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2524     ULONG ulAdditionalFlags = 0, ulOptions = 0;
2525     AFSFileOpenCB   stOpenCB;
2526     AFSFileOpenResultCB stOpenResultCB;
2527     ULONG       ulResultLen = 0;
2528     AFSObjectInfoCB *pParentObjectInfo = NULL;
2529     AFSObjectInfoCB *pObjectInfo = NULL;
2530     ULONG       ulFileAccess = 0;
2531     AFSFileAccessReleaseCB stReleaseFileAccess;
2532     LONG lCount;
2533
2534     __Enter
2535     {
2536
2537         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2538         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2539
2540         pFileObject = pIrpSp->FileObject;
2541
2542         pParentObjectInfo = ParentDirCB->ObjectInformation;
2543
2544         pObjectInfo = DirectoryCB->ObjectInformation;
2545
2546         //
2547         // Check if the entry is pending a deletion
2548         //
2549
2550         if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2551         {
2552
2553             ntStatus = STATUS_DELETE_PENDING;
2554
2555             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2556                           AFS_TRACE_LEVEL_ERROR,
2557                           "AFSProcessOpen (%08lX) Entry pending delete %wZ Status %08lX\n",
2558                           Irp,
2559                           &DirectoryCB->NameInformation.FileName,
2560                           ntStatus);
2561
2562             try_return( ntStatus);
2563         }
2564
2565         //
2566         // Extract out the options
2567         //
2568
2569         ulOptions = pIrpSp->Parameters.Create.Options;
2570
2571         //
2572         // Check if we should go and retrieve updated information for the node
2573         //
2574
2575         ntStatus = AFSValidateEntry( DirectoryCB,
2576                                      AuthGroup,
2577                                      FALSE);
2578
2579         if( !NT_SUCCESS( ntStatus))
2580         {
2581
2582             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2583                           AFS_TRACE_LEVEL_ERROR,
2584                           "AFSProcessOpen (%08lX) Failed to validate entry %wZ Status %08lX\n",
2585                           Irp,
2586                           &DirectoryCB->NameInformation.FileName,
2587                           ntStatus);
2588
2589             try_return( ntStatus);
2590         }
2591
2592         //
2593         // If this is marked for delete on close then be sure we can delete the entry
2594         //
2595
2596         if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2597         {
2598
2599             ntStatus = AFSNotifyDelete( DirectoryCB,
2600                                         AuthGroup,
2601                                         TRUE);
2602
2603             if( !NT_SUCCESS( ntStatus))
2604             {
2605
2606                 ntStatus = STATUS_CANNOT_DELETE;
2607
2608                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2609                               AFS_TRACE_LEVEL_ERROR,
2610                               "AFSProcessOpen (%08lX) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2611                               Irp,
2612                               &DirectoryCB->NameInformation.FileName,
2613                               ntStatus);
2614
2615                 try_return( ntStatus);
2616             }
2617         }
2618
2619         //
2620         // Be sure we have an Fcb for the current object
2621         //
2622
2623         if( pObjectInfo->Fcb == NULL)
2624         {
2625
2626             ntStatus = AFSInitFcb( DirectoryCB);
2627
2628             if( !NT_SUCCESS( ntStatus))
2629             {
2630
2631                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2632                               AFS_TRACE_LEVEL_ERROR,
2633                               "AFSProcessOpen (%08lX) Failed to init fcb on %wZ Status %08lX\n",
2634                               Irp,
2635                               &DirectoryCB->NameInformation.FileName,
2636                               ntStatus);
2637
2638                 try_return( ntStatus);
2639             }
2640
2641             if ( ntStatus != STATUS_REPARSE)
2642             {
2643
2644                 bAllocatedFcb = TRUE;
2645             }
2646
2647             ntStatus = STATUS_SUCCESS;
2648         }
2649         else
2650         {
2651
2652             AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
2653                             TRUE);
2654         }
2655
2656         //
2657         // Increment the open count on this Fcb
2658         //
2659
2660         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2661
2662         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2663                       AFS_TRACE_LEVEL_VERBOSE,
2664                       "AFSProcessOpen Increment2 count on Fcb %08lX Cnt %d\n",
2665                       pObjectInfo->Fcb,
2666                       lCount);
2667
2668         bReleaseFcb = TRUE;
2669
2670         //
2671         // Check access on the entry
2672         //
2673
2674         if( pObjectInfo->Fcb->OpenHandleCount > 0)
2675         {
2676
2677             ntStatus = IoCheckShareAccess( *pDesiredAccess,
2678                                            usShareAccess,
2679                                            pFileObject,
2680                                            &pObjectInfo->Fcb->ShareAccess,
2681                                            FALSE);
2682
2683             if( !NT_SUCCESS( ntStatus))
2684             {
2685
2686                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2687                               AFS_TRACE_LEVEL_ERROR,
2688                               "AFSProcessOpen (%08lX) Failed to check share access on %wZ Status %08lX\n",
2689                               Irp,
2690                               &DirectoryCB->NameInformation.FileName,
2691                               ntStatus);
2692
2693                 try_return( ntStatus);
2694             }
2695         }
2696
2697         //
2698         // Additional checks
2699         //
2700
2701         if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2702         {
2703
2704             //
2705             // If the caller is asking for write access then try to flush the image section
2706             //
2707
2708             if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2709                 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2710             {
2711
2712                 if( !MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2713                                           MmFlushForWrite))
2714                 {
2715
2716                     ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2717                                                                             STATUS_SHARING_VIOLATION;
2718
2719                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2720                                   AFS_TRACE_LEVEL_ERROR,
2721                                   "AFSProcessOpen (%08lX) Failed to flush image section %wZ Status %08lX\n",
2722                                   Irp,
2723                                   &DirectoryCB->NameInformation.FileName,
2724                                   ntStatus);
2725
2726                     try_return( ntStatus);
2727                 }
2728             }
2729
2730             if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2731             {
2732
2733                 ntStatus = STATUS_NOT_A_DIRECTORY;
2734
2735                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2736                               AFS_TRACE_LEVEL_ERROR,
2737                               "AFSProcessOpen (%08lX) Attempt to open file as directory %wZ Status %08lX\n",
2738                               Irp,
2739                               &DirectoryCB->NameInformation.FileName,
2740                               ntStatus);
2741
2742                 try_return( ntStatus);
2743             }
2744
2745             pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2746         }
2747         else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2748                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2749         {
2750
2751             if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2752             {
2753
2754                 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2755
2756                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2757                               AFS_TRACE_LEVEL_ERROR,
2758                               "AFSProcessOpen (%08lX) Attempt to open directory as file %wZ Status %08lX\n",
2759                               Irp,
2760                               &DirectoryCB->NameInformation.FileName,
2761                               ntStatus);
2762
2763                 try_return( ntStatus);
2764             }
2765         }
2766         else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2767                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2768                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2769                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2770         {
2771
2772         }
2773         else
2774         {
2775             ASSERT( FALSE);
2776             try_return( ntStatus = STATUS_UNSUCCESSFUL);
2777         }
2778
2779         //
2780         // Check with the service that we can open the file
2781         //
2782
2783         stOpenCB.ParentId = pParentObjectInfo->FileId;
2784
2785         stOpenCB.DesiredAccess = *pDesiredAccess;
2786
2787         stOpenCB.ShareAccess = usShareAccess;
2788
2789         stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2790
2791         stOpenCB.Identifier = (ULONGLONG)pFileObject;
2792
2793         stOpenResultCB.GrantedAccess = 0;
2794
2795         ulResultLen = sizeof( AFSFileOpenResultCB);
2796
2797         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2798                                       AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2799                                       AuthGroup,
2800                                       &DirectoryCB->NameInformation.FileName,
2801                                       &pObjectInfo->FileId,
2802                                       (void *)&stOpenCB,
2803                                       sizeof( AFSFileOpenCB),
2804                                       (void *)&stOpenResultCB,
2805                                       &ulResultLen);
2806
2807         if( !NT_SUCCESS( ntStatus))
2808         {
2809
2810             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2811                           AFS_TRACE_LEVEL_ERROR,
2812                           "AFSProcessOpen (%08lX) Failed open in service %wZ Status %08lX\n",
2813                           Irp,
2814                           &DirectoryCB->NameInformation.FileName,
2815                           ntStatus);
2816
2817             try_return( ntStatus);
2818         }
2819
2820         //
2821         // Save the granted access in case we need to release it below
2822         //
2823
2824         ulFileAccess = stOpenResultCB.FileAccess;
2825
2826         //
2827         // Check if there is a conflict
2828         //
2829
2830         if( !AFSCheckAccess( *pDesiredAccess,
2831                              stOpenResultCB.GrantedAccess,
2832                              BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2833         {
2834
2835             ntStatus = STATUS_ACCESS_DENIED;
2836
2837             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2838                           AFS_TRACE_LEVEL_ERROR,
2839                           "AFSProcessOpen (%08lX) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2840                           Irp,
2841                           *pDesiredAccess,
2842                           stOpenResultCB.GrantedAccess,
2843                           &DirectoryCB->NameInformation.FileName,
2844                           ntStatus);
2845
2846             try_return( ntStatus);
2847         }
2848
2849         //
2850         // Initialize the Ccb for the file.
2851         //
2852
2853         ntStatus = AFSInitCcb( Ccb);
2854
2855         if( !NT_SUCCESS( ntStatus))
2856         {
2857
2858             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2859                           AFS_TRACE_LEVEL_ERROR,
2860                           "AFSProcessOpen (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2861                           Irp,
2862                           &DirectoryCB->NameInformation.FileName,
2863                           ntStatus);
2864
2865             try_return( ntStatus);
2866         }
2867
2868         bAllocatedCcb = TRUE;
2869
2870         (*Ccb)->DirectoryCB = DirectoryCB;
2871
2872         (*Ccb)->FileAccess = ulFileAccess;
2873
2874         (*Ccb)->GrantedAccess = *pDesiredAccess;
2875
2876         //
2877         // Perform the access check on the target if this is a mount point or symlink
2878         //
2879
2880         if( pObjectInfo->Fcb->OpenHandleCount > 0)
2881         {
2882
2883             IoUpdateShareAccess( pFileObject,
2884                                  &pObjectInfo->Fcb->ShareAccess);
2885         }
2886         else
2887         {
2888
2889             //
2890             // Set the access
2891             //
2892
2893             IoSetShareAccess( *pDesiredAccess,
2894                               usShareAccess,
2895                               pFileObject,
2896                               &pObjectInfo->Fcb->ShareAccess);
2897         }
2898
2899         lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2900
2901         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2902                       AFS_TRACE_LEVEL_VERBOSE,
2903                       "AFSProcessOpen Increment handle count on Fcb %08lX Cnt %d\n",
2904                       pObjectInfo->Fcb,
2905                       lCount);
2906
2907         //
2908         // Increment the open reference and handle on the parent node
2909         //
2910
2911         lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2912
2913         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2914                       AFS_TRACE_LEVEL_VERBOSE,
2915                       "AFSProcessOpen Increment child open handle count on Parent object %08lX Cnt %d\n",
2916                       pObjectInfo->ParentObjectInformation,
2917                       lCount);
2918
2919         lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2920
2921         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2922                       AFS_TRACE_LEVEL_VERBOSE,
2923                       "AFSProcessOpen Increment child open ref count on Parent object %08lX Cnt %d\n",
2924                       pObjectInfo->ParentObjectInformation,
2925                       lCount);
2926
2927         if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2928         {
2929
2930             //
2931             // Mark it for delete on close
2932             //
2933
2934             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2935                           AFS_TRACE_LEVEL_VERBOSE,
2936                           "AFSProcessOpen (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2937                           Irp,
2938                           DirectoryCB,
2939                           &DirectoryCB->NameInformation.FileName);
2940
2941             SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2942         }
2943
2944         //
2945         // Indicate the object is held
2946         //
2947
2948         SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2949
2950         //
2951         // Return the open result for this file
2952         //
2953
2954         Irp->IoStatus.Information = FILE_OPENED;
2955
2956         *Fcb = pObjectInfo->Fcb;
2957
2958 try_exit:
2959
2960         if( bReleaseFcb)
2961         {
2962
2963             if( !NT_SUCCESS( ntStatus))
2964             {
2965                 //
2966                 // Decrement the open count on this Fcb
2967                 //
2968
2969                 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2970
2971                 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2972                               AFS_TRACE_LEVEL_VERBOSE,
2973                               "AFSProcessOpen Decrement2 count on Fcb %08lX Cnt %d\n",
2974                               pObjectInfo->Fcb,
2975                               lCount);
2976             }
2977
2978             AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2979         }
2980
2981         if( !NT_SUCCESS( ntStatus))
2982         {
2983
2984             if ( ulFileAccess > 0)
2985             {
2986
2987                 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2988
2989                 stReleaseFileAccess.FileAccess = ulFileAccess;
2990
2991                 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2992
2993                 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2994                                    AFS_REQUEST_FLAG_SYNCHRONOUS,
2995                                    AuthGroup,
2996                                    &DirectoryCB->NameInformation.FileName,
2997                                    &pObjectInfo->FileId,
2998                                    (void *)&stReleaseFileAccess,
2999                                    sizeof( AFSFileAccessReleaseCB),
3000                                    NULL,
3001                                    NULL);
3002             }
3003
3004             if( bAllocatedCcb)
3005             {
3006
3007                 AFSRemoveCcb( NULL,
3008                               *Ccb);
3009             }
3010
3011             *Ccb = NULL;
3012
3013             if( bAllocatedFcb)
3014             {
3015
3016                 AFSRemoveFcb( &pObjectInfo->Fcb);
3017             }
3018
3019             *Fcb = NULL;
3020         }
3021     }
3022
3023     return ntStatus;
3024 }
3025
3026 NTSTATUS
3027 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
3028                               IN PIRP           Irp,
3029                               IN AFSVolumeCB   *VolumeCB,
3030                               IN GUID          *AuthGroup,
3031                               IN AFSDirectoryCB *ParentDirCB,
3032                               IN AFSDirectoryCB *DirectoryCB,
3033                               OUT AFSFcb       **Fcb,
3034                               OUT AFSCcb       **Ccb)
3035 {
3036
3037     NTSTATUS ntStatus = STATUS_SUCCESS;
3038     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3039     PFILE_OBJECT pFileObject = NULL;
3040     LARGE_INTEGER liZero = {0,0};
3041     BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
3042     ULONG   ulAttributes = 0;
3043     LARGE_INTEGER liTime;
3044     ULONG ulCreateDisposition = 0;
3045     BOOLEAN bAllocatedCcb = FALSE, bAllocatedFcb = FALSE;
3046     PACCESS_MASK pDesiredAccess = NULL;
3047     USHORT usShareAccess;
3048     AFSObjectInfoCB *pParentObjectInfo = NULL;
3049     AFSObjectInfoCB *pObjectInfo = NULL;
3050     LONG lCount;
3051     LARGE_INTEGER liSaveSize;
3052     LARGE_INTEGER liSaveVDL;
3053     LARGE_INTEGER liSaveAlloc;
3054
3055     __Enter
3056     {
3057
3058         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3059
3060         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
3061
3062         pFileObject = pIrpSp->FileObject;
3063
3064         ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
3065
3066         ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
3067
3068         if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
3069         {
3070
3071             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3072                           AFS_TRACE_LEVEL_ERROR,
3073                           "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3074                           Irp,
3075                           &DirectoryCB->NameInformation.FileName);
3076
3077             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3078         }
3079
3080         pParentObjectInfo = ParentDirCB->ObjectInformation;
3081
3082         pObjectInfo = DirectoryCB->ObjectInformation;
3083
3084         //
3085         // Check if we should go and retrieve updated information for the node
3086         //
3087
3088         ntStatus = AFSValidateEntry( DirectoryCB,
3089                                      AuthGroup,
3090                                      FALSE);
3091
3092         if( !NT_SUCCESS( ntStatus))
3093         {
3094
3095             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3096                           AFS_TRACE_LEVEL_ERROR,
3097                           "AFSProcessOverwriteSupersede (%08lX) Failed to validate entry %wZ Status %08lX\n",
3098                           Irp,
3099                           &DirectoryCB->NameInformation.FileName,
3100                           ntStatus);
3101
3102             try_return( ntStatus);
3103         }
3104
3105         //
3106         // Be sure we have an Fcb for the object block
3107         //
3108
3109         if( pObjectInfo->Fcb == NULL)
3110         {
3111
3112             ntStatus = AFSInitFcb( DirectoryCB);
3113
3114             *Fcb = pObjectInfo->Fcb;
3115
3116             if( !NT_SUCCESS( ntStatus))
3117             {
3118
3119                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3120                               AFS_TRACE_LEVEL_ERROR,
3121                               "AFSProcessOverwriteSupersede (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
3122                               Irp,
3123                               &DirectoryCB->NameInformation.FileName,
3124                               ntStatus);
3125
3126                 try_return( ntStatus);
3127             }
3128
3129             if ( ntStatus != STATUS_REPARSE)
3130             {
3131
3132                 bAllocatedFcb = TRUE;
3133             }
3134
3135             ntStatus = STATUS_SUCCESS;
3136         }
3137         else
3138         {
3139
3140             AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
3141                             TRUE);
3142         }
3143
3144         //
3145         // Increment the open count on this Fcb.
3146         //