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