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