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