2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
14 * this list of conditions and the following disclaimer in the
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.
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.
36 // File: AFSCreate.cpp
39 #include "AFSCommon.h"
42 // Function: AFSCreate
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.
51 // A status is returned for the function. The Irp completion processing is handled in the specific
56 AFSCreate( IN PDEVICE_OBJECT LibDeviceObject,
59 UNREFERENCED_PARAMETER(LibDeviceObject);
60 NTSTATUS ntStatus = STATUS_SUCCESS;
61 IO_STACK_LOCATION *pIrpSp;
62 FILE_OBJECT *pFileObject = NULL;
67 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
68 pFileObject = pIrpSp->FileObject;
70 if( pFileObject == NULL ||
71 pFileObject->FileName.Buffer == NULL)
74 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
75 AFS_TRACE_LEVEL_VERBOSE,
76 "AFSCreate (%p) Processing control device open request\n",
79 ntStatus = AFSControlDeviceCreate( Irp);
81 try_return( ntStatus);
84 if( AFSRDRDeviceObject == NULL)
87 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
88 AFS_TRACE_LEVEL_VERBOSE,
89 "AFSCreate (%p) Invalid request to open before library is initialized\n",
92 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
95 ntStatus = AFSCommonCreate( AFSRDRDeviceObject,
102 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
107 "EXCEPTION - AFSCreate\n"));
109 ntStatus = STATUS_ACCESS_DENIED;
111 AFSDumpTraceFilesFnc();
115 // Complete the request
118 AFSCompleteRequest( Irp,
125 AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
129 NTSTATUS ntStatus = STATUS_SUCCESS;
130 UNICODE_STRING uniFileName;
131 ULONG ulCreateDisposition = 0;
133 BOOLEAN bNoIntermediateBuffering = FALSE;
134 FILE_OBJECT *pFileObject = NULL;
135 IO_STACK_LOCATION *pIrpSp;
138 AFSDeviceExt *pDeviceExt = NULL;
139 BOOLEAN bOpenTargetDirectory = FALSE, bReleaseVolume = FALSE;
140 PACCESS_MASK pDesiredAccess = NULL;
141 UNICODE_STRING uniComponentName, uniRootFileName, uniParsedFileName;
142 UNICODE_STRING uniSubstitutedPathName;
143 UNICODE_STRING uniRelativeName;
144 AFSNameArrayHdr *pNameArray = NULL;
145 AFSVolumeCB *pVolumeCB = NULL;
146 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
147 AFSVolumeCB *pNewVolumeCB = NULL;
148 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
149 AFSDirectoryCB *pParentDirectoryCB = NULL, *pDirectoryCB = NULL;
150 AFSDirectoryCB *pNewParentDirectoryCB = NULL;
151 BOOLEAN bReleaseParentDir = FALSE, bReleaseDir = FALSE;
152 ULONG ulParseFlags = 0;
153 GUID stAuthGroup = {0};
154 ULONG ulNameProcessingFlags = 0;
155 BOOLEAN bOpenedReparsePoint = FALSE;
161 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
162 pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
163 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
164 ulOptions = pIrpSp->Parameters.Create.Options;
165 bNoIntermediateBuffering = BooleanFlagOn( ulOptions, FILE_NO_INTERMEDIATE_BUFFERING);
166 bOpenTargetDirectory = BooleanFlagOn( pIrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
167 pFileObject = pIrpSp->FileObject;
168 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
170 uniFileName.Length = uniFileName.MaximumLength = 0;
171 uniFileName.Buffer = NULL;
173 uniRootFileName.Length = uniRootFileName.MaximumLength = 0;
174 uniRootFileName.Buffer = NULL;
176 uniParsedFileName.Length = uniParsedFileName.MaximumLength = 0;
177 uniParsedFileName.Buffer = NULL;
179 uniSubstitutedPathName.Buffer = NULL;
180 uniSubstitutedPathName.Length = 0;
182 uniRelativeName.Buffer = NULL;
183 uniRelativeName.Length = 0;
185 if( AFSGlobalRoot == NULL)
187 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
190 RtlZeroMemory( &stAuthGroup,
193 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
194 (ULONGLONG)PsGetCurrentThreadId(),
198 // If we are in shutdown mode then fail the request
201 if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
204 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
205 AFS_TRACE_LEVEL_WARNING,
206 "AFSCommonCreate (%p) Open request after shutdown\n",
209 try_return( ntStatus = STATUS_TOO_LATE);
212 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
215 ntStatus = AFSEnumerateGlobalRoot( &stAuthGroup);
217 if( !NT_SUCCESS( ntStatus))
220 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
221 AFS_TRACE_LEVEL_ERROR,
222 "AFSCommonCreate Failed to enumerate global root Status %08lX\n",
225 try_return( ntStatus);
230 // Go and parse the name for processing.
231 // If ulParseFlags is returned with AFS_PARSE_FLAG_FREE_FILE_BUFFER set,
232 // then we are responsible for releasing the uniRootFileName.Buffer.
235 ntStatus = AFSParseName( Irp,
245 if( !NT_SUCCESS( ntStatus))
248 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
249 uniFileName.Length > 0 ? AFS_TRACE_LEVEL_ERROR : AFS_TRACE_LEVEL_VERBOSE,
250 "AFSCommonCreate (%p) Failed to parse name \"%wZ\" Status %08lX\n",
255 try_return( ntStatus);
259 // Check for STATUS_REPARSE
262 if( ntStatus == STATUS_REPARSE)
266 // Update the information and return
269 Irp->IoStatus.Information = IO_REPARSE;
271 try_return( ntStatus);
274 if ( pParentDirectoryCB != NULL)
277 bReleaseParentDir = TRUE;
281 // If the returned volume cb is NULL then we are dealing with the \\Server\GlobalRoot
285 if( pVolumeCB == NULL)
289 // Remove any leading or trailing slashes
292 if( uniFileName.Length >= sizeof( WCHAR) &&
293 uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
296 uniFileName.Length -= sizeof( WCHAR);
299 if( uniFileName.Length >= sizeof( WCHAR) &&
300 uniFileName.Buffer[ 0] == L'\\')
303 uniFileName.Buffer = &uniFileName.Buffer[ 1];
305 uniFileName.Length -= sizeof( WCHAR);
309 // If there is a remaining portion returned for this request then
310 // check if it is for the PIOCtl interface
313 if( uniFileName.Length > 0)
317 // We don't accept any other opens off of the AFS Root
320 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
323 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
326 if( RtlCompareUnicodeString( &AFSPIOCtlName,
332 // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
333 // AFSGlobalRoot->DirectoryCB.
336 ntStatus = AFSOpenIOCtlFcb( Irp,
338 AFSGlobalRoot->DirectoryCB,
342 if( !NT_SUCCESS( ntStatus))
345 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
346 AFS_TRACE_LEVEL_ERROR,
347 "AFSCommonCreate Failed to open root IOCtl Fcb Status %08lX\n",
351 else if( pParentDirectoryCB != NULL)
354 if( pParentDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
357 ntStatus = AFSOpenSpecialShareFcb( Irp,
363 if( !NT_SUCCESS( ntStatus))
366 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
367 AFS_TRACE_LEVEL_ERROR,
368 "AFSCommonCreate Failed to open special share Fcb Status %08lX\n",
374 try_return( ntStatus);
377 ntStatus = AFSOpenAFSRoot( Irp,
381 if( !NT_SUCCESS( ntStatus))
384 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
385 AFS_TRACE_LEVEL_ERROR,
386 "AFSCommonCreate Failed to open root Status %08lX\n",
390 try_return( ntStatus);
394 // We have a reference on the root volume
397 VolumeReferenceReason = AFS_VOLUME_REFERENCE_PARSE_NAME;
399 bReleaseVolume = TRUE;
402 // Attempt to locate the node in the name tree if this is not a target
403 // open and the target is not the root
406 uniComponentName.Length = 0;
407 uniComponentName.Buffer = NULL;
409 if( uniFileName.Length > sizeof( WCHAR) ||
410 uniFileName.Buffer[ 0] != L'\\')
413 if( !AFSValidNameFormat( &uniFileName))
416 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
418 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
419 AFS_TRACE_LEVEL_VERBOSE,
420 "AFSCommonCreate (%p) Invalid name %wZ Status %08lX\n",
425 try_return( ntStatus);
429 if ( !AFSIgnoreReparsePointToFile() ||
430 !BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
433 // If there is no ReparsePointPolicy then the FILE_OPEN_REPARSE_POINT
434 // flag is applied if it is set.
436 // If the FILE_OPEN_REPARSE_POINT flag is not set, then there is
437 // no extra work to be done in any case. Use a single pass evaluation.
440 ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
443 // Opening a reparse point directly?
446 if( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
448 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
449 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
450 AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
453 uniSubstitutedPathName = uniRootFileName;
455 ntStatus = AFSLocateNameEntry( &stAuthGroup,
460 ulNameProcessingFlags,
464 &NewVolumeReferenceReason,
465 &pNewParentDirectoryCB,
469 if ( pNewVolumeCB != NULL)
473 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
474 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
475 // the reference on pVolumeCB that was held prior to the call.
476 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
477 // will be released second.
480 lCount = AFSVolumeDecrement( pVolumeCB,
481 VolumeReferenceReason);
483 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
484 AFS_TRACE_LEVEL_VERBOSE,
485 "AFSCommonCreate Decrement count on volume %p Reason %u Cnt %d\n",
487 VolumeReferenceReason,
490 pVolumeCB = pNewVolumeCB;
494 VolumeReferenceReason = NewVolumeReferenceReason;
496 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
498 bReleaseVolume = (pVolumeCB != NULL);
502 // AFSLocateNameEntry does not alter the reference count of
503 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
507 if ( bReleaseParentDir)
510 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
512 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
513 AFS_TRACE_LEVEL_VERBOSE,
514 "AFSCommonCreate DecrementX count on %wZ DE %p Ccb %p Cnt %d\n",
515 &pParentDirectoryCB->NameInformation.FileName,
521 pParentDirectoryCB = pNewParentDirectoryCB;
523 pNewParentDirectoryCB = NULL;
525 bReleaseParentDir = (pParentDirectoryCB != NULL);
533 if( !NT_SUCCESS( ntStatus) &&
534 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
537 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
539 uniSubstitutedPathName.Buffer = NULL;
543 // AFSLocateNameEntry released the Parent while walking the
547 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
548 AFS_TRACE_LEVEL_VERBOSE,
549 "AFSCommonCreate (%p) Failed to locate name entry for %wZ Status %08lX\n",
554 try_return( ntStatus);
558 // Check for STATUS_REPARSE
561 if( ntStatus == STATUS_REPARSE)
564 uniSubstitutedPathName.Buffer = NULL;
567 // Update the information and return
570 Irp->IoStatus.Information = IO_REPARSE;
572 try_return( ntStatus);
576 // If we re-allocated the name, then update our substitute name
579 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
582 uniSubstitutedPathName = uniRootFileName;
587 uniSubstitutedPathName.Buffer = NULL;
591 // Check for a symlink access
594 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
595 pParentDirectoryCB != NULL)
599 // pParentDirectoryCB DirOpenReferenceCount is still held
602 UNICODE_STRING uniFinalComponent;
604 uniFinalComponent.Length = 0;
605 uniFinalComponent.MaximumLength = 0;
606 uniFinalComponent.Buffer = NULL;
608 AFSRetrieveFinalComponent( &uniFileName,
611 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
614 if( !NT_SUCCESS( ntStatus) &&
615 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
618 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
619 AFS_TRACE_LEVEL_VERBOSE,
620 "AFSCommonCreate (%p) Failing access to symlink %wZ Status %08lX\n",
625 try_return( ntStatus);
631 AFSNameArrayHdr *pNameArrayClone = NULL;
634 // The FILE_OPEN_REPARSE_POINT flag has been specified and a ReparsePointPolicy
635 // is in effect which conditionally applies depending on the type of the target
636 // object. Therefore, two lookup passes must be performed.
637 // 1. Evaluate the path as if the FILE_OPEN_REPARSE_POINT flag had
638 // not been specified.
639 // 2. If the target object type matches the policy, use it and ignore
640 // the FILE_OPEN_REPARSE_POINT flag.
641 // 3. If the target object type does not match the policy, perform
642 // a second pass that opens the reparse point.
643 // 4. If the target object cannot be evaluated, perform the second pass
644 // that opens the reparse point.
647 ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
649 uniSubstitutedPathName = uniRootFileName;
652 // Since we may need to replay the call with different options
653 // the values that might be altered need to be cloned:
654 // 1. uniRootFileName
658 pNameArrayClone = AFSInitNameArray( NULL, 0);
660 if ( pNameArrayClone == NULL)
663 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
664 AFS_TRACE_LEVEL_VERBOSE,
665 "AFSCommonCreate (%p) Failed to initialize name array clone\n",
668 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
671 ntStatus = AFSPopulateNameArrayFromRelatedArray( pNameArrayClone,
675 if ( !NT_SUCCESS(ntStatus))
678 AFSFreeNameArray( pNameArrayClone);
680 try_return( ntStatus);
684 // Now that the data is saved perform the lookup to determine
685 // what the target resolves to.
688 ntStatus = AFSLocateNameEntry( &stAuthGroup,
693 ulNameProcessingFlags,
697 &NewVolumeReferenceReason,
698 &pNewParentDirectoryCB,
702 if ( ntStatus == STATUS_SUCCESS ||
703 ntStatus == STATUS_REPARSE ||
704 ntStatus == STATUS_OBJECT_NAME_NOT_FOUND ||
705 ntStatus == STATUS_ACCESS_DENIED)
708 // Decide what to do based upon the ReparsePointPolicy
709 // and the type of the target object.
712 if ( ntStatus == STATUS_SUCCESS &&
713 AFSIgnoreReparsePointToFile() &&
714 pDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_FILE)
718 // We found an entity that matches the policy.
719 // Therefore, we are done. Cleanup the cloned data
720 // and clear the FILE_OPEN_REPARSE_FLAG so we do not
721 // later mark the CCB with CCB_FLAG_MASK_OPENED_REPARSE_POINT.
724 AFSFreeNameArray( pNameArrayClone);
726 pNameArrayClone = NULL;
728 ClearFlag( ulOptions, FILE_OPEN_REPARSE_POINT);
733 // There is no matching policy, so we need to cleanup the
734 // output values from AFSLocateNameEntry(), restore the
735 // cloned information, and re-issue the request attempting
736 // to open the reparse point (if any).
739 if ( pNewVolumeCB != NULL)
742 lCount = AFSVolumeDecrement( pNewVolumeCB,
743 NewVolumeReferenceReason);
747 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
750 if ( pNewParentDirectoryCB)
753 lCount = InterlockedDecrement( &pNewParentDirectoryCB->DirOpenReferenceCount);
755 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
756 AFS_TRACE_LEVEL_VERBOSE,
757 "AFSCommonCreate DecrementY count on %wZ DE %p Ccb %p Cnt %d\n",
758 &pNewParentDirectoryCB->NameInformation.FileName,
759 pNewParentDirectoryCB,
763 pNewParentDirectoryCB = NULL;
769 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
771 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
772 AFS_TRACE_LEVEL_VERBOSE,
773 "AFSCommonCreate DecrementZ count on %wZ DE %p Ccb %p Cnt %d\n",
774 &pDirectoryCB->NameInformation.FileName,
782 RtlZeroMemory( &uniComponentName,
783 sizeof( UNICODE_STRING));
785 if ( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
788 AFSExFreePoolWithTag( uniRootFileName.Buffer, 0);
790 uniRootFileName = uniSubstitutedPathName;
793 AFSFreeNameArray( pNameArray);
795 pNameArray = pNameArrayClone;
797 pNameArrayClone = NULL;
803 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
804 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
805 AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
807 ntStatus = AFSLocateNameEntry( &stAuthGroup,
812 ulNameProcessingFlags,
816 &NewVolumeReferenceReason,
817 &pNewParentDirectoryCB,
825 AFSFreeNameArray( pNameArrayClone);
827 pNameArrayClone = NULL;
830 if ( pNewVolumeCB != NULL)
834 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
835 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
836 // the reference on pVolumeCB that was held prior to the call.
837 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
838 // will be released second.
841 lCount = AFSVolumeDecrement( pVolumeCB,
842 VolumeReferenceReason);
844 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
845 AFS_TRACE_LEVEL_VERBOSE,
846 "AFSCommonCreate Decrement count on volume %p Reason %u Cnt %d\n",
848 VolumeReferenceReason,
851 pVolumeCB = pNewVolumeCB;
855 VolumeReferenceReason = NewVolumeReferenceReason;
857 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
859 bReleaseVolume = (pVolumeCB != NULL);
863 // AFSLocateNameEntry does not alter the reference count of
864 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
868 if ( bReleaseParentDir)
871 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
873 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
874 AFS_TRACE_LEVEL_VERBOSE,
875 "AFSCommonCreate DecrementX count on %wZ DE %p Ccb %p Cnt %d\n",
876 &pParentDirectoryCB->NameInformation.FileName,
882 pParentDirectoryCB = pNewParentDirectoryCB;
884 pNewParentDirectoryCB = NULL;
886 bReleaseParentDir = (pParentDirectoryCB != NULL);
894 if( !NT_SUCCESS( ntStatus) &&
895 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
898 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
900 uniSubstitutedPathName.Buffer = NULL;
904 // AFSLocateNameEntry released the Parent while walking the
908 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
909 AFS_TRACE_LEVEL_VERBOSE,
910 "AFSCommonCreate (%p) Failed to locate name entry for %wZ Status %08lX\n",
915 try_return( ntStatus);
919 // Check for STATUS_REPARSE
922 if( ntStatus == STATUS_REPARSE)
925 uniSubstitutedPathName.Buffer = NULL;
928 // Update the information and return
931 Irp->IoStatus.Information = IO_REPARSE;
933 try_return( ntStatus);
937 // If we re-allocated the name, then update our substitute name
940 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
943 uniSubstitutedPathName = uniRootFileName;
948 uniSubstitutedPathName.Buffer = NULL;
952 // Check for a symlink access
955 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
956 pParentDirectoryCB != NULL)
960 // pParentDirectoryCB DirOpenReferenceCount is still held
963 UNICODE_STRING uniFinalComponent;
965 uniFinalComponent.Length = 0;
966 uniFinalComponent.MaximumLength = 0;
967 uniFinalComponent.Buffer = NULL;
969 AFSRetrieveFinalComponent( &uniFileName,
972 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
975 if( !NT_SUCCESS( ntStatus) &&
976 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
979 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
980 AFS_TRACE_LEVEL_VERBOSE,
981 "AFSCommonCreate (%p) Failing access to symlink %wZ Status %08lX\n",
986 try_return( ntStatus);
993 // If we have no parent then this is a root open, be sure there is a directory entry
997 else if( pParentDirectoryCB == NULL &&
998 pDirectoryCB == NULL)
1001 pDirectoryCB = pVolumeCB->DirectoryCB;
1003 lCount = InterlockedIncrement( &pDirectoryCB->DirOpenReferenceCount);
1005 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1006 AFS_TRACE_LEVEL_VERBOSE,
1007 "AFSCommonCreate Increment0 count on %wZ DE %p Ccb %p Cnt %d\n",
1008 &pDirectoryCB->NameInformation.FileName,
1016 if( bOpenTargetDirectory)
1020 // If we have a directory cb for the entry then dereference it and reference the parent
1023 if( pDirectoryCB != NULL)
1026 if ( !bReleaseParentDir)
1030 // Perform in this order to prevent thrashing
1033 lCount = InterlockedIncrement( &pParentDirectoryCB->DirOpenReferenceCount);
1035 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1036 AFS_TRACE_LEVEL_VERBOSE,
1037 "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
1038 &pParentDirectoryCB->NameInformation.FileName,
1043 bReleaseParentDir = TRUE;
1047 // Do NOT decrement the reference count on the pDirectoryCB yet.
1048 // The BackupEntry below might drop the count to zero leaving
1049 // the entry subject to being deleted and we need some of the
1050 // contents during later processing
1053 AFSBackupEntry( pNameArray);
1057 // OK, open the target directory
1060 if( uniComponentName.Length == 0)
1062 AFSRetrieveFinalComponent( &uniFileName,
1066 ntStatus = AFSOpenTargetDirectory( Irp,
1074 if( !NT_SUCCESS( ntStatus))
1077 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1078 AFS_TRACE_LEVEL_ERROR,
1079 "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
1080 &pParentDirectoryCB->NameInformation.FileName,
1084 try_return( ntStatus);
1087 if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
1090 if( pDirectoryCB == NULL ||
1091 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
1093 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1094 AFS_TRACE_LEVEL_VERBOSE,
1095 "AFSCommonCreate (%p) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
1099 pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0));
1103 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1104 AFS_TRACE_LEVEL_VERBOSE,
1105 "AFSCommonCreate (%p) Opening as reparse point %wZ Type %08lX\n",
1108 pDirectoryCB->ObjectInformation->FileType));
1110 bOpenedReparsePoint = TRUE;
1115 // Based on the options passed in, process the file accordingly.
1118 if( ulCreateDisposition == FILE_CREATE ||
1119 ( ( ulCreateDisposition == FILE_OPEN_IF ||
1120 ulCreateDisposition == FILE_OVERWRITE_IF) &&
1121 pDirectoryCB == NULL))
1124 if( uniComponentName.Length == 0 ||
1125 pDirectoryCB != NULL)
1129 // We traversed the entire path so we found each entry,
1130 // fail with collision
1133 if( pDirectoryCB != NULL)
1136 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1137 AFS_TRACE_LEVEL_VERBOSE,
1138 "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
1139 &pDirectoryCB->NameInformation.FileName,
1145 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1146 AFS_TRACE_LEVEL_VERBOSE,
1147 "AFSCommonCreate Object name collision on create Status %08lX\n",
1151 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
1155 // OK, go and create the node
1158 ntStatus = AFSProcessCreate( Irp,
1168 if( !NT_SUCCESS( ntStatus))
1171 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1172 AFS_TRACE_LEVEL_ERROR,
1173 "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
1175 &pParentDirectoryCB->NameInformation.FileName,
1179 try_return( ntStatus);
1183 // We should not have an extra component except for PIOCtl opens
1186 if( uniComponentName.Length > 0)
1190 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
1193 if( RtlCompareUnicodeString( &AFSPIOCtlName,
1199 // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
1200 // pParentDirectoryCB.
1203 ntStatus = AFSOpenIOCtlFcb( Irp,
1209 if( !NT_SUCCESS( ntStatus))
1212 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1213 AFS_TRACE_LEVEL_ERROR,
1214 "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
1222 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1223 AFS_TRACE_LEVEL_VERBOSE,
1224 "AFSCommonCreate (%p) File %wZ name not found\n",
1228 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
1231 try_return( ntStatus);
1235 // For root opens the parent will be NULL
1238 if( pParentDirectoryCB == NULL)
1242 // Check for the delete on close flag for the root
1245 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
1248 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1249 AFS_TRACE_LEVEL_ERROR,
1250 "AFSCommonCreate (%p) Attempt to open root as delete on close\n",
1253 try_return( ntStatus = STATUS_CANNOT_DELETE);
1257 // If this is the target directory, then bail
1260 if( bOpenTargetDirectory)
1263 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1264 AFS_TRACE_LEVEL_ERROR,
1265 "AFSCommonCreate (%p) Attempt to open root as target directory\n",
1268 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1272 // Go and open the root of the volume
1275 ntStatus = AFSOpenRoot( Irp,
1281 if( !NT_SUCCESS( ntStatus))
1284 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1285 AFS_TRACE_LEVEL_ERROR,
1286 "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
1287 pVolumeCB->ObjectInformation.FileId.Cell,
1288 pVolumeCB->ObjectInformation.FileId.Volume,
1292 try_return( ntStatus);
1296 // At this point if we have no pDirectoryCB it was not found.
1299 if( pDirectoryCB == NULL)
1302 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1303 AFS_TRACE_LEVEL_ERROR,
1304 "AFSCommonCreate Failing access to %wZ Name not found\n",
1307 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
1310 if( ulCreateDisposition == FILE_OVERWRITE ||
1311 ulCreateDisposition == FILE_SUPERSEDE ||
1312 ulCreateDisposition == FILE_OVERWRITE_IF)
1316 // Go process a file for overwrite or supersede.
1319 ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
1328 if( !NT_SUCCESS( ntStatus))
1331 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1332 AFS_TRACE_LEVEL_ERROR,
1333 "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
1334 &pDirectoryCB->NameInformation.FileName,
1338 try_return( ntStatus);
1342 // Trying to open the file
1345 ntStatus = AFSProcessOpen( Irp,
1350 bOpenedReparsePoint,
1354 if( !NT_SUCCESS( ntStatus))
1357 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1358 AFS_TRACE_LEVEL_ERROR,
1359 "AFSCommonCreate Failed open on %wZ Status %08lX\n",
1360 &pDirectoryCB->NameInformation.FileName,
1366 if( NT_SUCCESS( ntStatus) &&
1367 ntStatus != STATUS_REPARSE)
1373 AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
1376 RtlCopyMemory( &pCcb->AuthGroup,
1381 // If we have a substitute name, then use it
1384 if( uniSubstitutedPathName.Buffer != NULL)
1387 pCcb->FullFileName = uniSubstitutedPathName;
1389 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1391 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1396 pCcb->FullFileName = uniRootFileName;
1398 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1401 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1403 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1407 if( bOpenedReparsePoint)
1409 SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1412 lCount = pCcb->DirectoryCB->DirOpenReferenceCount;
1414 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1415 AFS_TRACE_LEVEL_VERBOSE,
1416 "AFSCommonCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1417 &pCcb->DirectoryCB->NameInformation.FileName,
1422 ASSERT( lCount >= 0);
1424 pCcb->CurrentDirIndex = 0;
1426 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1429 SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1433 // Save off the name array for this instance
1436 pCcb->NameArray = pNameArray;
1440 AFSReleaseResource( &pCcb->NPCcb->CcbLock);
1444 // If we make it here then init the FO for the request.
1447 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1448 AFS_TRACE_LEVEL_VERBOSE_2,
1449 "AFSCommonCreate (%p) FileObject %p FsContext %p FsContext2 %p\n",
1455 pFileObject->FsContext = (void *)pFcb;
1457 pFileObject->FsContext2 = (void *)pCcb;
1462 ASSERT( pFcb->OpenHandleCount > 0);
1464 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1467 // For files perform additional processing
1470 switch( pFcb->Header.NodeTypeCode)
1477 pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1482 // If the user did not request nobuffering then mark the FO as cacheable
1485 if( bNoIntermediateBuffering)
1488 pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1493 pFileObject->Flags |= FO_CACHE_SUPPORTED;
1497 // If the file was opened for execution then we need to set the bit in the FO
1500 if( BooleanFlagOn( *pDesiredAccess,
1504 SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1508 // Update the last access time
1511 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1522 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1523 AFS_TRACE_LEVEL_ERROR,
1524 "AFSCommonCreate (%p) Returning with NULL Fcb FileObject %p FsContext %p FsContext2 %p\n",
1533 if( NT_SUCCESS( ntStatus) &&
1534 ntStatus == STATUS_REPARSE)
1537 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1538 AFS_TRACE_LEVEL_ERROR,
1539 "AFSCommonCreate (%p) STATUS_REPARSE FileObject %p FsContext %p FsContext2 %p\n",
1547 // Free up the sub name if we have one
1550 if( uniSubstitutedPathName.Buffer != NULL)
1553 AFSExFreePoolWithTag( uniSubstitutedPathName.Buffer, 0);
1555 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1560 // Free up the name array ...
1563 if( pNameArray != NULL)
1566 AFSFreeNameArray( pNameArray);
1569 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1572 AFSExFreePoolWithTag( uniRootFileName.Buffer, 0);
1578 lCount = AFSVolumeDecrement( pVolumeCB,
1579 VolumeReferenceReason);
1581 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1582 AFS_TRACE_LEVEL_VERBOSE,
1583 "AFSCommonCreate Decrement count on Volume %08lX Reason %u Cnt %d\n",
1585 VolumeReferenceReason,
1593 // Release the reference from AFSLocateNameEntry
1596 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
1598 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1599 AFS_TRACE_LEVEL_VERBOSE,
1600 "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1601 &pDirectoryCB->NameInformation.FileName,
1606 ASSERT( lCount >= 0);
1609 if ( bReleaseParentDir)
1613 // Release the reference from AFSLocateNameEntry
1616 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
1618 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1619 AFS_TRACE_LEVEL_VERBOSE,
1620 "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1621 &pParentDirectoryCB->NameInformation.FileName,
1626 ASSERT( lCount >= 0);
1630 // Setup the Irp for completion, the Information has been set previously
1633 Irp->IoStatus.Status = ntStatus;
1640 AFSOpenAFSRoot( IN PIRP Irp,
1645 NTSTATUS ntStatus = STATUS_SUCCESS;
1652 // Initialize the Ccb for the file.
1655 ntStatus = AFSInitCcb( Ccb,
1656 AFSGlobalRoot->DirectoryCB,
1660 if( !NT_SUCCESS( ntStatus))
1663 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1664 AFS_TRACE_LEVEL_ERROR,
1665 "AFSOpenAFSRoot (%p) Failed to allocate Ccb\n",
1668 try_return( ntStatus);
1672 // Increment the open count on this Fcb
1675 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1677 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1678 AFS_TRACE_LEVEL_VERBOSE,
1679 "AFSOpenAFSRoot Increment count on Fcb %p Cnt %d\n",
1680 AFSGlobalRoot->RootFcb,
1683 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1685 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1686 AFS_TRACE_LEVEL_VERBOSE,
1687 "AFSOpenAFSRoot Increment handle count on Fcb %p Cnt %d\n",
1688 AFSGlobalRoot->RootFcb,
1691 *Fcb = AFSGlobalRoot->RootFcb;
1694 // Return the open result for this file
1697 Irp->IoStatus.Information = FILE_OPENED;
1708 AFSOpenRoot( IN PIRP Irp,
1709 IN AFSVolumeCB *VolumeCB,
1711 OUT AFSFcb **RootFcb,
1715 NTSTATUS ntStatus = STATUS_SUCCESS;
1716 PFILE_OBJECT pFileObject = NULL;
1717 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1718 PACCESS_MASK pDesiredAccess = NULL;
1719 USHORT usShareAccess;
1721 BOOLEAN bAllocatedCcb = FALSE;
1722 BOOLEAN bReleaseFcb = FALSE;
1723 AFSFileOpenCB stOpenCB;
1724 AFSFileOpenResultCB stOpenResultCB;
1725 ULONG ulResultLen = 0;
1731 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1732 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1733 ulOptions = pIrpSp->Parameters.Create.Options;
1735 pFileObject = pIrpSp->FileObject;
1737 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1740 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1742 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1743 AFS_TRACE_LEVEL_ERROR,
1744 "AFSOpenRoot (%p) Attempt to open root as file Status %08lX\n",
1748 try_return( ntStatus);
1752 // Check if we should go and retrieve updated information for the node
1755 ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1760 if( !NT_SUCCESS( ntStatus))
1763 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1764 AFS_TRACE_LEVEL_ERROR,
1765 "AFSOpenRoot (%p) Failed to validate root entry Status %08lX\n",
1769 try_return( ntStatus);
1773 // Check with the service that we can open the file
1776 RtlZeroMemory( &stOpenCB,
1777 sizeof( AFSFileOpenCB));
1779 stOpenCB.DesiredAccess = *pDesiredAccess;
1781 stOpenCB.ShareAccess = usShareAccess;
1783 stOpenResultCB.GrantedAccess = 0;
1785 ulResultLen = sizeof( AFSFileOpenResultCB);
1787 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1788 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1791 &VolumeCB->ObjectInformation.FileId,
1792 VolumeCB->VolumeInformation.Cell,
1793 VolumeCB->VolumeInformation.CellLength,
1795 sizeof( AFSFileOpenCB),
1796 (void *)&stOpenResultCB,
1799 if( !NT_SUCCESS( ntStatus))
1802 UNICODE_STRING uniGUID;
1805 uniGUID.MaximumLength = 0;
1806 uniGUID.Buffer = NULL;
1808 if( AuthGroup != NULL)
1810 RtlStringFromGUID( *AuthGroup,
1814 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1815 AFS_TRACE_LEVEL_ERROR,
1816 "AFSOpenRoot (%p) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1818 VolumeCB->ObjectInformation.FileId.Cell,
1819 VolumeCB->ObjectInformation.FileId.Volume,
1823 if( AuthGroup != NULL)
1825 RtlFreeUnicodeString( &uniGUID);
1828 try_return( ntStatus);
1832 // If the entry is not initialized then do it now
1835 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1838 AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1841 ntStatus = AFSEnumerateDirectory( AuthGroup,
1842 &VolumeCB->ObjectInformation,
1845 if( !NT_SUCCESS( ntStatus))
1848 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1850 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1851 AFS_TRACE_LEVEL_ERROR,
1852 "AFSOpenRoot (%p) Failed to enumerate directory Status %08lX\n",
1856 try_return( ntStatus);
1859 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1863 // If the root fcb has been initialized then check access otherwise
1864 // init the volume fcb
1867 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1870 if( !NT_SUCCESS( ntStatus))
1873 try_return( ntStatus);
1876 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1878 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1879 AFS_TRACE_LEVEL_VERBOSE,
1880 "AFSOpenRoot Increment count on Fcb %p Cnt %d\n",
1887 // If there are current opens on the Fcb, check the access.
1890 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1893 ntStatus = IoCheckShareAccess( *pDesiredAccess,
1896 &VolumeCB->RootFcb->ShareAccess,
1899 if( !NT_SUCCESS( ntStatus))
1902 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1903 AFS_TRACE_LEVEL_ERROR,
1904 "AFSOpenRoot (%p) Access check failure Status %08lX\n",
1908 try_return( ntStatus);
1913 // Initialize the Ccb for the file.
1916 ntStatus = AFSInitCcb( Ccb,
1917 VolumeCB->DirectoryCB,
1921 if( !NT_SUCCESS( ntStatus))
1924 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1925 AFS_TRACE_LEVEL_ERROR,
1926 "AFSOpenRoot (%p) Failed to allocate Ccb Status %08lX\n",
1930 try_return( ntStatus);
1933 bAllocatedCcb = TRUE;
1936 // OK, update the share access on the fileobject
1939 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1942 IoUpdateShareAccess( pFileObject,
1943 &VolumeCB->RootFcb->ShareAccess);
1952 IoSetShareAccess( *pDesiredAccess,
1955 &VolumeCB->RootFcb->ShareAccess);
1959 // Increment the open count on this Fcb
1962 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1964 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1965 AFS_TRACE_LEVEL_VERBOSE,
1966 "AFSOpenRoot Increment handle count on Fcb %p Cnt %d\n",
1971 // Indicate the object is held
1974 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1977 // Return the open result for this file
1980 Irp->IoStatus.Information = FILE_OPENED;
1982 *RootFcb = VolumeCB->RootFcb;
1988 if ( !NT_SUCCESS( ntStatus))
1991 lCount = InterlockedDecrement( &VolumeCB->RootFcb->OpenReferenceCount);
1993 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1994 AFS_TRACE_LEVEL_VERBOSE,
1995 "AFSOpenRoot Decrement count on Fcb %p Cnt %d\n",
2000 AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
2003 if( !NT_SUCCESS( ntStatus))
2015 Irp->IoStatus.Information = 0;
2023 AFSProcessCreate( IN PIRP Irp,
2025 IN AFSVolumeCB *VolumeCB,
2026 IN AFSDirectoryCB *ParentDirCB,
2027 IN PUNICODE_STRING FileName,
2028 IN PUNICODE_STRING ComponentName,
2029 IN PUNICODE_STRING FullFileName,
2034 NTSTATUS ntStatus = STATUS_SUCCESS;
2035 PFILE_OBJECT pFileObject = NULL;
2036 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2037 ULONG ulOptions = 0;
2038 ULONG ulAttributes = 0;
2039 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
2040 PACCESS_MASK pDesiredAccess = NULL;
2041 USHORT usShareAccess;
2042 AFSDirectoryCB *pDirEntry = NULL;
2043 AFSObjectInfoCB *pParentObjectInfo = NULL;
2044 AFSObjectInfoCB *pObjectInfo = NULL;
2050 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2051 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2053 pFileObject = pIrpSp->FileObject;
2056 // Extract out the options
2059 ulOptions = pIrpSp->Parameters.Create.Options;
2062 // We pass all attributes they want to apply to the file to the create
2065 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
2068 // If this is a directory create then set the attribute correctly
2071 if( ulOptions & FILE_DIRECTORY_FILE)
2074 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
2077 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2078 AFS_TRACE_LEVEL_VERBOSE,
2079 "AFSProcessCreate (%p) Creating file %wZ Attributes %08lX\n",
2084 if( BooleanFlagOn( VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
2087 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2088 AFS_TRACE_LEVEL_ERROR,
2089 "AFSProcessCreate Request failed due to read only volume %wZ\n",
2092 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
2095 pParentObjectInfo = ParentDirCB->ObjectInformation;
2098 // Allocate and insert the direntry into the parent node
2101 ntStatus = AFSCreateDirEntry( AuthGroup,
2109 if( !NT_SUCCESS( ntStatus))
2112 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2113 AFS_TRACE_LEVEL_ERROR,
2114 "AFSProcessCreate (%p) Failed to create directory entry %wZ Status %08lX\n",
2119 try_return( ntStatus);
2122 bFileCreated = TRUE;
2124 pObjectInfo = pDirEntry->ObjectInformation;
2126 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
2127 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
2130 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2131 AFS_TRACE_LEVEL_VERBOSE,
2132 "AFSProcessCreate (%p) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2134 &pDirEntry->NameInformation.FileName,
2135 pObjectInfo->FileId.Cell,
2136 pObjectInfo->FileId.Volume,
2137 pObjectInfo->FileId.Vnode,
2138 pObjectInfo->FileId.Unique));
2140 ntStatus = AFSEvaluateNode( AuthGroup,
2143 if( !NT_SUCCESS( ntStatus))
2146 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
2149 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2152 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2153 AFS_TRACE_LEVEL_ERROR,
2154 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
2156 &pDirEntry->NameInformation.FileName,
2157 pObjectInfo->FileId.Cell,
2158 pObjectInfo->FileId.Volume,
2159 pObjectInfo->FileId.Vnode,
2160 pObjectInfo->FileId.Unique,
2161 pParentObjectInfo->FileId.Cell,
2162 pParentObjectInfo->FileId.Volume,
2163 pParentObjectInfo->FileId.Vnode,
2164 pParentObjectInfo->FileId.Unique,
2167 else if ( AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId))
2170 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2171 AFS_TRACE_LEVEL_ERROR,
2172 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2174 &pDirEntry->NameInformation.FileName,
2175 pObjectInfo->FileId.Cell,
2176 pObjectInfo->FileId.Volume,
2177 pObjectInfo->FileId.Vnode,
2178 pObjectInfo->FileId.Unique,
2179 pParentObjectInfo->FileId.Cell,
2180 pParentObjectInfo->FileId.Volume,
2181 pParentObjectInfo->FileId.Vnode,
2182 pParentObjectInfo->FileId.Unique,
2188 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2189 AFS_TRACE_LEVEL_ERROR,
2190 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2192 &pDirEntry->NameInformation.FileName,
2193 pObjectInfo->FileId.Cell,
2194 pObjectInfo->FileId.Volume,
2195 pObjectInfo->FileId.Vnode,
2196 pObjectInfo->FileId.Unique,
2197 pParentObjectInfo->FileId.Cell,
2198 pParentObjectInfo->FileId.Volume,
2199 pParentObjectInfo->FileId.Vnode,
2200 pParentObjectInfo->FileId.Unique,
2201 pObjectInfo->ParentFileId.Cell,
2202 pObjectInfo->ParentFileId.Volume,
2203 pObjectInfo->ParentFileId.Vnode,
2204 pObjectInfo->ParentFileId.Unique,
2211 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2212 AFS_TRACE_LEVEL_ERROR,
2213 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2215 &pDirEntry->NameInformation.FileName,
2216 pObjectInfo->FileId.Cell,
2217 pObjectInfo->FileId.Volume,
2218 pObjectInfo->FileId.Vnode,
2219 pObjectInfo->FileId.Unique,
2223 try_return( ntStatus);
2226 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
2229 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2230 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
2233 // We may have raced and the Fcb is already created
2237 // Allocate and initialize the Fcb for the file.
2240 ntStatus = AFSInitFcb( pDirEntry);
2242 *Fcb = pObjectInfo->Fcb;
2244 if( !NT_SUCCESS( ntStatus))
2247 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2248 AFS_TRACE_LEVEL_ERROR,
2249 "AFSProcessCreate (%p) Failed to initialize fcb %wZ Status %08lX\n",
2254 try_return( ntStatus);
2257 ntStatus = STATUS_SUCCESS;
2260 // Increment the open count on this Fcb
2263 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
2265 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2266 AFS_TRACE_LEVEL_VERBOSE,
2267 "AFSProcessCreate Increment count on Fcb %p Cnt %d\n",
2274 // Initialize the Ccb for the file.
2277 ntStatus = AFSInitCcb( Ccb,
2282 if( !NT_SUCCESS( ntStatus))
2285 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2286 AFS_TRACE_LEVEL_ERROR,
2287 "AFSProcessCreate (%p) Failed to initialize ccb %wZ Status %08lX\n",
2292 try_return( ntStatus);
2295 bAllocatedCcb = TRUE;
2298 // If this is a file, update the headers filesizes.
2301 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
2305 // Update the sizes with the information passed in
2308 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2309 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2310 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2313 // Notify the system of the addition
2316 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2318 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
2319 (ULONG)FILE_ACTION_ADDED);
2321 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2323 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2327 // This is a new directory node so indicate it has been enumerated
2330 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
2333 // And the parent directory entry
2336 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2339 // Notify the system of the addition
2342 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2344 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2345 (ULONG)FILE_ACTION_ADDED);
2347 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2348 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2349 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2350 (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
2354 // And the parent directory entry
2357 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2360 // Notify the system of the addition
2363 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2365 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2366 (ULONG)FILE_ACTION_ADDED);
2370 // Save off the access for the open
2373 IoSetShareAccess( *pDesiredAccess,
2376 &(*Fcb)->ShareAccess);
2378 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2380 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2381 AFS_TRACE_LEVEL_VERBOSE,
2382 "AFSProcessCreate Increment handle count on Fcb %p Cnt %d\n",
2387 // Increment the open reference and handle on the parent node
2390 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2392 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2393 AFS_TRACE_LEVEL_VERBOSE,
2394 "AFSProcessCreate Increment child open handle count on Parent object %p Cnt %d\n",
2398 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2400 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2401 AFS_TRACE_LEVEL_VERBOSE,
2402 "AFSProcessCreate Increment child open ref count on Parent object %p Cnt %d\n",
2406 if( ulOptions & FILE_DELETE_ON_CLOSE)
2410 // Mark it for delete on close
2413 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2414 AFS_TRACE_LEVEL_VERBOSE,
2415 "AFSProcessCreate (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2420 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2424 // Indicate the object is locked in the service
2427 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2430 // Return the open result for this file
2433 Irp->IoStatus.Information = FILE_CREATED;
2438 // If we created the Fcb we need to release the resources
2444 if( !NT_SUCCESS( ntStatus))
2447 // Decrement the open count on this Fcb
2450 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2452 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2453 AFS_TRACE_LEVEL_VERBOSE,
2454 "AFSProcessCreate Decrement count on Fcb %p Cnt %d\n",
2459 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2466 // Decrement the reference added during initialization of the DE
2467 // AFSInitCcb allocates its own reference count.
2470 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2472 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2473 AFS_TRACE_LEVEL_VERBOSE,
2474 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2475 &pDirEntry->NameInformation.FileName,
2479 ASSERT( lCount >= 0);
2482 if( !NT_SUCCESS( ntStatus))
2488 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2489 AFS_TRACE_LEVEL_VERBOSE,
2490 "AFSProcessCreate Create failed, removing DE %p from parent object %p Status %08lX\n",
2496 // Remove the dir entry from the parent
2499 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2502 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2504 AFSNotifyDelete( pDirEntry,
2509 // Pull the directory entry from the parent
2512 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2514 FALSE); // Leave it in the enum list so the worker cleans it up
2517 // Tag the parent as needing verification
2520 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2522 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2524 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2535 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2548 AFSOpenTargetDirectory( IN PIRP Irp,
2549 IN AFSVolumeCB *VolumeCB,
2550 IN AFSDirectoryCB *ParentDirectoryCB,
2551 IN AFSDirectoryCB *TargetDirectoryCB,
2552 IN UNICODE_STRING *TargetName,
2556 UNREFERENCED_PARAMETER(VolumeCB);
2557 NTSTATUS ntStatus = STATUS_SUCCESS;
2558 PFILE_OBJECT pFileObject = NULL;
2559 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2560 PACCESS_MASK pDesiredAccess = NULL;
2561 USHORT usShareAccess;
2562 BOOLEAN bAllocatedCcb = FALSE;
2563 BOOLEAN bReleaseFcb = FALSE;
2564 AFSObjectInfoCB *pParentObject = NULL;
2565 AFSObjectInfoCB *pGrandParentObject = NULL;
2566 UNICODE_STRING uniTargetName;
2572 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2573 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2575 pFileObject = pIrpSp->FileObject;
2577 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2578 AFS_TRACE_LEVEL_VERBOSE,
2579 "AFSOpenTargetDirectory (%p) Processing file %wZ\n",
2583 pParentObject = ParentDirectoryCB->ObjectInformation;
2585 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2588 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2592 // Make sure we have an Fcb for the access
2595 // Allocate and initialize the Fcb for the file.
2598 ntStatus = AFSInitFcb( ParentDirectoryCB);
2600 *Fcb = pParentObject->Fcb;
2602 if( !NT_SUCCESS( ntStatus))
2605 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2606 AFS_TRACE_LEVEL_ERROR,
2607 "AFSOpenTargetDirectory (%p) Failed to initialize fcb %wZ Status %08lX\n",
2609 &ParentDirectoryCB->NameInformation.FileName,
2612 try_return( ntStatus);
2615 ntStatus = STATUS_SUCCESS;
2618 // Increment the open count on this Fcb
2621 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2623 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2624 AFS_TRACE_LEVEL_VERBOSE,
2625 "AFSOpenTargetDirectory Increment count on Fcb %p Cnt %d\n",
2632 // If there are current opens on the Fcb, check the access.
2635 if( pParentObject->Fcb->OpenHandleCount > 0)
2638 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2641 &pParentObject->Fcb->ShareAccess,
2644 if( !NT_SUCCESS( ntStatus))
2647 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2648 AFS_TRACE_LEVEL_ERROR,
2649 "AFSOpenTargetDirectory (%p) Access check failure %wZ Status %08lX\n",
2651 &ParentDirectoryCB->NameInformation.FileName,
2654 try_return( ntStatus);
2659 // Initialize the Ccb for the file.
2662 ntStatus = AFSInitCcb( Ccb,
2667 if( !NT_SUCCESS( ntStatus))
2670 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2671 AFS_TRACE_LEVEL_ERROR,
2672 "AFSOpenTargetDirectory (%p) Failed to initialize ccb %wZ Status %08lX\n",
2674 &ParentDirectoryCB->NameInformation.FileName,
2677 try_return( ntStatus);
2680 bAllocatedCcb = TRUE;
2682 if( TargetDirectoryCB != NULL &&
2683 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2689 Irp->IoStatus.Information = FILE_EXISTS;
2691 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2696 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2698 uniTargetName = *TargetName;
2702 // Update the filename in the fileobject for rename processing
2705 RtlCopyMemory( pFileObject->FileName.Buffer,
2706 uniTargetName.Buffer,
2707 uniTargetName.Length);
2709 pFileObject->FileName.Length = uniTargetName.Length;
2712 // OK, update the share access on the fileobject
2715 if( pParentObject->Fcb->OpenHandleCount > 0)
2718 IoUpdateShareAccess( pFileObject,
2719 &pParentObject->Fcb->ShareAccess);
2728 IoSetShareAccess( *pDesiredAccess,
2731 &pParentObject->Fcb->ShareAccess);
2734 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2736 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2737 AFS_TRACE_LEVEL_VERBOSE,
2738 "AFSOpenTargetDirectory Increment handle count on Fcb %p Cnt %d\n",
2743 // Increment the open reference and handle on the parent node
2746 if( BooleanFlagOn( pParentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2749 pGrandParentObject = AFSFindObjectInfo( pParentObject->VolumeCB,
2750 &pParentObject->ParentFileId,
2753 if ( pGrandParentObject)
2756 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenHandleCount);
2758 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2759 AFS_TRACE_LEVEL_VERBOSE,
2760 "AFSOpenTargetDirectory Increment child open handle count on Parent object %p Cnt %d\n",
2764 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenReferenceCount);
2766 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2767 AFS_TRACE_LEVEL_VERBOSE,
2768 "AFSOpenTargetDirectory Increment child open ref count on Parent object %p Cnt %d\n",
2772 AFSReleaseObjectInfo( &pGrandParentObject);
2781 if( !NT_SUCCESS( ntStatus))
2784 // Decrement the open count on this Fcb
2787 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2789 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2790 AFS_TRACE_LEVEL_VERBOSE,
2791 "AFSOpenTargetDirectory Decrement count on Fcb %p Cnt %d\n",
2796 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2799 if( !NT_SUCCESS( ntStatus))
2812 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2823 AFSProcessOpen( IN PIRP Irp,
2825 IN AFSVolumeCB *VolumeCB,
2826 IN AFSDirectoryCB *ParentDirCB,
2827 IN AFSDirectoryCB *DirectoryCB,
2828 IN BOOLEAN bOpenedReparsePoint,
2832 UNREFERENCED_PARAMETER(VolumeCB);
2833 NTSTATUS ntStatus = STATUS_SUCCESS;
2834 PFILE_OBJECT pFileObject = NULL;
2835 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2836 PACCESS_MASK pDesiredAccess = NULL;
2837 USHORT usShareAccess;
2838 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE;
2839 ULONG ulOptions = 0;
2840 AFSFileOpenCB stOpenCB;
2841 AFSFileOpenResultCB stOpenResultCB;
2842 ULONG ulResultLen = 0;
2843 AFSObjectInfoCB *pParentObjectInfo = NULL;
2844 AFSObjectInfoCB *pObjectInfo = NULL;
2845 ULONG ulFileAccess = 0;
2846 AFSFileAccessReleaseCB stReleaseFileAccess;
2852 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2853 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2855 pFileObject = pIrpSp->FileObject;
2857 pParentObjectInfo = ParentDirCB->ObjectInformation;
2859 pObjectInfo = DirectoryCB->ObjectInformation;
2861 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2862 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
2865 // Check if the entry is pending a deletion
2868 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2871 ntStatus = STATUS_DELETE_PENDING;
2873 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2874 AFS_TRACE_LEVEL_ERROR,
2875 "AFSProcessOpen (%p) Entry pending delete %wZ Status %08lX\n",
2877 &DirectoryCB->NameInformation.FileName,
2880 try_return( ntStatus);
2884 // Extract out the options
2887 ulOptions = pIrpSp->Parameters.Create.Options;
2890 // Check if we should go and retrieve updated information for the node
2893 ntStatus = AFSValidateEntry( DirectoryCB,
2895 bOpenedReparsePoint,
2898 if( !NT_SUCCESS( ntStatus))
2901 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2902 AFS_TRACE_LEVEL_ERROR,
2903 "AFSProcessOpen (%p) Failed to validate entry %wZ Status %08lX\n",
2905 &DirectoryCB->NameInformation.FileName,
2908 try_return( ntStatus);
2912 // If this is marked for delete on close then be sure we can delete the entry
2915 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2918 ntStatus = AFSNotifyDelete( DirectoryCB,
2922 if( !NT_SUCCESS( ntStatus))
2925 ntStatus = STATUS_CANNOT_DELETE;
2927 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2928 AFS_TRACE_LEVEL_ERROR,
2929 "AFSProcessOpen (%p) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2931 &DirectoryCB->NameInformation.FileName,
2934 try_return( ntStatus);
2939 // Be sure we have an Fcb for the current object
2942 ntStatus = AFSInitFcb( DirectoryCB);
2944 if( !NT_SUCCESS( ntStatus))
2947 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2948 AFS_TRACE_LEVEL_ERROR,
2949 "AFSProcessOpen (%p) Failed to init fcb on %wZ Status %08lX\n",
2951 &DirectoryCB->NameInformation.FileName,
2954 try_return( ntStatus);
2957 ntStatus = STATUS_SUCCESS;
2960 // AFSInitFcb returns the Fcb resource held
2966 // Increment the open count on this Fcb
2969 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2971 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2972 AFS_TRACE_LEVEL_VERBOSE,
2973 "AFSProcessOpen Increment2 count on Fcb %p Cnt %d\n",
2978 // Check access on the entry
2981 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2984 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2987 &pObjectInfo->Fcb->ShareAccess,
2990 if( !NT_SUCCESS( ntStatus))
2993 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2994 AFS_TRACE_LEVEL_ERROR,
2995 "AFSProcessOpen (%p) Failed to check share access on %wZ Status %08lX\n",
2997 &DirectoryCB->NameInformation.FileName,
3000 try_return( ntStatus);
3005 // Additional checks
3008 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
3012 // If the caller is asking for write access then try to flush the image section
3015 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
3016 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
3021 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3022 AFS_TRACE_LEVEL_VERBOSE,
3023 "AFSProcessOpen Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3024 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3025 PsGetCurrentThread()));
3027 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3033 bMmFlushed = MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3036 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
3041 ntStatus = GetExceptionCode();
3045 "EXCEPTION - AFSProcessOpen MmFlushImageSection failed FID %08lX-%08lX-%08lX-%08lX Status 0x%08lX\n",
3046 pObjectInfo->FileId.Cell,
3047 pObjectInfo->FileId.Volume,
3048 pObjectInfo->FileId.Vnode,
3049 pObjectInfo->FileId.Unique,
3053 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
3054 AFS_TRACE_LEVEL_VERBOSE,
3055 "AFSProcessOpen Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3056 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3057 PsGetCurrentThread()));
3059 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3064 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
3065 STATUS_SHARING_VIOLATION;
3067 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3068 AFS_TRACE_LEVEL_ERROR,
3069 "AFSProcessOpen (%p) Failed to flush image section %wZ Status %08lX\n",
3071 &DirectoryCB->NameInformation.FileName,
3074 try_return( ntStatus);
3078 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))