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