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,
1353 if( !NT_SUCCESS( ntStatus))
1356 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1357 AFS_TRACE_LEVEL_ERROR,
1358 "AFSCommonCreate Failed open on %wZ Status %08lX\n",
1359 &pDirectoryCB->NameInformation.FileName,
1365 if( NT_SUCCESS( ntStatus) &&
1366 ntStatus != STATUS_REPARSE)
1372 AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
1375 RtlCopyMemory( &pCcb->AuthGroup,
1380 // If we have a substitute name, then use it
1383 if( uniSubstitutedPathName.Buffer != NULL)
1386 pCcb->FullFileName = uniSubstitutedPathName;
1388 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1390 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1395 pCcb->FullFileName = uniRootFileName;
1397 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1400 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1402 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1406 if( bOpenedReparsePoint)
1408 SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1411 lCount = pCcb->DirectoryCB->DirOpenReferenceCount;
1413 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1414 AFS_TRACE_LEVEL_VERBOSE,
1415 "AFSCommonCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1416 &pCcb->DirectoryCB->NameInformation.FileName,
1421 ASSERT( lCount >= 0);
1423 pCcb->CurrentDirIndex = 0;
1425 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1428 SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1432 // Save off the name array for this instance
1435 pCcb->NameArray = pNameArray;
1439 AFSReleaseResource( &pCcb->NPCcb->CcbLock);
1443 // If we make it here then init the FO for the request.
1446 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1447 AFS_TRACE_LEVEL_VERBOSE_2,
1448 "AFSCommonCreate (%p) FileObject %p FsContext %p FsContext2 %p\n",
1454 pFileObject->FsContext = (void *)pFcb;
1456 pFileObject->FsContext2 = (void *)pCcb;
1461 ASSERT( pFcb->OpenHandleCount > 0);
1463 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1466 // For files perform additional processing
1469 switch( pFcb->Header.NodeTypeCode)
1476 pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1481 // If the user did not request nobuffering then mark the FO as cacheable
1484 if( bNoIntermediateBuffering)
1487 pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1492 pFileObject->Flags |= FO_CACHE_SUPPORTED;
1496 // If the file was opened for execution then we need to set the bit in the FO
1499 if( BooleanFlagOn( *pDesiredAccess,
1503 SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1507 // Update the last access time
1510 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1521 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1522 AFS_TRACE_LEVEL_ERROR,
1523 "AFSCommonCreate (%p) Returning with NULL Fcb FileObject %p FsContext %p FsContext2 %p\n",
1532 if( NT_SUCCESS( ntStatus) &&
1533 ntStatus == STATUS_REPARSE)
1536 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1537 AFS_TRACE_LEVEL_ERROR,
1538 "AFSCommonCreate (%p) STATUS_REPARSE FileObject %p FsContext %p FsContext2 %p\n",
1546 // Free up the sub name if we have one
1549 if( uniSubstitutedPathName.Buffer != NULL)
1552 AFSExFreePoolWithTag( uniSubstitutedPathName.Buffer, 0);
1554 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1559 // Free up the name array ...
1562 if( pNameArray != NULL)
1565 AFSFreeNameArray( pNameArray);
1568 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1571 AFSExFreePoolWithTag( uniRootFileName.Buffer, 0);
1577 lCount = AFSVolumeDecrement( pVolumeCB,
1578 VolumeReferenceReason);
1580 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1581 AFS_TRACE_LEVEL_VERBOSE,
1582 "AFSCommonCreate Decrement count on Volume %08lX Reason %u Cnt %d\n",
1584 VolumeReferenceReason,
1592 // Release the reference from AFSLocateNameEntry
1595 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
1597 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1598 AFS_TRACE_LEVEL_VERBOSE,
1599 "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1600 &pDirectoryCB->NameInformation.FileName,
1605 ASSERT( lCount >= 0);
1608 if ( bReleaseParentDir)
1612 // Release the reference from AFSLocateNameEntry
1615 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
1617 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1618 AFS_TRACE_LEVEL_VERBOSE,
1619 "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1620 &pParentDirectoryCB->NameInformation.FileName,
1625 ASSERT( lCount >= 0);
1629 // Setup the Irp for completion, the Information has been set previously
1632 Irp->IoStatus.Status = ntStatus;
1639 AFSOpenAFSRoot( IN PIRP Irp,
1644 NTSTATUS ntStatus = STATUS_SUCCESS;
1651 // Initialize the Ccb for the file.
1654 ntStatus = AFSInitCcb( Ccb,
1655 AFSGlobalRoot->DirectoryCB,
1659 if( !NT_SUCCESS( ntStatus))
1662 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1663 AFS_TRACE_LEVEL_ERROR,
1664 "AFSOpenAFSRoot (%p) Failed to allocate Ccb\n",
1667 try_return( ntStatus);
1671 // Increment the open count on this Fcb
1674 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1676 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1677 AFS_TRACE_LEVEL_VERBOSE,
1678 "AFSOpenAFSRoot Increment count on Fcb %p Cnt %d\n",
1679 AFSGlobalRoot->RootFcb,
1682 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1684 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1685 AFS_TRACE_LEVEL_VERBOSE,
1686 "AFSOpenAFSRoot Increment handle count on Fcb %p Cnt %d\n",
1687 AFSGlobalRoot->RootFcb,
1690 *Fcb = AFSGlobalRoot->RootFcb;
1693 // Return the open result for this file
1696 Irp->IoStatus.Information = FILE_OPENED;
1707 AFSOpenRoot( IN PIRP Irp,
1708 IN AFSVolumeCB *VolumeCB,
1710 OUT AFSFcb **RootFcb,
1714 NTSTATUS ntStatus = STATUS_SUCCESS;
1715 PFILE_OBJECT pFileObject = NULL;
1716 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1717 PACCESS_MASK pDesiredAccess = NULL;
1718 USHORT usShareAccess;
1720 BOOLEAN bAllocatedCcb = FALSE;
1721 BOOLEAN bReleaseFcb = FALSE;
1722 AFSFileOpenCB stOpenCB;
1723 AFSFileOpenResultCB stOpenResultCB;
1724 ULONG ulResultLen = 0;
1730 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1731 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1732 ulOptions = pIrpSp->Parameters.Create.Options;
1734 pFileObject = pIrpSp->FileObject;
1736 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1739 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1741 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1742 AFS_TRACE_LEVEL_ERROR,
1743 "AFSOpenRoot (%p) Attempt to open root as file Status %08lX\n",
1747 try_return( ntStatus);
1751 // Check if we should go and retrieve updated information for the node
1754 ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1759 if( !NT_SUCCESS( ntStatus))
1762 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1763 AFS_TRACE_LEVEL_ERROR,
1764 "AFSOpenRoot (%p) Failed to validate root entry Status %08lX\n",
1768 try_return( ntStatus);
1772 // Check with the service that we can open the file
1775 RtlZeroMemory( &stOpenCB,
1776 sizeof( AFSFileOpenCB));
1778 stOpenCB.DesiredAccess = *pDesiredAccess;
1780 stOpenCB.ShareAccess = usShareAccess;
1782 stOpenResultCB.GrantedAccess = 0;
1784 ulResultLen = sizeof( AFSFileOpenResultCB);
1786 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1787 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1790 &VolumeCB->ObjectInformation.FileId,
1791 VolumeCB->VolumeInformation.Cell,
1792 VolumeCB->VolumeInformation.CellLength,
1794 sizeof( AFSFileOpenCB),
1795 (void *)&stOpenResultCB,
1798 if( !NT_SUCCESS( ntStatus))
1801 UNICODE_STRING uniGUID;
1804 uniGUID.MaximumLength = 0;
1805 uniGUID.Buffer = NULL;
1807 if( AuthGroup != NULL)
1809 RtlStringFromGUID( *AuthGroup,
1813 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1814 AFS_TRACE_LEVEL_ERROR,
1815 "AFSOpenRoot (%p) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1817 VolumeCB->ObjectInformation.FileId.Cell,
1818 VolumeCB->ObjectInformation.FileId.Volume,
1822 if( AuthGroup != NULL)
1824 RtlFreeUnicodeString( &uniGUID);
1827 try_return( ntStatus);
1831 // If the entry is not initialized then do it now
1834 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1837 AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1840 ntStatus = AFSEnumerateDirectory( AuthGroup,
1841 &VolumeCB->ObjectInformation,
1844 if( !NT_SUCCESS( ntStatus))
1847 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1849 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1850 AFS_TRACE_LEVEL_ERROR,
1851 "AFSOpenRoot (%p) Failed to enumerate directory Status %08lX\n",
1855 try_return( ntStatus);
1858 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1862 // If the root fcb has been initialized then check access otherwise
1863 // init the volume fcb
1866 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1869 if( !NT_SUCCESS( ntStatus))
1872 try_return( ntStatus);
1875 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1877 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1878 AFS_TRACE_LEVEL_VERBOSE,
1879 "AFSOpenRoot Increment count on Fcb %p Cnt %d\n",
1886 // If there are current opens on the Fcb, check the access.
1889 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1892 ntStatus = IoCheckShareAccess( *pDesiredAccess,
1895 &VolumeCB->RootFcb->ShareAccess,
1898 if( !NT_SUCCESS( ntStatus))
1901 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1902 AFS_TRACE_LEVEL_ERROR,
1903 "AFSOpenRoot (%p) Access check failure Status %08lX\n",
1907 try_return( ntStatus);
1912 // Initialize the Ccb for the file.
1915 ntStatus = AFSInitCcb( Ccb,
1916 VolumeCB->DirectoryCB,
1920 if( !NT_SUCCESS( ntStatus))
1923 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1924 AFS_TRACE_LEVEL_ERROR,
1925 "AFSOpenRoot (%p) Failed to allocate Ccb Status %08lX\n",
1929 try_return( ntStatus);
1932 bAllocatedCcb = TRUE;
1935 // OK, update the share access on the fileobject
1938 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1941 IoUpdateShareAccess( pFileObject,
1942 &VolumeCB->RootFcb->ShareAccess);
1951 IoSetShareAccess( *pDesiredAccess,
1954 &VolumeCB->RootFcb->ShareAccess);
1958 // Increment the open count on this Fcb
1961 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1963 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1964 AFS_TRACE_LEVEL_VERBOSE,
1965 "AFSOpenRoot Increment handle count on Fcb %p Cnt %d\n",
1970 // Indicate the object is held
1973 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1976 // Return the open result for this file
1979 Irp->IoStatus.Information = FILE_OPENED;
1981 *RootFcb = VolumeCB->RootFcb;
1987 if ( !NT_SUCCESS( ntStatus))
1990 lCount = InterlockedDecrement( &VolumeCB->RootFcb->OpenReferenceCount);
1992 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1993 AFS_TRACE_LEVEL_VERBOSE,
1994 "AFSOpenRoot Decrement count on Fcb %p Cnt %d\n",
1999 AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
2002 if( !NT_SUCCESS( ntStatus))
2014 Irp->IoStatus.Information = 0;
2022 AFSProcessCreate( IN PIRP Irp,
2024 IN AFSVolumeCB *VolumeCB,
2025 IN AFSDirectoryCB *ParentDirCB,
2026 IN PUNICODE_STRING FileName,
2027 IN PUNICODE_STRING ComponentName,
2028 IN PUNICODE_STRING FullFileName,
2033 NTSTATUS ntStatus = STATUS_SUCCESS;
2034 PFILE_OBJECT pFileObject = NULL;
2035 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2036 ULONG ulOptions = 0;
2037 ULONG ulAttributes = 0;
2038 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
2039 PACCESS_MASK pDesiredAccess = NULL;
2040 USHORT usShareAccess;
2041 AFSDirectoryCB *pDirEntry = NULL;
2042 AFSObjectInfoCB *pParentObjectInfo = NULL;
2043 AFSObjectInfoCB *pObjectInfo = NULL;
2049 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2050 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2052 pFileObject = pIrpSp->FileObject;
2055 // Extract out the options
2058 ulOptions = pIrpSp->Parameters.Create.Options;
2061 // We pass all attributes they want to apply to the file to the create
2064 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
2067 // If this is a directory create then set the attribute correctly
2070 if( ulOptions & FILE_DIRECTORY_FILE)
2073 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
2076 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2077 AFS_TRACE_LEVEL_VERBOSE,
2078 "AFSProcessCreate (%p) Creating file %wZ Attributes %08lX\n",
2083 if( BooleanFlagOn( VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
2086 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2087 AFS_TRACE_LEVEL_ERROR,
2088 "AFSProcessCreate Request failed due to read only volume %wZ\n",
2091 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
2094 pParentObjectInfo = ParentDirCB->ObjectInformation;
2097 // Allocate and insert the direntry into the parent node
2100 ntStatus = AFSCreateDirEntry( AuthGroup,
2108 if( !NT_SUCCESS( ntStatus))
2111 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2112 AFS_TRACE_LEVEL_ERROR,
2113 "AFSProcessCreate (%p) Failed to create directory entry %wZ Status %08lX\n",
2118 try_return( ntStatus);
2121 bFileCreated = TRUE;
2123 pObjectInfo = pDirEntry->ObjectInformation;
2125 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
2126 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
2129 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2130 AFS_TRACE_LEVEL_VERBOSE,
2131 "AFSProcessCreate (%p) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
2133 &pDirEntry->NameInformation.FileName,
2134 pObjectInfo->FileId.Cell,
2135 pObjectInfo->FileId.Volume,
2136 pObjectInfo->FileId.Vnode,
2137 pObjectInfo->FileId.Unique));
2139 ntStatus = AFSEvaluateNode( AuthGroup,
2142 if( !NT_SUCCESS( ntStatus))
2145 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
2148 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2151 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2152 AFS_TRACE_LEVEL_ERROR,
2153 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
2155 &pDirEntry->NameInformation.FileName,
2156 pObjectInfo->FileId.Cell,
2157 pObjectInfo->FileId.Volume,
2158 pObjectInfo->FileId.Vnode,
2159 pObjectInfo->FileId.Unique,
2160 pParentObjectInfo->FileId.Cell,
2161 pParentObjectInfo->FileId.Volume,
2162 pParentObjectInfo->FileId.Vnode,
2163 pParentObjectInfo->FileId.Unique,
2166 else if ( AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId))
2169 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2170 AFS_TRACE_LEVEL_ERROR,
2171 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2173 &pDirEntry->NameInformation.FileName,
2174 pObjectInfo->FileId.Cell,
2175 pObjectInfo->FileId.Volume,
2176 pObjectInfo->FileId.Vnode,
2177 pObjectInfo->FileId.Unique,
2178 pParentObjectInfo->FileId.Cell,
2179 pParentObjectInfo->FileId.Volume,
2180 pParentObjectInfo->FileId.Vnode,
2181 pParentObjectInfo->FileId.Unique,
2187 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2188 AFS_TRACE_LEVEL_ERROR,
2189 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2191 &pDirEntry->NameInformation.FileName,
2192 pObjectInfo->FileId.Cell,
2193 pObjectInfo->FileId.Volume,
2194 pObjectInfo->FileId.Vnode,
2195 pObjectInfo->FileId.Unique,
2196 pParentObjectInfo->FileId.Cell,
2197 pParentObjectInfo->FileId.Volume,
2198 pParentObjectInfo->FileId.Vnode,
2199 pParentObjectInfo->FileId.Unique,
2200 pObjectInfo->ParentFileId.Cell,
2201 pObjectInfo->ParentFileId.Volume,
2202 pObjectInfo->ParentFileId.Vnode,
2203 pObjectInfo->ParentFileId.Unique,
2210 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2211 AFS_TRACE_LEVEL_ERROR,
2212 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
2214 &pDirEntry->NameInformation.FileName,
2215 pObjectInfo->FileId.Cell,
2216 pObjectInfo->FileId.Volume,
2217 pObjectInfo->FileId.Vnode,
2218 pObjectInfo->FileId.Unique,
2222 try_return( ntStatus);
2225 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
2228 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2229 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
2232 // We may have raced and the Fcb is already created
2236 // Allocate and initialize the Fcb for the file.
2239 ntStatus = AFSInitFcb( pDirEntry);
2241 *Fcb = pObjectInfo->Fcb;
2243 if( !NT_SUCCESS( ntStatus))
2246 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2247 AFS_TRACE_LEVEL_ERROR,
2248 "AFSProcessCreate (%p) Failed to initialize fcb %wZ Status %08lX\n",
2253 try_return( ntStatus);
2256 ntStatus = STATUS_SUCCESS;
2259 // Increment the open count on this Fcb
2262 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
2264 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2265 AFS_TRACE_LEVEL_VERBOSE,
2266 "AFSProcessCreate Increment count on Fcb %p Cnt %d\n",
2273 // Initialize the Ccb for the file.
2276 ntStatus = AFSInitCcb( Ccb,
2281 if( !NT_SUCCESS( ntStatus))
2284 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2285 AFS_TRACE_LEVEL_ERROR,
2286 "AFSProcessCreate (%p) Failed to initialize ccb %wZ Status %08lX\n",
2291 try_return( ntStatus);
2294 bAllocatedCcb = TRUE;
2297 // If this is a file, update the headers filesizes.
2300 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
2304 // Update the sizes with the information passed in
2307 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2308 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2309 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2312 // Notify the system of the addition
2315 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2317 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
2318 (ULONG)FILE_ACTION_ADDED);
2320 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2322 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2326 // This is a new directory node so indicate it has been enumerated
2329 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
2332 // And the parent directory entry
2335 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2338 // Notify the system of the addition
2341 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2343 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2344 (ULONG)FILE_ACTION_ADDED);
2346 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2347 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2348 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2349 (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
2353 // And the parent directory entry
2356 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2359 // Notify the system of the addition
2362 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2364 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2365 (ULONG)FILE_ACTION_ADDED);
2369 // Save off the access for the open
2372 IoSetShareAccess( *pDesiredAccess,
2375 &(*Fcb)->ShareAccess);
2377 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2379 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2380 AFS_TRACE_LEVEL_VERBOSE,
2381 "AFSProcessCreate Increment handle count on Fcb %p Cnt %d\n",
2386 // Increment the open reference and handle on the parent node
2389 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2391 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2392 AFS_TRACE_LEVEL_VERBOSE,
2393 "AFSProcessCreate Increment child open handle count on Parent object %p Cnt %d\n",
2397 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2399 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2400 AFS_TRACE_LEVEL_VERBOSE,
2401 "AFSProcessCreate Increment child open ref count on Parent object %p Cnt %d\n",
2405 if( ulOptions & FILE_DELETE_ON_CLOSE)
2409 // Mark it for delete on close
2412 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2413 AFS_TRACE_LEVEL_VERBOSE,
2414 "AFSProcessCreate (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2419 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2423 // Indicate the object is locked in the service
2426 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2429 // Return the open result for this file
2432 Irp->IoStatus.Information = FILE_CREATED;
2437 // If we created the Fcb we need to release the resources
2443 if( !NT_SUCCESS( ntStatus))
2446 // Decrement the open count on this Fcb
2449 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2451 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2452 AFS_TRACE_LEVEL_VERBOSE,
2453 "AFSProcessCreate Decrement count on Fcb %p Cnt %d\n",
2458 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2465 // Decrement the reference added during initialization of the DE
2466 // AFSInitCcb allocates its own reference count.
2469 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2471 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2472 AFS_TRACE_LEVEL_VERBOSE,
2473 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2474 &pDirEntry->NameInformation.FileName,
2478 ASSERT( lCount >= 0);
2481 if( !NT_SUCCESS( ntStatus))
2487 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2488 AFS_TRACE_LEVEL_VERBOSE,
2489 "AFSProcessCreate Create failed, removing DE %p from parent object %p Status %08lX\n",
2495 // Remove the dir entry from the parent
2498 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2501 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2503 AFSNotifyDelete( pDirEntry,
2508 // Pull the directory entry from the parent
2511 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2513 FALSE); // Leave it in the enum list so the worker cleans it up
2516 // Tag the parent as needing verification
2519 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2521 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2523 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2534 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2547 AFSOpenTargetDirectory( IN PIRP Irp,
2548 IN AFSVolumeCB *VolumeCB,
2549 IN AFSDirectoryCB *ParentDirectoryCB,
2550 IN AFSDirectoryCB *TargetDirectoryCB,
2551 IN UNICODE_STRING *TargetName,
2555 UNREFERENCED_PARAMETER(VolumeCB);
2556 NTSTATUS ntStatus = STATUS_SUCCESS;
2557 PFILE_OBJECT pFileObject = NULL;
2558 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2559 PACCESS_MASK pDesiredAccess = NULL;
2560 USHORT usShareAccess;
2561 BOOLEAN bAllocatedCcb = FALSE;
2562 BOOLEAN bReleaseFcb = FALSE;
2563 AFSObjectInfoCB *pParentObject = NULL;
2564 AFSObjectInfoCB *pGrandParentObject = NULL;
2565 UNICODE_STRING uniTargetName;
2571 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2572 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2574 pFileObject = pIrpSp->FileObject;
2576 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2577 AFS_TRACE_LEVEL_VERBOSE,
2578 "AFSOpenTargetDirectory (%p) Processing file %wZ\n",
2582 pParentObject = ParentDirectoryCB->ObjectInformation;
2584 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2587 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2591 // Make sure we have an Fcb for the access
2594 // Allocate and initialize the Fcb for the file.
2597 ntStatus = AFSInitFcb( ParentDirectoryCB);
2599 *Fcb = pParentObject->Fcb;
2601 if( !NT_SUCCESS( ntStatus))
2604 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2605 AFS_TRACE_LEVEL_ERROR,
2606 "AFSOpenTargetDirectory (%p) Failed to initialize fcb %wZ Status %08lX\n",
2608 &ParentDirectoryCB->NameInformation.FileName,
2611 try_return( ntStatus);
2614 ntStatus = STATUS_SUCCESS;
2617 // Increment the open count on this Fcb
2620 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2622 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2623 AFS_TRACE_LEVEL_VERBOSE,
2624 "AFSOpenTargetDirectory Increment count on Fcb %p Cnt %d\n",
2631 // If there are current opens on the Fcb, check the access.
2634 if( pParentObject->Fcb->OpenHandleCount > 0)
2637 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2640 &pParentObject->Fcb->ShareAccess,
2643 if( !NT_SUCCESS( ntStatus))
2646 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2647 AFS_TRACE_LEVEL_ERROR,
2648 "AFSOpenTargetDirectory (%p) Access check failure %wZ Status %08lX\n",
2650 &ParentDirectoryCB->NameInformation.FileName,
2653 try_return( ntStatus);
2658 // Initialize the Ccb for the file.
2661 ntStatus = AFSInitCcb( Ccb,
2666 if( !NT_SUCCESS( ntStatus))
2669 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2670 AFS_TRACE_LEVEL_ERROR,
2671 "AFSOpenTargetDirectory (%p) Failed to initialize ccb %wZ Status %08lX\n",
2673 &ParentDirectoryCB->NameInformation.FileName,
2676 try_return( ntStatus);
2679 bAllocatedCcb = TRUE;
2681 if( TargetDirectoryCB != NULL &&
2682 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2688 Irp->IoStatus.Information = FILE_EXISTS;
2690 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2695 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2697 uniTargetName = *TargetName;
2701 // Update the filename in the fileobject for rename processing
2704 RtlCopyMemory( pFileObject->FileName.Buffer,
2705 uniTargetName.Buffer,
2706 uniTargetName.Length);
2708 pFileObject->FileName.Length = uniTargetName.Length;
2711 // OK, update the share access on the fileobject
2714 if( pParentObject->Fcb->OpenHandleCount > 0)
2717 IoUpdateShareAccess( pFileObject,
2718 &pParentObject->Fcb->ShareAccess);
2727 IoSetShareAccess( *pDesiredAccess,
2730 &pParentObject->Fcb->ShareAccess);
2733 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2735 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2736 AFS_TRACE_LEVEL_VERBOSE,
2737 "AFSOpenTargetDirectory Increment handle count on Fcb %p Cnt %d\n",
2742 // Increment the open reference and handle on the parent node
2745 if( BooleanFlagOn( pParentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2748 pGrandParentObject = AFSFindObjectInfo( pParentObject->VolumeCB,
2749 &pParentObject->ParentFileId,
2752 if ( pGrandParentObject)
2755 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenHandleCount);
2757 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2758 AFS_TRACE_LEVEL_VERBOSE,
2759 "AFSOpenTargetDirectory Increment child open handle count on Parent object %p Cnt %d\n",
2763 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenReferenceCount);
2765 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2766 AFS_TRACE_LEVEL_VERBOSE,
2767 "AFSOpenTargetDirectory Increment child open ref count on Parent object %p Cnt %d\n",
2771 AFSReleaseObjectInfo( &pGrandParentObject);
2780 if( !NT_SUCCESS( ntStatus))
2783 // Decrement the open count on this Fcb
2786 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2788 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2789 AFS_TRACE_LEVEL_VERBOSE,
2790 "AFSOpenTargetDirectory Decrement count on Fcb %p Cnt %d\n",
2795 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2798 if( !NT_SUCCESS( ntStatus))
2811 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2822 AFSProcessOpen( IN PIRP Irp,
2824 IN AFSVolumeCB *VolumeCB,
2825 IN AFSDirectoryCB *ParentDirCB,
2826 IN AFSDirectoryCB *DirectoryCB,
2830 UNREFERENCED_PARAMETER(VolumeCB);
2831 NTSTATUS ntStatus = STATUS_SUCCESS;
2832 PFILE_OBJECT pFileObject = NULL;
2833 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2834 PACCESS_MASK pDesiredAccess = NULL;
2835 USHORT usShareAccess;
2836 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE;
2837 ULONG ulOptions = 0;
2838 AFSFileOpenCB stOpenCB;
2839 AFSFileOpenResultCB stOpenResultCB;
2840 ULONG ulResultLen = 0;
2841 AFSObjectInfoCB *pParentObjectInfo = NULL;
2842 AFSObjectInfoCB *pObjectInfo = NULL;
2843 ULONG ulFileAccess = 0;
2844 AFSFileAccessReleaseCB stReleaseFileAccess;
2850 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2851 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2853 pFileObject = pIrpSp->FileObject;
2855 pParentObjectInfo = ParentDirCB->ObjectInformation;
2857 pObjectInfo = DirectoryCB->ObjectInformation;
2859 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2860 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
2863 // Check if the entry is pending a deletion
2866 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2869 ntStatus = STATUS_DELETE_PENDING;
2871 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2872 AFS_TRACE_LEVEL_ERROR,
2873 "AFSProcessOpen (%p) Entry pending delete %wZ Status %08lX\n",
2875 &DirectoryCB->NameInformation.FileName,
2878 try_return( ntStatus);
2882 // Extract out the options
2885 ulOptions = pIrpSp->Parameters.Create.Options;
2888 // Check if we should go and retrieve updated information for the node
2891 ntStatus = AFSValidateEntry( DirectoryCB,
2896 if( !NT_SUCCESS( ntStatus))
2899 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2900 AFS_TRACE_LEVEL_ERROR,
2901 "AFSProcessOpen (%p) Failed to validate entry %wZ Status %08lX\n",
2903 &DirectoryCB->NameInformation.FileName,
2906 try_return( ntStatus);
2910 // If this is marked for delete on close then be sure we can delete the entry
2913 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2916 ntStatus = AFSNotifyDelete( DirectoryCB,
2920 if( !NT_SUCCESS( ntStatus))
2923 ntStatus = STATUS_CANNOT_DELETE;
2925 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2926 AFS_TRACE_LEVEL_ERROR,
2927 "AFSProcessOpen (%p) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2929 &DirectoryCB->NameInformation.FileName,
2932 try_return( ntStatus);
2937 // Be sure we have an Fcb for the current object
2940 ntStatus = AFSInitFcb( DirectoryCB);
2942 if( !NT_SUCCESS( ntStatus))
2945 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2946 AFS_TRACE_LEVEL_ERROR,
2947 "AFSProcessOpen (%p) Failed to init fcb on %wZ Status %08lX\n",
2949 &DirectoryCB->NameInformation.FileName,
2952 try_return( ntStatus);
2955 ntStatus = STATUS_SUCCESS;
2958 // AFSInitFcb returns the Fcb resource held
2964 // Increment the open count on this Fcb
2967 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2969 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2970 AFS_TRACE_LEVEL_VERBOSE,
2971 "AFSProcessOpen Increment2 count on Fcb %p Cnt %d\n",
2976 // Check access on the entry
2979 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2982 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2985 &pObjectInfo->Fcb->ShareAccess,
2988 if( !NT_SUCCESS( ntStatus))
2991 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2992 AFS_TRACE_LEVEL_ERROR,
2993 "AFSProcessOpen (%p) Failed to check share access on %wZ Status %08lX\n",
2995 &DirectoryCB->NameInformation.FileName,
2998 try_return( ntStatus);
3003 // Additional checks
3006 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
3010 // If the caller is asking for write access then try to flush the image section
3013 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
3014 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
3019 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3020 AFS_TRACE_LEVEL_VERBOSE,
3021 "AFSProcessOpen Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3022 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3023 PsGetCurrentThread()));
3025 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3028 bMmFlushed = MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3031 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3032 AFS_TRACE_LEVEL_VERBOSE,
3033 "AFSProcessOpen Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3034 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3035 PsGetCurrentThread()));
3037 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3042 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
3043 STATUS_SHARING_VIOLATION;
3045 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3046 AFS_TRACE_LEVEL_ERROR,
3047 "AFSProcessOpen (%p) Failed to flush image section %wZ Status %08lX\n",
3049 &DirectoryCB->NameInformation.FileName,
3052 try_return( ntStatus);
3056 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
3059 ntStatus = STATUS_NOT_A_DIRECTORY;
3061 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3062 AFS_TRACE_LEVEL_ERROR,
3063 "AFSProcessOpen (%p) Attempt to open file as directory %wZ Status %08lX\n",
3065 &DirectoryCB->NameInformation.FileName,
3068 try_return( ntStatus);
3071 pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
3073 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
3074 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
3077 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
3080 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
3082 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3083 AFS_TRACE_LEVEL_ERROR,
3084 "AFSProcessOpen (%p) Attempt to open directory as file %wZ Status %08lX\n",
3086 &DirectoryCB->NameInformation.FileName,
3089 try_return( ntStatus);
3092 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
3093 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
3094 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
3095 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
3102 try_return( ntStatus = STATUS_UNSUCCESSFUL);
3106 // Check with the service that we can open the file
3109 stOpenCB.ParentId = pParentObjectInfo->FileId;
3111 stOpenCB.DesiredAccess = *pDesiredAccess;
3113 stOpenCB.ShareAccess = usShareAccess;
3115 stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
3117 stOpenCB.Identifier = (ULONGLONG)pFileObject;
3119 stOpenResultCB.GrantedAccess = 0;
3121 ulResultLen = sizeof( AFSFileOpenResultCB);
3123 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
3124 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
3126 &DirectoryCB->NameInformation.FileName,
3127 &pObjectInfo->FileId,
3128 pObjectInfo->VolumeCB->VolumeInformation.Cell,
3129 pObjectInfo->VolumeCB->VolumeInformation.CellLength,
3131 sizeof( AFSFileOpenCB),
3132 (void *)&stOpenResultCB,
3135 if( !NT_SUCCESS( ntStatus))
3138 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3139 AFS_TRACE_LEVEL_ERROR,
3140 "AFSProcessOpen (%p) Failed open in service %wZ Status %08lX\n",
3142 &DirectoryCB->NameInformation.FileName,
3145 try_return( ntStatus);
3149 // Save the granted access in case we need to release it below
3152 ulFileAccess = stOpenResultCB.FileAccess;
3155 // Check if there is a conflict
3158 if( !AFSCheckAccess( *pDesiredAccess,
3159 stOpenResultCB.GrantedAccess,
3160 BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
3163 ntStatus = STATUS_ACCESS_DENIED;
3165 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3166 AFS_TRACE_LEVEL_ERROR,
3167 "AFSProcessOpen (%p) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
3170 stOpenResultCB.GrantedAccess,
3171 &DirectoryCB->NameInformation.FileName,
3174 try_return( ntStatus);
3178 // Initialize the Ccb for the file.
3181 ntStatus = AFSInitCcb( Ccb,
3186 if( !NT_SUCCESS( ntStatus))
3189 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3190 AFS_TRACE_LEVEL_ERROR,
3191 "AFSProcessOpen (%p) Failed to initialize ccb %wZ Status %08lX\n",
3193 &DirectoryCB->NameInformation.FileName,
3196 try_return( ntStatus);
3199 bAllocatedCcb = TRUE;
3202 // Perform the access check on the target if this is a mount point or symlink
3205 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3208 IoUpdateShareAccess( pFileObject,
3209 &pObjectInfo->Fcb->ShareAccess);
3218 IoSetShareAccess( *pDesiredAccess,
3221 &pObjectInfo->Fcb->ShareAccess);
3224 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
3226 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3227 AFS_TRACE_LEVEL_VERBOSE,
3228 "AFSProcessOpen Increment handle count on Fcb %p Cnt %d\n",
3233 // Increment the open reference and handle on the parent node
3236 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3238 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3239 AFS_TRACE_LEVEL_VERBOSE,
3240 "AFSProcessOpen Increment child open handle count on Parent object %p Cnt %d\n",
3244 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3246 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3247 AFS_TRACE_LEVEL_VERBOSE,
3248 "AFSProcessOpen Increment child open ref count on Parent object %p Cnt %d\n",
3252 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
3256 // Mark it for delete on close
3259 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3260 AFS_TRACE_LEVEL_VERBOSE,
3261 "AFSProcessOpen (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
3264 &DirectoryCB->NameInformation.FileName));
3266 SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
3270 // Indicate the object is held
3273 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
3276 // Return the open result for this file
3279 Irp->IoStatus.Information = FILE_OPENED;
3281 *Fcb = pObjectInfo->Fcb;
3288 if( !NT_SUCCESS( ntStatus))
3291 // Decrement the open count on this Fcb
3294 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
3296 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3297 AFS_TRACE_LEVEL_VERBOSE,
3298 "AFSProcessOpen Decrement2 count on Fcb %p Cnt %d\n",
3303 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3306 if( !NT_SUCCESS( ntStatus))
3309 if ( ulFileAccess > 0)
3312 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
3314 stReleaseFileAccess.FileAccess = ulFileAccess;
3316 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
3318 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
3319 AFS_REQUEST_FLAG_SYNCHRONOUS,
3321 &DirectoryCB->NameInformation.FileName,
3322 &pObjectInfo->FileId,
3323 pObjectInfo->VolumeCB->VolumeInformation.Cell,
3324 pObjectInfo->VolumeCB->VolumeInformation.CellLength,
3325 (void *)&stReleaseFileAccess,
3326 sizeof( AFSFileAccessReleaseCB),
3341 // Fcb will be freed by AFSPrimaryVolumeWorker thread
3352 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
3354 IN AFSVolumeCB *VolumeCB,
3356 IN AFSDirectoryCB *ParentDirCB,
3357 IN AFSDirectoryCB *DirectoryCB,
3361 UNREFERENCED_PARAMETER(DeviceObject);
3362 NTSTATUS ntStatus = STATUS_SUCCESS;
3363 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3364 PFILE_OBJECT pFileObject = NULL;
3365 LARGE_INTEGER liZero = {0,0};
3366 BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
3367 ULONG ulAttributes = 0;
3368 ULONG ulCreateDisposition = 0;
3369 BOOLEAN bAllocatedCcb = FALSE;
3370 BOOLEAN bUserMapped = FALSE;
3371 PACCESS_MASK pDesiredAccess = NULL;
3372 USHORT usShareAccess;
3373 AFSObjectInfoCB *pParentObjectInfo = NULL;
3374 AFSObjectInfoCB *pObjectInfo = NULL;
3376 LARGE_INTEGER liSaveSize;
3377 LARGE_INTEGER liSaveVDL;
3378 LARGE_INTEGER liSaveAlloc;
3383 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3385 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
3387 pFileObject = pIrpSp->FileObject;
3389 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
3391 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
3393 if( BooleanFlagOn( VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
3396 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3397 AFS_TRACE_LEVEL_ERROR,
3398 "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3400 &DirectoryCB->NameInformation.FileName));
3402 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3405 pParentObjectInfo = ParentDirCB->ObjectInformation;
3407 pObjectInfo = DirectoryCB->ObjectInformation;
3409 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3410 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
3413 // Check if we should go and retrieve updated information for the node
3416 ntStatus = AFSValidateEntry( DirectoryCB,
3421 if( !NT_SUCCESS( ntStatus))
3424 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3425 AFS_TRACE_LEVEL_ERROR,
3426 "AFSProcessOverwriteSupersede (%p) Failed to validate entry %wZ Status %08lX\n",
3428 &DirectoryCB->NameInformation.FileName,
3431 try_return( ntStatus);
3435 // Be sure we have an Fcb for the object block
3438 ntStatus = AFSInitFcb( DirectoryCB);
3440 *Fcb = pObjectInfo->Fcb;
3442 if( !NT_SUCCESS( ntStatus))
3445 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3446 AFS_TRACE_LEVEL_ERROR,
3447 "AFSProcessOverwriteSupersede (%p) Failed to initialize fcb %wZ Status %08lX\n",
3449 &DirectoryCB->NameInformation.FileName,
3452 try_return( ntStatus);
3455 ntStatus = STATUS_SUCCESS;
3458 // Increment the open count on this Fcb.
3461 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3463 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3464 AFS_TRACE_LEVEL_VERBOSE,
3465 "AFSProcessOverwriteSupersede Increment2 count on Fcb %p Cnt %d\n",
3472 // Check access on the entry
3475 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3478 ntStatus = IoCheckShareAccess( *pDesiredAccess,
3481 &pObjectInfo->Fcb->ShareAccess,
3484 if( !NT_SUCCESS( ntStatus))
3487 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3488 AFS_TRACE_LEVEL_ERROR,
3489 "AFSProcessOverwriteSupersede (%p) Access check failure %wZ Status %08lX\n",
3491 &DirectoryCB->NameInformation.FileName,
3494 try_return( ntStatus);
3498 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3499 AFS_TRACE_LEVEL_VERBOSE,
3500 "AFSProcessOverwriteSupercede Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3501 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3502 PsGetCurrentThread()));
3504 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3508 // Before we actually truncate, check to see if the purge
3509 // is going to fail.
3512 bUserMapped = !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3515 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3516 AFS_TRACE_LEVEL_VERBOSE,
3517 "AFSProcessOverwriteSupercede Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3518 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3519 PsGetCurrentThread()));
3521 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3526 ntStatus = STATUS_USER_MAPPED_FILE;
3528 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3529 AFS_TRACE_LEVEL_ERROR,
3530 "AFSProcessOverwriteSupersede (%p) File user mapped %wZ Status %08lX\n",
3532 &DirectoryCB->NameInformation.FileName,
3535 try_return( ntStatus);
3539 // Initialize the Ccb for the file.
3542 ntStatus = AFSInitCcb( Ccb,
3547 if( !NT_SUCCESS( ntStatus))
3550 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3551 AFS_TRACE_LEVEL_ERROR,
3552 "AFSProcessOverwriteSupersede (%p) Failed to initialize ccb %wZ Status %08lX\n",
3554 &DirectoryCB->NameInformation.FileName,
3557 try_return( ntStatus);
3560 bAllocatedCcb = TRUE;
3563 // Set the file length to zero
3566 AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3569 bReleasePaging = TRUE;
3571 liSaveSize = pObjectInfo->Fcb->Header.FileSize;
3572 liSaveAlloc = pObjectInfo->Fcb->Header.AllocationSize;
3573 liSaveVDL = pObjectInfo->Fcb->Header.ValidDataLength;
3575 pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3576 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3577 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3579 pObjectInfo->EndOfFile.QuadPart = 0;
3580 pObjectInfo->AllocationSize.QuadPart = 0;
3583 // Trim down the extents. We do this BEFORE telling the service
3584 // the file is truncated since there is a potential race between
3585 // a worker thread releasing extents and us trimming
3588 AFSTrimExtents( pObjectInfo->Fcb,
3589 &pObjectInfo->Fcb->Header.FileSize);
3591 KeQuerySystemTime( &pObjectInfo->ChangeTime);
3593 KeQuerySystemTime( &pObjectInfo->LastAccessTime);
3595 KeQuerySystemTime( &pObjectInfo->LastWriteTime);
3598 // Set the update flag accordingly
3601 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
3602 AFS_FCB_FLAG_UPDATE_CREATE_TIME |
3603 AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
3604 AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
3605 AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
3607 ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
3611 if( !NT_SUCCESS( ntStatus))
3614 pObjectInfo->Fcb->Header.ValidDataLength = liSaveVDL;
3615 pObjectInfo->Fcb->Header.FileSize = liSaveSize;
3616 pObjectInfo->Fcb->Header.AllocationSize = liSaveAlloc;
3617 pObjectInfo->Fcb->ObjectInformation->EndOfFile = liSaveSize;
3618 pObjectInfo->Fcb->ObjectInformation->AllocationSize = liSaveAlloc;
3620 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3621 AFS_TRACE_LEVEL_ERROR,
3622 "AFSProcessOverwriteSupersede (%p) Failed to update file information %wZ Status %08lX\n",
3624 &DirectoryCB->NameInformation.FileName,
3627 try_return( ntStatus);
3630 ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
3632 if( ulCreateDisposition == FILE_SUPERSEDE)
3635 pObjectInfo->FileAttributes = ulAttributes;
3641 pObjectInfo->FileAttributes |= ulAttributes;
3645 // Save off the access for the open
3648 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3651 IoUpdateShareAccess( pFileObject,
3652 &pObjectInfo->Fcb->ShareAccess);
3661 IoSetShareAccess( *pDesiredAccess,
3664 &pObjectInfo->Fcb->ShareAccess);
3668 // Return the correct action
3671 if( ulCreateDisposition == FILE_SUPERSEDE)
3674 Irp->IoStatus.Information = FILE_SUPERSEDED;
3679 Irp->IoStatus.Information = FILE_OVERWRITTEN;
3682 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
3684 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3685 AFS_TRACE_LEVEL_VERBOSE,
3686 "AFSProcessOverwriteSupersede Increment handle count on Fcb %p Cnt %d\n",
3691 // Increment the open reference and handle on the parent node
3694 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3696 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3697 AFS_TRACE_LEVEL_VERBOSE,
3698 "AFSProcessOverwriteSupersede Increment child open handle count on Parent object %p Cnt %d\n",
3702 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3704 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3705 AFS_TRACE_LEVEL_VERBOSE,
3706 "AFSProcessOverwriteSupersede Increment child open ref count on Parent object %p Cnt %d\n",
3710 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3712 bReleaseFcb = FALSE;
3714 *Fcb = pObjectInfo->Fcb;
3717 // Now that the Fcb->Resource has been dropped
3718 // we can call CcSetFileSizes. We are still holding
3719 // the PagingIoResource
3722 pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
3724 pFileObject->FsContext = (void *)pObjectInfo->Fcb;
3726 pFileObject->FsContext2 = (void *)*Ccb;
3728 CcSetFileSizes( pFileObject,
3729 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3736 AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3742 if( !NT_SUCCESS( ntStatus))
3745 // Decrement the open count on this Fcb.
3748 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
3750 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3751 AFS_TRACE_LEVEL_VERBOSE,
3752 "AFSProcessOverwriteSupersede Decrement2 count on Fcb %p Cnt %d\n",
3757 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3760 if( !NT_SUCCESS( ntStatus))
3773 // Fcb will be freed by AFSPrimaryVolumeWorker thread
3784 AFSControlDeviceCreate( IN PIRP Irp)
3787 NTSTATUS ntStatus = STATUS_SUCCESS;
3792 if ( KernelMode == Irp->RequestorMode) {
3794 // For now, just let the open happen
3796 Irp->IoStatus.Information = FILE_OPENED;
3801 // Not from usermode, All access must be via
3802 // the FS component (which will do the
3805 ntStatus = STATUS_ACCESS_DENIED;
3813 // AFSOpenIOCtlFcb does not release a DirOpenReferenceCount on
3818 AFSOpenIOCtlFcb( IN PIRP Irp,
3820 IN AFSDirectoryCB *ParentDirCB,
3825 NTSTATUS ntStatus = STATUS_SUCCESS;
3826 PFILE_OBJECT pFileObject = NULL;
3827 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3828 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
3829 AFSPIOCtlOpenCloseRequestCB stPIOCtlOpen;
3831 AFSObjectInfoCB *pParentObjectInfo = NULL;
3837 pFileObject = pIrpSp->FileObject;
3839 pParentObjectInfo = ParentDirCB->ObjectInformation;
3842 // If we haven't initialized the PIOCtl DirectoryCB for this directory then do it now
3845 if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB == NULL)
3848 ntStatus = AFSInitPIOCtlDirectoryCB( pParentObjectInfo);
3850 if( !NT_SUCCESS( ntStatus))
3853 try_return( ntStatus);
3858 // Allocate and initialize the Fcb for the file.
3861 ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB);
3863 *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
3865 if( !NT_SUCCESS( ntStatus))
3868 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3869 AFS_TRACE_LEVEL_ERROR,
3870 "AFSOpenIOCtlFcb (%p) Failed to initialize fcb Status %08lX\n",
3874 try_return( ntStatus);
3877 ntStatus = STATUS_SUCCESS;
3880 // Increment the open reference and handle on the node
3883 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3885 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3886 AFS_TRACE_LEVEL_VERBOSE,
3887 "AFSOpenIOCtlFcb Increment count on Fcb %p Cnt %d\n",
3894 // Initialize the Ccb for the file.
3897 ntStatus = AFSInitCcb( Ccb,
3898 pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
3902 if( !NT_SUCCESS( ntStatus))
3905 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3906 AFS_TRACE_LEVEL_ERROR,
3907 "AFSOpenIOCtlFcb (%p) Failed to initialize ccb Status %08lX\n",
3911 try_return( ntStatus);
3914 bAllocatedCcb = TRUE;
3917 // Set the PIOCtl index
3920 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3922 RtlZeroMemory( &stPIOCtlOpen,
3923 sizeof( AFSPIOCtlOpenCloseRequestCB));
3925 stPIOCtlOpen.RequestId = (*Ccb)->RequestID;
3927 stPIOCtlOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3929 RtlZeroMemory( &stFileID,
3930 sizeof( AFSFileID));
3933 // The parent directory FID of the node
3936 stFileID = pParentObjectInfo->FileId;
3939 // Issue the open request to the service
3942 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_OPEN,
3943 AFS_REQUEST_FLAG_SYNCHRONOUS,
3949 (void *)&stPIOCtlOpen,
3950 sizeof( AFSPIOCtlOpenCloseRequestCB),
3954 if( !NT_SUCCESS( ntStatus))
3957 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3958 AFS_TRACE_LEVEL_ERROR,
3959 "AFSOpenIOCtlFcb (%p) Failed service open Status %08lX\n",
3963 try_return( ntStatus);
3967 // Increment the handle on the node
3970 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3972 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3973 AFS_TRACE_LEVEL_VERBOSE,
3974 "AFSOpenIOCtlFcb Increment handle count on Fcb %p Cnt %d\n",
3979 // Increment the open reference and handle on the parent node
3982 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3984 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3985 AFS_TRACE_LEVEL_VERBOSE,
3986 "AFSOpenIOCtlFcb Increment child open handle count on Parent object %p Cnt %d\n",
3990 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3992 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3993 AFS_TRACE_LEVEL_VERBOSE,
3994 "AFSOpenIOCtlFcb Increment child open ref count on Parent object %p Cnt %d\n",
3999 // Return the open result for this file
4002 Irp->IoStatus.Information = FILE_OPENED;
4007 // If we created the Fcb we need to release the resources
4013 if( !NT_SUCCESS( ntStatus))
4016 // Decrement the open reference and handle on the node
4019 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
4021 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
4022 AFS_TRACE_LEVEL_VERBOSE,
4023 "AFSOpenIOCtlFcb Decrement count on Fcb %p Cnt %d\n",
4028 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
4031 if( !NT_SUCCESS( ntStatus))
4044 // Fcb will be freed by AFSPrimaryVolumeWorker thread
4055 AFSOpenSpecialShareFcb( IN PIRP Irp,
4057 IN AFSDirectoryCB *DirectoryCB,
4062 NTSTATUS ntStatus = STATUS_SUCCESS;
4063 PFILE_OBJECT pFileObject = NULL;
4064 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
4065 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE, bAllocateFcb = FALSE;
4066 AFSObjectInfoCB *pObjectInfo = NULL;
4067 AFSObjectInfoCB *pParentObjectInfo = NULL;
4068 AFSPipeOpenCloseRequestCB stPipeOpen;
4074 pFileObject = pIrpSp->FileObject;
4076 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4077 AFS_TRACE_LEVEL_VERBOSE_2,
4078 "AFSOpenSpecialShareFcb (%p) Processing Share %wZ open\n",
4080 &DirectoryCB->NameInformation.FileName));
4082 pObjectInfo = DirectoryCB->ObjectInformation;
4084 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
4087 pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
4088 &pObjectInfo->ParentFileId,
4092 if( DirectoryCB->ObjectInformation->Fcb == NULL)
4096 // Allocate and initialize the Fcb for the file.
4099 ntStatus = AFSInitFcb( DirectoryCB);
4101 *Fcb = pObjectInfo->Fcb;
4103 if( !NT_SUCCESS( ntStatus))
4106 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4107 AFS_TRACE_LEVEL_ERROR,
4108 "AFSOpenSpecialShareFcb (%p) Failed to initialize fcb Status %08lX\n",
4112 try_return( ntStatus);
4115 if ( ntStatus != STATUS_REPARSE)
4118 bAllocateFcb = TRUE;
4121 ntStatus = STATUS_SUCCESS;
4126 *Fcb = pObjectInfo->Fcb;
4128 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
4133 // Increment the open count on this Fcb
4136 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
4138 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
4139 AFS_TRACE_LEVEL_VERBOSE,
4140 "AFSOpenSpecialShareFcb Increment count on Fcb %p Cnt %d\n",
4147 // Initialize the Ccb for the file.
4150 ntStatus = AFSInitCcb( Ccb,
4155 if( !NT_SUCCESS( ntStatus))
4158 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4159 AFS_TRACE_LEVEL_ERROR,
4160 "AFSOpenSpecialShareFcb (%p) Failed to initialize ccb Status %08lX\n",
4164 try_return( ntStatus);
4167 bAllocatedCcb = TRUE;
4170 // Call the service to open the share
4173 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
4175 RtlZeroMemory( &stPipeOpen,
4176 sizeof( AFSPipeOpenCloseRequestCB));
4178 stPipeOpen.RequestId = (*Ccb)->RequestID;
4180 stPipeOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
4183 // Issue the open request to the service
4186 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_OPEN,
4187 AFS_REQUEST_FLAG_SYNCHRONOUS,
4189 &DirectoryCB->NameInformation.FileName,
4193 (void *)&stPipeOpen,
4194 sizeof( AFSPipeOpenCloseRequestCB),
4198 if( !NT_SUCCESS( ntStatus))
4201 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
4202 AFS_TRACE_LEVEL_ERROR,
4203 "AFSOpenSpecialShareFcb (%p) Failed service open Status %08lX\n",
4207 try_return( ntStatus);
4210 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
4212 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
4213 AFS_TRACE_LEVEL_VERBOSE,
4214 "AFSOpenSpecialShareFcb Increment handle count on Fcb %p Cnt %d\n",
4219 // Increment the open reference and handle on the parent node
4222 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
4224 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4225 AFS_TRACE_LEVEL_VERBOSE,
4226 "AFSOpenSpecialShareFcb Increment child open handle count on Parent object %p Cnt %d\n",
4230 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
4232 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
4233 AFS_TRACE_LEVEL_VERBOSE,
4234 "AFSOpenSpecialShareFcb Increment child open ref count on Parent object %p Cnt %d\n",
4239 // Return the open result for this file
4242 Irp->IoStatus.Information = FILE_OPENED;
4249 if( !NT_SUCCESS( ntStatus))
4252 // Decrement the open count on this Fcb
4255 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
4257 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
4258 AFS_TRACE_LEVEL_VERBOSE,
4259 "AFSOpenSpecialShareFcb Decrement count on Fcb %p Cnt %d\n",
4264 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
4267 if( !NT_SUCCESS( ntStatus))
4283 // Need to tear down this Fcb since it is not in the tree for the worker thread
4286 AFSAcquireExcl( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
4289 AFSRemoveFcb( &DirectoryCB->ObjectInformation->Fcb);
4291 AFSReleaseResource( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);