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