Windows: More specific error values
[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_MEDIA_WRITE_PROTECTED);
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                  (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
1982         {
1983
1984             //
1985             // And the parent directory entry
1986             //
1987
1988             KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1989
1990             //
1991             // Notify the system of the addition
1992             //
1993
1994             AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1995                                             *Ccb,
1996                                             (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1997                                             (ULONG)FILE_ACTION_ADDED);
1998         }
1999
2000         //
2001         // Save off the access for the open
2002         //
2003
2004         IoSetShareAccess( *pDesiredAccess,
2005                           usShareAccess,
2006                           pFileObject,
2007                           &(*Fcb)->ShareAccess);
2008
2009         //
2010         // Increment the open count on this Fcb
2011         //
2012
2013         InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
2014
2015         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2016                       AFS_TRACE_LEVEL_VERBOSE,
2017                       "AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n",
2018                       *Fcb,
2019                       (*Fcb)->OpenReferenceCount);
2020
2021         InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2022
2023         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2024                       AFS_TRACE_LEVEL_VERBOSE,
2025                       "AFSProcessCreate Increment handle count on Fcb %08lX Cnt %d\n",
2026                       (*Fcb),
2027                       (*Fcb)->OpenHandleCount);
2028
2029         //
2030         // Increment the open reference and handle on the parent node
2031         //
2032
2033         InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2034
2035         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2036                       AFS_TRACE_LEVEL_VERBOSE,
2037                       "AFSProcessCreate Increment child open handle count on Parent object %08lX Cnt %d\n",
2038                       pObjectInfo->ParentObjectInformation,
2039                       pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2040
2041         InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2042
2043         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2044                       AFS_TRACE_LEVEL_VERBOSE,
2045                       "AFSProcessCreate Increment child open ref count on Parent object %08lX Cnt %d\n",
2046                       pObjectInfo->ParentObjectInformation,
2047                       pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2048
2049         if( ulOptions & FILE_DELETE_ON_CLOSE)
2050         {
2051
2052             //
2053             // Mark it for delete on close
2054             //
2055
2056             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2057                           AFS_TRACE_LEVEL_VERBOSE,
2058                           "AFSProcessCreate (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2059                           Irp,
2060                           pDirEntry,
2061                           FullFileName);
2062
2063             SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2064         }
2065
2066         //
2067         // Indicate the object is locked in the service
2068         //
2069
2070         SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2071
2072         //
2073         // Return the open result for this file
2074         //
2075
2076         Irp->IoStatus.Information = FILE_CREATED;
2077
2078 try_exit:
2079
2080         //
2081         // If we created the Fcb we need to release the resources
2082         //
2083
2084         if( bReleaseFcb)
2085         {
2086
2087             AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2088         }
2089
2090         if( !NT_SUCCESS( ntStatus))
2091         {
2092
2093             if( bFileCreated)
2094             {
2095
2096                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2097                               AFS_TRACE_LEVEL_VERBOSE,
2098                               "AFSProcessCreate Create failed, removing DE %p from aprent object %p Status %08lX\n",
2099                               pDirEntry,
2100                               pParentObjectInfo,
2101                               ntStatus);
2102
2103                 //
2104                 // Remove the dir entry from the parent
2105                 //
2106
2107                 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2108                                 TRUE);
2109
2110                 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2111
2112                 //
2113                 // Decrement the reference added during initialization of the DE
2114                 //
2115
2116                 InterlockedDecrement( &pDirEntry->OpenReferenceCount);
2117
2118                 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2119                               AFS_TRACE_LEVEL_VERBOSE,
2120                               "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2121                               &pDirEntry->NameInformation.FileName,
2122                               pDirEntry,
2123                               pDirEntry->OpenReferenceCount);
2124
2125                 //
2126                 // Pull the directory entry from the parent
2127                 //
2128
2129                 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2130                                             pDirEntry,
2131                                             FALSE); // Leave it in the enum list so the worker cleans it up
2132
2133                 AFSNotifyDelete( pDirEntry,
2134                                  AuthGroup,
2135                                  FALSE);
2136
2137                 //
2138                 // Tag the parent as needing verification
2139                 //
2140
2141                 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2142
2143                 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2144             }
2145
2146             if( bAllocatedCcb)
2147             {
2148
2149                 AFSRemoveCcb( NULL,
2150                               *Ccb);
2151             }
2152
2153             if( bAllocatedFcb)
2154             {
2155
2156                 AFSRemoveFcb( pObjectInfo->Fcb);
2157
2158                 pObjectInfo->Fcb = NULL;
2159             }
2160
2161             *Fcb = NULL;
2162
2163             *Ccb = NULL;
2164         }
2165     }
2166
2167     return ntStatus;
2168 }
2169
2170 NTSTATUS
2171 AFSOpenTargetDirectory( IN PIRP Irp,
2172                         IN AFSVolumeCB *VolumeCB,
2173                         IN AFSDirectoryCB *ParentDirectoryCB,
2174                         IN AFSDirectoryCB *TargetDirectoryCB,
2175                         IN UNICODE_STRING *TargetName,
2176                         OUT AFSFcb **Fcb,
2177                         OUT AFSCcb **Ccb)
2178 {
2179
2180     NTSTATUS ntStatus = STATUS_SUCCESS;
2181     PFILE_OBJECT pFileObject = NULL;
2182     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2183     PACCESS_MASK pDesiredAccess = NULL;
2184     USHORT usShareAccess;
2185     BOOLEAN bAllocatedCcb = FALSE;
2186     BOOLEAN bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2187     AFSObjectInfoCB *pParentObject = NULL, *pTargetObject = NULL;
2188     UNICODE_STRING uniTargetName;
2189
2190     __Enter
2191     {
2192
2193         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2194         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2195
2196         pFileObject = pIrpSp->FileObject;
2197
2198         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2199                       AFS_TRACE_LEVEL_VERBOSE,
2200                       "AFSOpenTargetDirectory (%08lX) Processing file %wZ\n",
2201                       Irp,
2202                       TargetName);
2203
2204         pParentObject = ParentDirectoryCB->ObjectInformation;
2205
2206         if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2207         {
2208
2209             try_return( ntStatus = STATUS_INVALID_PARAMETER);
2210         }
2211
2212         //
2213         // Make sure we have an Fcb for the access
2214         //
2215
2216         if( pParentObject->Fcb != NULL)
2217         {
2218
2219             *Fcb = pParentObject->Fcb;
2220
2221             AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
2222                             TRUE);
2223         }
2224         else
2225         {
2226
2227             //
2228             // Allocate and initialize the Fcb for the file.
2229             //
2230
2231             ntStatus = AFSInitFcb( ParentDirectoryCB,
2232                                    Fcb);
2233
2234             if( !NT_SUCCESS( ntStatus))
2235             {
2236
2237                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2238                               AFS_TRACE_LEVEL_ERROR,
2239                               "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
2240                               Irp,
2241                               &ParentDirectoryCB->NameInformation.FileName,
2242                               ntStatus);
2243
2244                 try_return( ntStatus);
2245             }
2246
2247             bAllocatedFcb = TRUE;
2248         }
2249
2250         bReleaseFcb = TRUE;
2251
2252         //
2253         // If there are current opens on the Fcb, check the access.
2254         //
2255
2256         if( pParentObject->Fcb->OpenHandleCount > 0)
2257         {
2258
2259             ntStatus = IoCheckShareAccess( *pDesiredAccess,
2260                                            usShareAccess,
2261                                            pFileObject,
2262                                            &pParentObject->Fcb->ShareAccess,
2263                                            FALSE);
2264
2265             if( !NT_SUCCESS( ntStatus))
2266             {
2267
2268                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2269                               AFS_TRACE_LEVEL_ERROR,
2270                               "AFSOpenTargetDirectory (%08lX) Access check failure %wZ Status %08lX\n",
2271                               Irp,
2272                               &ParentDirectoryCB->NameInformation.FileName,
2273                               ntStatus);
2274
2275                 try_return( ntStatus);
2276             }
2277         }
2278
2279         //
2280         // Initialize the Ccb for the file.
2281         //
2282
2283         ntStatus = AFSInitCcb( Ccb);
2284
2285         if( !NT_SUCCESS( ntStatus))
2286         {
2287
2288             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2289                           AFS_TRACE_LEVEL_ERROR,
2290                           "AFSOpenTargetDirectory (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2291                           Irp,
2292                           &ParentDirectoryCB->NameInformation.FileName,
2293                           ntStatus);
2294
2295             try_return( ntStatus);
2296         }
2297
2298         bAllocatedCcb = TRUE;
2299
2300         //
2301         // Initialize the Ccb
2302         //
2303
2304         (*Ccb)->DirectoryCB = ParentDirectoryCB;
2305
2306         (*Ccb)->GrantedAccess = *pDesiredAccess;
2307
2308         if( TargetDirectoryCB != NULL &&
2309             FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2310                                 TargetName,
2311                                 FALSE,
2312                                 NULL))
2313         {
2314
2315             Irp->IoStatus.Information = FILE_EXISTS;
2316
2317             uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2318         }
2319         else
2320         {
2321
2322             Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2323
2324             uniTargetName = *TargetName;
2325         }
2326
2327         //
2328         // Update the filename in the fileobject for rename processing
2329         //
2330
2331         RtlCopyMemory( pFileObject->FileName.Buffer,
2332                        uniTargetName.Buffer,
2333                        uniTargetName.Length);
2334
2335         pFileObject->FileName.Length = uniTargetName.Length;
2336
2337         //
2338         // OK, update the share access on the fileobject
2339         //
2340
2341         if( pParentObject->Fcb->OpenHandleCount > 0)
2342         {
2343
2344             IoUpdateShareAccess( pFileObject,
2345                                  &pParentObject->Fcb->ShareAccess);
2346         }
2347         else
2348         {
2349
2350             //
2351             // Set the access
2352             //
2353
2354             IoSetShareAccess( *pDesiredAccess,
2355                               usShareAccess,
2356                               pFileObject,
2357                               &pParentObject->Fcb->ShareAccess);
2358         }
2359
2360         //
2361         // Increment the open count on this Fcb
2362         //
2363
2364         InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2365
2366         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2367                       AFS_TRACE_LEVEL_VERBOSE,
2368                       "AFSOpenTargetDirectory Increment count on Fcb %08lX Cnt %d\n",
2369                       pParentObject->Fcb,
2370                       pParentObject->Fcb->OpenReferenceCount);
2371
2372         InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2373
2374         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2375                       AFS_TRACE_LEVEL_VERBOSE,
2376                       "AFSOpenTargetDirectory Increment handle count on Fcb %08lX Cnt %d\n",
2377                       pParentObject->Fcb,
2378                       pParentObject->Fcb->OpenHandleCount);
2379
2380         //
2381         // Increment the open reference and handle on the parent node
2382         //
2383
2384         if( pParentObject->ParentObjectInformation != NULL)
2385         {
2386
2387             InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2388
2389             AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2390                           AFS_TRACE_LEVEL_VERBOSE,
2391                           "AFSOpenTargetDirectory Increment child open handle count on Parent object %08lX Cnt %d\n",
2392                           pParentObject->ParentObjectInformation,
2393                           pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2394
2395             InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2396
2397             AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2398                           AFS_TRACE_LEVEL_VERBOSE,
2399                           "AFSOpenTargetDirectory Increment child open ref count on Parent object %08lX Cnt %d\n",
2400                           pParentObject->ParentObjectInformation,
2401                           pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2402         }
2403
2404 try_exit:
2405
2406         if( bReleaseFcb)
2407         {
2408
2409             AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2410         }
2411
2412         if( !NT_SUCCESS( ntStatus))
2413         {
2414
2415             if( bAllocatedCcb)
2416             {
2417
2418                 AFSRemoveCcb( NULL,
2419                               *Ccb);
2420             }
2421
2422             *Ccb = NULL;
2423
2424             if( bAllocatedFcb)
2425             {
2426
2427                 AFSRemoveFcb( pParentObject->Fcb);
2428
2429                 pParentObject->Fcb = NULL;
2430             }
2431
2432             *Fcb = NULL;
2433         }
2434     }
2435
2436     return ntStatus;
2437 }
2438
2439 NTSTATUS
2440 AFSProcessOpen( IN PIRP Irp,
2441                 IN GUID *AuthGroup,
2442                 IN AFSVolumeCB *VolumeCB,
2443                 IN AFSDirectoryCB *ParentDirCB,
2444                 IN AFSDirectoryCB *DirectoryCB,
2445                 OUT AFSFcb **Fcb,
2446                 OUT AFSCcb **Ccb)
2447 {
2448
2449     NTSTATUS ntStatus = STATUS_SUCCESS;
2450     PFILE_OBJECT pFileObject = NULL;
2451     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2452     PACCESS_MASK pDesiredAccess = NULL;
2453     USHORT usShareAccess;
2454     BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2455     ULONG ulAdditionalFlags = 0, ulOptions = 0;
2456     AFSFileOpenCB   stOpenCB;
2457     AFSFileOpenResultCB stOpenResultCB;
2458     ULONG       ulResultLen = 0;
2459     AFSObjectInfoCB *pParentObjectInfo = NULL;
2460     AFSObjectInfoCB *pObjectInfo = NULL;
2461     ULONG       ulFileAccess = 0;
2462     AFSFileAccessReleaseCB stReleaseFileAccess;
2463
2464     __Enter
2465     {
2466
2467         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2468         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2469
2470         pFileObject = pIrpSp->FileObject;
2471
2472         pParentObjectInfo = ParentDirCB->ObjectInformation;
2473
2474         pObjectInfo = DirectoryCB->ObjectInformation;
2475
2476         //
2477         // Check if the entry is pending a deletion
2478         //
2479
2480         if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2481         {
2482
2483             ntStatus = STATUS_DELETE_PENDING;
2484
2485             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2486                           AFS_TRACE_LEVEL_ERROR,
2487                           "AFSProcessOpen (%08lX) Entry pending delete %wZ Status %08lX\n",
2488                           Irp,
2489                           &DirectoryCB->NameInformation.FileName,
2490                           ntStatus);
2491
2492             try_return( ntStatus);
2493         }
2494
2495         //
2496         // Extract out the options
2497         //
2498
2499         ulOptions = pIrpSp->Parameters.Create.Options;
2500
2501         //
2502         // Check if we should go and retrieve updated information for the node
2503         //
2504
2505         ntStatus = AFSValidateEntry( DirectoryCB,
2506                                      AuthGroup,
2507                                      TRUE,
2508                                      FALSE);
2509
2510         if( !NT_SUCCESS( ntStatus))
2511         {
2512
2513             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2514                           AFS_TRACE_LEVEL_ERROR,
2515                           "AFSProcessOpen (%08lX) Failed to validate entry %wZ Status %08lX\n",
2516                           Irp,
2517                           &DirectoryCB->NameInformation.FileName,
2518                           ntStatus);
2519
2520             try_return( ntStatus);
2521         }
2522
2523         //
2524         // If this is marked for delete on close then be sure we can delete the entry
2525         //
2526
2527         if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2528         {
2529
2530             ntStatus = AFSNotifyDelete( DirectoryCB,
2531                                         AuthGroup,
2532                                         TRUE);
2533
2534             if( !NT_SUCCESS( ntStatus))
2535             {
2536
2537                 ntStatus = STATUS_CANNOT_DELETE;
2538
2539                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2540                               AFS_TRACE_LEVEL_ERROR,
2541                               "AFSProcessOpen (%08lX) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2542                               Irp,
2543                               &DirectoryCB->NameInformation.FileName,
2544                               ntStatus);
2545
2546                 try_return( ntStatus);
2547             }
2548         }
2549
2550         //
2551         // Be sure we have an Fcb for the current object
2552         //
2553
2554         if( pObjectInfo->Fcb == NULL)
2555         {
2556
2557             ntStatus = AFSInitFcb( DirectoryCB,
2558                                    &pObjectInfo->Fcb);
2559
2560             if( !NT_SUCCESS( ntStatus))
2561             {
2562
2563                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2564                               AFS_TRACE_LEVEL_ERROR,
2565                               "AFSProcessOpen (%08lX) Failed to init fcb on %wZ Status %08lX\n",
2566                               Irp,
2567                               &DirectoryCB->NameInformation.FileName,
2568                               ntStatus);
2569
2570                 try_return( ntStatus);
2571             }
2572
2573             bAllocatedFcb = TRUE;
2574         }
2575         else
2576         {
2577
2578             AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
2579                             TRUE);
2580         }
2581
2582         bReleaseFcb = TRUE;
2583
2584         //
2585         // Reference the Fcb so it won't go away while we call into the service for processing
2586         //
2587
2588         InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2589
2590         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2591                       AFS_TRACE_LEVEL_VERBOSE,
2592                       "AFSProcessOpen Increment count on Fcb %08lX Cnt %d\n",
2593                       pObjectInfo->Fcb,
2594                       pObjectInfo->Fcb->OpenReferenceCount);
2595
2596         //
2597         // Check access on the entry
2598         //
2599
2600         if( pObjectInfo->Fcb->OpenHandleCount > 0)
2601         {
2602
2603             ntStatus = IoCheckShareAccess( *pDesiredAccess,
2604                                            usShareAccess,
2605                                            pFileObject,
2606                                            &pObjectInfo->Fcb->ShareAccess,
2607                                            FALSE);
2608
2609             if( !NT_SUCCESS( ntStatus))
2610             {
2611
2612                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2613                               AFS_TRACE_LEVEL_ERROR,
2614                               "AFSProcessOpen (%08lX) Failed to check share access on %wZ Status %08lX\n",
2615                               Irp,
2616                               &DirectoryCB->NameInformation.FileName,
2617                               ntStatus);
2618
2619                 try_return( ntStatus);
2620             }
2621         }
2622
2623         //
2624         // Additional checks
2625         //
2626
2627         if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2628         {
2629
2630             //
2631             // If the caller is asking for write access then try to flush the image section
2632             //
2633
2634             if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2635                 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2636             {
2637
2638                 if( !MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2639                                           MmFlushForWrite))
2640                 {
2641
2642                     ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2643                                                                             STATUS_SHARING_VIOLATION;
2644
2645                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2646                                   AFS_TRACE_LEVEL_ERROR,
2647                                   "AFSProcessOpen (%08lX) Failed to flush image section %wZ Status %08lX\n",
2648                                   Irp,
2649                                   &DirectoryCB->NameInformation.FileName,
2650                                   ntStatus);
2651
2652                     try_return( ntStatus);
2653                 }
2654             }
2655
2656             if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2657             {
2658
2659                 ntStatus = STATUS_NOT_A_DIRECTORY;
2660
2661                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2662                               AFS_TRACE_LEVEL_ERROR,
2663                               "AFSProcessOpen (%08lX) Attempt to open file as directory %wZ Status %08lX\n",
2664                               Irp,
2665                               &DirectoryCB->NameInformation.FileName,
2666                               ntStatus);
2667
2668                 try_return( ntStatus);
2669             }
2670
2671             pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2672         }
2673         else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2674                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2675         {
2676
2677             if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2678             {
2679
2680                 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2681
2682                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2683                               AFS_TRACE_LEVEL_ERROR,
2684                               "AFSProcessOpen (%08lX) Attempt to open directory as file %wZ Status %08lX\n",
2685                               Irp,
2686                               &DirectoryCB->NameInformation.FileName,
2687                               ntStatus);
2688
2689                 try_return( ntStatus);
2690             }
2691         }
2692         else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2693                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2694                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2695                  pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2696         {
2697
2698         }
2699         else
2700         {
2701             ASSERT( FALSE);
2702             try_return( ntStatus = STATUS_UNSUCCESSFUL);
2703         }
2704
2705         //
2706         // Check with the service that we can open the file
2707         //
2708
2709         stOpenCB.ParentId = pParentObjectInfo->FileId;
2710
2711         stOpenCB.DesiredAccess = *pDesiredAccess;
2712
2713         stOpenCB.ShareAccess = usShareAccess;
2714
2715         stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2716
2717         stOpenCB.Identifier = (ULONGLONG)pFileObject;
2718
2719         stOpenResultCB.GrantedAccess = 0;
2720
2721         ulResultLen = sizeof( AFSFileOpenResultCB);
2722
2723         ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2724                                       AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2725                                       AuthGroup,
2726                                       &DirectoryCB->NameInformation.FileName,
2727                                       &pObjectInfo->FileId,
2728                                       (void *)&stOpenCB,
2729                                       sizeof( AFSFileOpenCB),
2730                                       (void *)&stOpenResultCB,
2731                                       &ulResultLen);
2732
2733         if( !NT_SUCCESS( ntStatus))
2734         {
2735
2736             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2737                           AFS_TRACE_LEVEL_ERROR,
2738                           "AFSProcessOpen (%08lX) Failed open in service %wZ Status %08lX\n",
2739                           Irp,
2740                           &DirectoryCB->NameInformation.FileName,
2741                           ntStatus);
2742
2743             try_return( ntStatus);
2744         }
2745
2746         //
2747         // Save the granted access in case we need to release it below
2748         //
2749
2750         ulFileAccess = stOpenResultCB.FileAccess;
2751
2752         //
2753         // Check if there is a conflict
2754         //
2755
2756         if( !AFSCheckAccess( *pDesiredAccess,
2757                              stOpenResultCB.GrantedAccess,
2758                              BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2759         {
2760
2761             ntStatus = STATUS_ACCESS_DENIED;
2762
2763             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2764                           AFS_TRACE_LEVEL_ERROR,
2765                           "AFSProcessOpen (%08lX) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2766                           Irp,
2767                           *pDesiredAccess,
2768                           stOpenResultCB.GrantedAccess,
2769                           &DirectoryCB->NameInformation.FileName,
2770                           ntStatus);
2771
2772             try_return( ntStatus);
2773         }
2774
2775         //
2776         // Initialize the Ccb for the file.
2777         //
2778
2779         ntStatus = AFSInitCcb( Ccb);
2780
2781         if( !NT_SUCCESS( ntStatus))
2782         {
2783
2784             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2785                           AFS_TRACE_LEVEL_ERROR,
2786                           "AFSProcessOpen (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2787                           Irp,
2788                           &DirectoryCB->NameInformation.FileName,
2789                           ntStatus);
2790
2791             try_return( ntStatus);
2792         }
2793
2794         bAllocatedCcb = TRUE;
2795
2796         (*Ccb)->DirectoryCB = DirectoryCB;
2797
2798         (*Ccb)->FileAccess = ulFileAccess;
2799
2800         (*Ccb)->GrantedAccess = *pDesiredAccess;
2801
2802         //
2803         // Perform the access check on the target if this is a mount point or symlink
2804         //
2805
2806         if( pObjectInfo->Fcb->OpenHandleCount > 0)
2807         {
2808
2809             IoUpdateShareAccess( pFileObject,
2810                                  &pObjectInfo->Fcb->ShareAccess);
2811         }
2812         else
2813         {
2814
2815             //
2816             // Set the access
2817             //
2818
2819             IoSetShareAccess( *pDesiredAccess,
2820                               usShareAccess,
2821                               pFileObject,
2822                               &pObjectInfo->Fcb->ShareAccess);
2823         }
2824
2825         //
2826         // Increment the open count on this Fcb
2827         //
2828
2829         InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2830
2831         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2832                       AFS_TRACE_LEVEL_VERBOSE,
2833                       "AFSProcessOpen Increment2 count on Fcb %08lX Cnt %d\n",
2834                       pObjectInfo->Fcb,
2835                       pObjectInfo->Fcb->OpenReferenceCount);
2836
2837         InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2838
2839         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2840                       AFS_TRACE_LEVEL_VERBOSE,
2841                       "AFSProcessOpen Increment handle count on Fcb %08lX Cnt %d\n",
2842                       pObjectInfo->Fcb,
2843                       pObjectInfo->Fcb->OpenHandleCount);
2844
2845         //
2846         // Increment the open reference and handle on the parent node
2847         //
2848
2849         InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2850
2851         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2852                       AFS_TRACE_LEVEL_VERBOSE,
2853                       "AFSProcessOpen Increment child open handle count on Parent object %08lX Cnt %d\n",
2854                       pObjectInfo->ParentObjectInformation,
2855                       pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2856
2857         InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2858
2859         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2860                       AFS_TRACE_LEVEL_VERBOSE,
2861                       "AFSProcessOpen Increment child open ref count on Parent object %08lX Cnt %d\n",
2862                       pObjectInfo->ParentObjectInformation,
2863                       pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2864
2865         if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2866         {
2867
2868             //
2869             // Mark it for delete on close
2870             //
2871
2872             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2873                           AFS_TRACE_LEVEL_VERBOSE,
2874                           "AFSProcessOpen (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2875                           Irp,
2876                           DirectoryCB,
2877                           &DirectoryCB->NameInformation.FileName);
2878
2879             SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2880         }
2881
2882         //
2883         // Indicate the object is held
2884         //
2885
2886         SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2887
2888         //
2889         // Return the open result for this file
2890         //
2891
2892         Irp->IoStatus.Information = FILE_OPENED;
2893
2894         *Fcb = pObjectInfo->Fcb;
2895
2896 try_exit:
2897
2898         if( bReleaseFcb)
2899         {
2900
2901             //
2902             // Remove the reference we added initially
2903             //
2904
2905             InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2906
2907             AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2908                           AFS_TRACE_LEVEL_VERBOSE,
2909                           "AFSProcessOpen Decrement count on Fcb %08lX Cnt %d\n",
2910                           pObjectInfo->Fcb,
2911                           pObjectInfo->Fcb->OpenReferenceCount);
2912
2913             AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2914         }
2915
2916         if( !NT_SUCCESS( ntStatus))
2917         {
2918
2919             if ( ulFileAccess > 0)
2920             {
2921
2922                 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2923
2924                 stReleaseFileAccess.FileAccess = ulFileAccess;
2925
2926                 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2927
2928                 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2929                                    AFS_REQUEST_FLAG_SYNCHRONOUS,
2930                                    AuthGroup,
2931                                    &DirectoryCB->NameInformation.FileName,
2932                                    &pObjectInfo->FileId,
2933                                    (void *)&stReleaseFileAccess,
2934                                    sizeof( AFSFileAccessReleaseCB),
2935                                    NULL,
2936                                    NULL);
2937             }
2938
2939             if( bAllocatedCcb)
2940             {
2941
2942                 AFSRemoveCcb( NULL,
2943                               *Ccb);
2944             }
2945
2946             *Ccb = NULL;
2947
2948             if( bAllocatedFcb)
2949             {
2950
2951                 AFSRemoveFcb( pObjectInfo->Fcb);
2952
2953                 pObjectInfo->Fcb = NULL;
2954             }
2955
2956             *Fcb = NULL;
2957         }
2958     }
2959
2960     return ntStatus;
2961 }
2962
2963 NTSTATUS
2964 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
2965                               IN PIRP           Irp,
2966                               IN AFSVolumeCB   *VolumeCB,
2967                               IN GUID          *AuthGroup,
2968                               IN AFSDirectoryCB *ParentDirCB,
2969                               IN AFSDirectoryCB *DirectoryCB,
2970                               OUT AFSFcb       **Fcb,
2971                               OUT AFSCcb       **Ccb)
2972 {
2973
2974     NTSTATUS ntStatus = STATUS_SUCCESS;
2975     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2976     PFILE_OBJECT pFileObject = NULL;
2977     LARGE_INTEGER liZero = {0,0};
2978     BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
2979     ULONG   ulAttributes = 0;
2980     LARGE_INTEGER liTime;
2981     ULONG ulCreateDisposition = 0;
2982     BOOLEAN bAllocatedCcb = FALSE, bAllocatedFcb = FALSE;
2983     PACCESS_MASK pDesiredAccess = NULL;
2984     USHORT usShareAccess;
2985     AFSObjectInfoCB *pParentObjectInfo = NULL;
2986     AFSObjectInfoCB *pObjectInfo = NULL;
2987
2988     __Enter
2989     {
2990
2991         pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2992         usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2993
2994         pFileObject = pIrpSp->FileObject;
2995
2996         ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
2997
2998         ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
2999
3000         if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
3001         {
3002
3003             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3004                           AFS_TRACE_LEVEL_ERROR,
3005                           "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3006                           Irp,
3007                           &DirectoryCB->NameInformation.FileName);
3008
3009             try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3010         }
3011
3012         pParentObjectInfo = ParentDirCB->ObjectInformation;
3013
3014         pObjectInfo = DirectoryCB->ObjectInformation;
3015
3016         //
3017         // Check if we should go and retrieve updated information for the node
3018         //
3019
3020         ntStatus = AFSValidateEntry( DirectoryCB,
3021                                      AuthGroup,
3022                                      TRUE,
3023                                      FALSE);
3024
3025         if( !NT_SUCCESS( ntStatus))
3026         {
3027
3028             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3029                           AFS_TRACE_LEVEL_ERROR,
3030                           "AFSProcessOverwriteSupersede (%08lX) Failed to validate entry %wZ Status %08lX\n",
3031                           Irp,
3032                           &DirectoryCB->NameInformation.FileName,
3033                           ntStatus);
3034
3035             try_return( ntStatus);
3036         }
3037
3038         //
3039         // Be sure we have an Fcb for the object block
3040         //
3041
3042         if( pObjectInfo->Fcb == NULL)
3043         {
3044
3045             ntStatus = AFSInitFcb( DirectoryCB,
3046                                    Fcb);
3047
3048             if( !NT_SUCCESS( ntStatus))
3049             {
3050
3051                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3052                               AFS_TRACE_LEVEL_ERROR,
3053                               "AFSProcessOverwriteSupersede (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
3054                               Irp,
3055                               &DirectoryCB->NameInformation.FileName,
3056                               ntStatus);
3057
3058                 try_return( ntStatus);
3059             }
3060
3061             bAllocatedFcb = TRUE;
3062         }
3063         else
3064         {
3065
3066             AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
3067                             TRUE);
3068         }
3069
3070         bReleaseFcb = TRUE;
3071
3072         //
3073         // Reference the Fcb so it won't go away while processing the request
3074         //
3075
3076         InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3077
3078         AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3079                       AFS_TRACE_LEVEL_VERBOSE,
3080                       "AFSProcessOverwriteSupersede Increment count on Fcb %08lX Cnt %d\n",
3081                       pObjectInfo->Fcb,
3082                       pObjectInfo->Fcb->OpenReferenceCount);
3083
3084         //
3085         // Check access on the entry
3086         //
3087
3088         if( pObjectInfo->Fcb->OpenHandleCount > 0)
3089         {
3090
3091             ntStatus = IoCheckShareAccess( *pDesiredAccess,
3092                                            usShareAccess,
3093                                            pFileObject,
3094                                            &pObjectInfo->Fcb->ShareAccess,
3095                                            FALSE);
3096
3097             if( !NT_SUCCESS( ntStatus))
3098             {
3099
3100                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3101                               AFS_TRACE_LEVEL_ERROR,
3102                               "AFSProcessOverwriteSupersede (%08lX) Access check failure %wZ Status %08lX\n",
3103                               Irp,
3104                               &DirectoryCB->NameInformation.FileName,
3105                               ntStatus);
3106
3107                 try_return( ntStatus);
3108             }
3109         }
3110
3111         //
3112         //  Before we actually truncate, check to see if the purge
3113         //  is going to fail.
3114         //
3115
3116         if( !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3117                                    &liZero))
3118         {
3119
3120             ntStatus = STATUS_USER_MAPPED_FILE;
3121
3122             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3123                           AFS_TRACE_LEVEL_ERROR,
3124                           "AFSProcessOverwriteSupersede (%08lX) File user mapped %wZ Status %08lX\n",
3125                           Irp,
3126                           &DirectoryCB->NameInformation.FileName,
3127                           ntStatus);
3128
3129             try_return( ntStatus);
3130         }
3131
3132         //
3133         // Initialize the Ccb for the file.
3134         //
3135
3136         ntStatus = AFSInitCcb( Ccb);
3137
3138         if( !NT_SUCCESS( ntStatus))
3139         {
3140
3141             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3142                           AFS_TRACE_LEVEL_ERROR,
3143                           "AFSProcessOverwriteSupersede (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
3144                           Irp,
3145                           &DirectoryCB->NameInformation.FileName,
3146                           ntStatus);
3147
3148             try_return( ntStatus);
3149         }
3150
3151         bAllocatedCcb = TRUE;
3152
3153         //
3154         // Initialize the Ccb
3155         //
3156
3157         (*Ccb)->DirectoryCB = DirectoryCB;
3158
3159         (*Ccb)->GrantedAccess = *pDesiredAccess;
3160
3161         //
3162         // Need to purge any data currently in the cache
3163         //
3164
3165         CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3166                              NULL,
3167                              0,
3168                              FALSE);
3169
3170         pObject