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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 BOOLEAN bReleaseParentDir = FALSE, bReleaseDir = FALSE;
151 ULONG ulParseFlags = 0;
152 GUID stAuthGroup = {0};
153 ULONG ulNameProcessingFlags = 0;
154 BOOLEAN bOpenedReparsePoint = FALSE;
160 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
161 pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
162 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
163 ulOptions = pIrpSp->Parameters.Create.Options;
164 bNoIntermediateBuffering = BooleanFlagOn( ulOptions, FILE_NO_INTERMEDIATE_BUFFERING);
165 bOpenTargetDirectory = BooleanFlagOn( pIrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
166 pFileObject = pIrpSp->FileObject;
167 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
169 uniFileName.Length = uniFileName.MaximumLength = 0;
170 uniFileName.Buffer = NULL;
172 uniRootFileName.Length = uniRootFileName.MaximumLength = 0;
173 uniRootFileName.Buffer = NULL;
175 uniParsedFileName.Length = uniParsedFileName.MaximumLength = 0;
176 uniParsedFileName.Buffer = NULL;
178 uniSubstitutedPathName.Buffer = NULL;
179 uniSubstitutedPathName.Length = 0;
181 uniRelativeName.Buffer = NULL;
182 uniRelativeName.Length = 0;
184 if( AFSGlobalRoot == NULL)
186 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
189 RtlZeroMemory( &stAuthGroup,
192 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
193 (ULONGLONG)PsGetCurrentThreadId(),
197 // If we are in shutdown mode then fail the request
200 if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
203 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
204 AFS_TRACE_LEVEL_WARNING,
205 "AFSCommonCreate (%p) Open request after shutdown\n",
208 try_return( ntStatus = STATUS_TOO_LATE);
211 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
214 ntStatus = AFSEnumerateGlobalRoot( &stAuthGroup);
216 if( !NT_SUCCESS( ntStatus))
219 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
220 AFS_TRACE_LEVEL_ERROR,
221 "AFSCommonCreate Failed to enumerate global root Status %08lX\n",
224 try_return( ntStatus);
229 // Go and parse the name for processing.
230 // If ulParseFlags is returned with AFS_PARSE_FLAG_FREE_FILE_BUFFER set,
231 // then we are responsible for releasing the uniRootFileName.Buffer.
234 ntStatus = AFSParseName( Irp,
244 if( !NT_SUCCESS( ntStatus))
247 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
248 uniFileName.Length > 0 ? AFS_TRACE_LEVEL_ERROR : AFS_TRACE_LEVEL_VERBOSE,
249 "AFSCommonCreate (%p) Failed to parse name \"%wZ\" Status %08lX\n",
254 try_return( ntStatus);
258 // Check for STATUS_REPARSE
261 if( ntStatus == STATUS_REPARSE)
265 // Update the information and return
268 Irp->IoStatus.Information = IO_REPARSE;
270 try_return( ntStatus);
273 if ( pParentDirectoryCB != NULL)
276 bReleaseParentDir = TRUE;
280 // If the returned volume cb is NULL then we are dealing with the \\Server\GlobalRoot
284 if( pVolumeCB == NULL)
288 // Remove any leading or trailing slashes
291 if( uniFileName.Length >= sizeof( WCHAR) &&
292 uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
295 uniFileName.Length -= sizeof( WCHAR);
298 if( uniFileName.Length >= sizeof( WCHAR) &&
299 uniFileName.Buffer[ 0] == L'\\')
302 uniFileName.Buffer = &uniFileName.Buffer[ 1];
304 uniFileName.Length -= sizeof( WCHAR);
308 // If there is a remaining portion returned for this request then
309 // check if it is for the PIOCtl interface
312 if( uniFileName.Length > 0)
316 // We don't accept any other opens off of the AFS Root
319 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
322 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
325 if( RtlCompareUnicodeString( &AFSPIOCtlName,
331 // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
332 // AFSGlobalRoot->DirectoryCB.
335 ntStatus = AFSOpenIOCtlFcb( Irp,
337 AFSGlobalRoot->DirectoryCB,
341 if( !NT_SUCCESS( ntStatus))
344 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
345 AFS_TRACE_LEVEL_ERROR,
346 "AFSCommonCreate Failed to open root IOCtl Fcb Status %08lX\n",
350 else if( pParentDirectoryCB != NULL)
353 if( pParentDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
356 ntStatus = AFSOpenSpecialShareFcb( Irp,
362 if( !NT_SUCCESS( ntStatus))
365 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
366 AFS_TRACE_LEVEL_ERROR,
367 "AFSCommonCreate Failed to open special share Fcb Status %08lX\n",
373 try_return( ntStatus);
376 ntStatus = AFSOpenAFSRoot( Irp,
380 if( !NT_SUCCESS( ntStatus))
383 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
384 AFS_TRACE_LEVEL_ERROR,
385 "AFSCommonCreate Failed to open root Status %08lX\n",
389 try_return( ntStatus);
393 // We have a reference on the root volume
396 VolumeReferenceReason = AFS_VOLUME_REFERENCE_PARSE_NAME;
398 bReleaseVolume = TRUE;
401 // Attempt to locate the node in the name tree if this is not a target
402 // open and the target is not the root
405 uniComponentName.Length = 0;
406 uniComponentName.Buffer = NULL;
408 if( uniFileName.Length > sizeof( WCHAR) ||
409 uniFileName.Buffer[ 0] != L'\\')
412 if( !AFSValidNameFormat( &uniFileName))
415 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
417 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
418 AFS_TRACE_LEVEL_VERBOSE,
419 "AFSCommonCreate (%p) Invalid name %wZ Status %08lX\n",
424 try_return( ntStatus);
428 // Opening a reparse point directly?
431 ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
433 if( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
435 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
436 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
437 AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
440 uniSubstitutedPathName = uniRootFileName;
442 ntStatus = AFSLocateNameEntry( &stAuthGroup,
447 ulNameProcessingFlags,
451 &NewVolumeReferenceReason,
457 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
458 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
459 // the reference on pVolumeCB that was held prior to the call.
460 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
461 // will be released second.
464 lCount = AFSVolumeDecrement( pVolumeCB,
465 VolumeReferenceReason);
467 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
468 AFS_TRACE_LEVEL_VERBOSE,
469 "AFSCommonCreate Decrement count on volume %p Reason %u Cnt %d\n",
471 VolumeReferenceReason,
474 pVolumeCB = pNewVolumeCB;
478 VolumeReferenceReason = NewVolumeReferenceReason;
480 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
482 bReleaseVolume = (pVolumeCB != NULL);
484 if( !NT_SUCCESS( ntStatus) &&
485 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
488 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
490 uniSubstitutedPathName.Buffer = NULL;
494 // AFSLocateNameEntry released the Parent while walking the
498 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
499 AFS_TRACE_LEVEL_VERBOSE,
500 "AFSCommonCreate (%p) Failed to locate name entry for %wZ Status %08lX\n",
505 bReleaseParentDir = FALSE;
507 try_return( ntStatus);
511 // Check for STATUS_REPARSE
514 if( ntStatus == STATUS_REPARSE)
517 uniSubstitutedPathName.Buffer = NULL;
520 // Update the information and return
523 Irp->IoStatus.Information = IO_REPARSE;
525 bReleaseParentDir = FALSE;
527 try_return( ntStatus);
531 // If we re-allocated the name, then update our substitute name
534 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
537 uniSubstitutedPathName = uniRootFileName;
542 uniSubstitutedPathName.Buffer = NULL;
546 // Check for a symlink access
549 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
550 pParentDirectoryCB != NULL)
554 // pParentDirectoryCB DirOpenReferenceCount is still held
557 UNICODE_STRING uniFinalComponent;
559 uniFinalComponent.Length = 0;
560 uniFinalComponent.MaximumLength = 0;
561 uniFinalComponent.Buffer = NULL;
563 AFSRetrieveFinalComponent( &uniFileName,
566 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
569 if( !NT_SUCCESS( ntStatus) &&
570 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
573 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
574 AFS_TRACE_LEVEL_VERBOSE,
575 "AFSCommonCreate (%p) Failing access to symlink %wZ Status %08lX\n",
580 try_return( ntStatus);
587 // AFSLocateNameEntry succeeded. The parent directory reference
588 // has been released and if there is a directory returned, it is
592 bReleaseParentDir = FALSE;
603 // If we have no parent then this is a root open, be sure there is a directory entry
607 else if( pParentDirectoryCB == NULL &&
608 pDirectoryCB == NULL)
611 pDirectoryCB = pVolumeCB->DirectoryCB;
613 lCount = InterlockedIncrement( &pDirectoryCB->DirOpenReferenceCount);
615 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
616 AFS_TRACE_LEVEL_VERBOSE,
617 "AFSCommonCreate Increment0 count on %wZ DE %p Ccb %p Cnt %d\n",
618 &pDirectoryCB->NameInformation.FileName,
626 if( bOpenTargetDirectory)
630 // If we have a directory cb for the entry then dereference it and reference the parent
633 if( pDirectoryCB != NULL)
636 if ( !bReleaseParentDir)
640 // Perform in this order to prevent thrashing
643 lCount = InterlockedIncrement( &pParentDirectoryCB->DirOpenReferenceCount);
645 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
646 AFS_TRACE_LEVEL_VERBOSE,
647 "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
648 &pParentDirectoryCB->NameInformation.FileName,
653 bReleaseParentDir = TRUE;
657 // Do NOT decrement the reference count on the pDirectoryCB yet.
658 // The BackupEntry below might drop the count to zero leaving
659 // the entry subject to being deleted and we need some of the
660 // contents during later processing
663 AFSBackupEntry( pNameArray);
667 // OK, open the target directory
670 if( uniComponentName.Length == 0)
672 AFSRetrieveFinalComponent( &uniFileName,
676 ntStatus = AFSOpenTargetDirectory( Irp,
684 if( !NT_SUCCESS( ntStatus))
687 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
688 AFS_TRACE_LEVEL_ERROR,
689 "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
690 &pParentDirectoryCB->NameInformation.FileName,
694 try_return( ntStatus);
697 if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
700 if( pDirectoryCB == NULL ||
701 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
703 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
704 AFS_TRACE_LEVEL_VERBOSE,
705 "AFSCommonCreate (%p) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
709 pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0);
713 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
714 AFS_TRACE_LEVEL_VERBOSE,
715 "AFSCommonCreate (%p) Opening as reparse point %wZ Type %08lX\n",
718 pDirectoryCB->ObjectInformation->FileType);
720 bOpenedReparsePoint = TRUE;
725 // Based on the options passed in, process the file accordingly.
728 if( ulCreateDisposition == FILE_CREATE ||
729 ( ( ulCreateDisposition == FILE_OPEN_IF ||
730 ulCreateDisposition == FILE_OVERWRITE_IF) &&
731 pDirectoryCB == NULL))
734 if( uniComponentName.Length == 0 ||
735 pDirectoryCB != NULL)
739 // We traversed the entire path so we found each entry,
740 // fail with collision
743 if( pDirectoryCB != NULL)
746 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
747 AFS_TRACE_LEVEL_VERBOSE,
748 "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
749 &pDirectoryCB->NameInformation.FileName,
755 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
756 AFS_TRACE_LEVEL_VERBOSE,
757 "AFSCommonCreate Object name collision on create Status %08lX\n",
761 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
765 // OK, go and create the node
768 ntStatus = AFSProcessCreate( Irp,
778 if( !NT_SUCCESS( ntStatus))
781 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
782 AFS_TRACE_LEVEL_ERROR,
783 "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
785 &pParentDirectoryCB->NameInformation.FileName,
789 try_return( ntStatus);
793 // We should not have an extra component except for PIOCtl opens
796 if( uniComponentName.Length > 0)
800 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
803 if( RtlCompareUnicodeString( &AFSPIOCtlName,
809 // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
810 // pParentDirectoryCB.
813 ntStatus = AFSOpenIOCtlFcb( Irp,
819 if( !NT_SUCCESS( ntStatus))
822 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
823 AFS_TRACE_LEVEL_ERROR,
824 "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
832 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
833 AFS_TRACE_LEVEL_VERBOSE,
834 "AFSCommonCreate (%p) File %wZ name not found\n",
838 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
841 try_return( ntStatus);
845 // For root opens the parent will be NULL
848 if( pParentDirectoryCB == NULL)
852 // Check for the delete on close flag for the root
855 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
858 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
859 AFS_TRACE_LEVEL_ERROR,
860 "AFSCommonCreate (%p) Attempt to open root as delete on close\n",
863 try_return( ntStatus = STATUS_CANNOT_DELETE);
867 // If this is the target directory, then bail
870 if( bOpenTargetDirectory)
873 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
874 AFS_TRACE_LEVEL_ERROR,
875 "AFSCommonCreate (%p) Attempt to open root as target directory\n",
878 try_return( ntStatus = STATUS_INVALID_PARAMETER);
882 // Go and open the root of the volume
885 ntStatus = AFSOpenRoot( Irp,
891 if( !NT_SUCCESS( ntStatus))
894 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
895 AFS_TRACE_LEVEL_ERROR,
896 "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
897 pVolumeCB->ObjectInformation.FileId.Cell,
898 pVolumeCB->ObjectInformation.FileId.Volume,
902 try_return( ntStatus);
906 // At this point if we have no pDirectoryCB it was not found.
909 if( pDirectoryCB == NULL)
912 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
913 AFS_TRACE_LEVEL_ERROR,
914 "AFSCommonCreate Failing access to %wZ Name not found\n",
917 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
920 if( ulCreateDisposition == FILE_OVERWRITE ||
921 ulCreateDisposition == FILE_SUPERSEDE ||
922 ulCreateDisposition == FILE_OVERWRITE_IF)
926 // Go process a file for overwrite or supersede.
929 ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
938 if( !NT_SUCCESS( ntStatus))
941 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
942 AFS_TRACE_LEVEL_ERROR,
943 "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
944 &pDirectoryCB->NameInformation.FileName,
948 try_return( ntStatus);
952 // Trying to open the file
955 ntStatus = AFSProcessOpen( Irp,
963 if( !NT_SUCCESS( ntStatus))
966 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
967 AFS_TRACE_LEVEL_ERROR,
968 "AFSCommonCreate Failed open on %wZ Status %08lX\n",
969 &pDirectoryCB->NameInformation.FileName,
975 if( NT_SUCCESS( ntStatus) &&
976 ntStatus != STATUS_REPARSE)
982 AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
985 RtlCopyMemory( &pCcb->AuthGroup,
990 // If we have a substitute name, then use it
993 if( uniSubstitutedPathName.Buffer != NULL)
996 pCcb->FullFileName = uniSubstitutedPathName;
998 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1000 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1005 pCcb->FullFileName = uniRootFileName;
1007 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1010 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1012 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1016 if( bOpenedReparsePoint)
1018 SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1021 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1022 AFS_TRACE_LEVEL_VERBOSE,
1023 "AFSCommonCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1024 &pCcb->DirectoryCB->NameInformation.FileName,
1027 lCount = pCcb->DirectoryCB->DirOpenReferenceCount);
1029 ASSERT( lCount >= 0);
1031 pCcb->CurrentDirIndex = 0;
1033 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1036 SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1040 // Save off the name array for this instance
1043 pCcb->NameArray = pNameArray;
1047 AFSReleaseResource( &pCcb->NPCcb->CcbLock);
1051 // If we make it here then init the FO for the request.
1054 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1055 AFS_TRACE_LEVEL_VERBOSE_2,
1056 "AFSCommonCreate (%p) FileObject %p FsContext %p FsContext2 %p\n",
1062 pFileObject->FsContext = (void *)pFcb;
1064 pFileObject->FsContext2 = (void *)pCcb;
1069 ASSERT( pFcb->OpenHandleCount > 0);
1071 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1074 // For files perform additional processing
1077 switch( pFcb->Header.NodeTypeCode)
1084 pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1089 // If the user did not request nobuffering then mark the FO as cacheable
1092 if( bNoIntermediateBuffering)
1095 pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1100 pFileObject->Flags |= FO_CACHE_SUPPORTED;
1104 // If the file was opened for execution then we need to set the bit in the FO
1107 if( BooleanFlagOn( *pDesiredAccess,
1111 SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1115 // Update the last access time
1118 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1129 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1130 AFS_TRACE_LEVEL_ERROR,
1131 "AFSCommonCreate (%p) Returning with NULL Fcb FileObject %p FsContext %p FsContext2 %p\n",
1140 if( NT_SUCCESS( ntStatus) &&
1141 ntStatus == STATUS_REPARSE)
1144 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1145 AFS_TRACE_LEVEL_ERROR,
1146 "AFSCommonCreate (%p) STATUS_REPARSE FileObject %p FsContext %p FsContext2 %p\n",
1154 // Free up the sub name if we have one
1157 if( uniSubstitutedPathName.Buffer != NULL)
1160 AFSExFreePoolWithTag( uniSubstitutedPathName.Buffer, 0);
1162 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1167 // Free up the name array ...
1170 if( pNameArray != NULL)
1173 AFSFreeNameArray( pNameArray);
1176 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1179 AFSExFreePoolWithTag( uniRootFileName.Buffer, 0);
1185 lCount = AFSVolumeDecrement( pVolumeCB,
1186 VolumeReferenceReason);
1188 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1189 AFS_TRACE_LEVEL_VERBOSE,
1190 "AFSCommonCreate Decrement count on Volume %08lX Reason %u Cnt %d\n",
1192 VolumeReferenceReason,
1200 // Release the reference from AFSLocateNameEntry
1203 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
1205 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1206 AFS_TRACE_LEVEL_VERBOSE,
1207 "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1208 &pDirectoryCB->NameInformation.FileName,
1213 ASSERT( lCount >= 0);
1216 if ( bReleaseParentDir)
1220 // Release the reference from AFSLocateNameEntry
1223 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
1225 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1226 AFS_TRACE_LEVEL_VERBOSE,
1227 "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1228 &pParentDirectoryCB->NameInformation.FileName,
1233 ASSERT( lCount >= 0);
1237 // Setup the Irp for completion, the Information has been set previously
1240 Irp->IoStatus.Status = ntStatus;
1247 AFSOpenAFSRoot( IN PIRP Irp,
1252 NTSTATUS ntStatus = STATUS_SUCCESS;
1259 // Initialize the Ccb for the file.
1262 ntStatus = AFSInitCcb( Ccb,
1263 AFSGlobalRoot->DirectoryCB,
1267 if( !NT_SUCCESS( ntStatus))
1270 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1271 AFS_TRACE_LEVEL_ERROR,
1272 "AFSOpenAFSRoot (%p) Failed to allocate Ccb\n",
1275 try_return( ntStatus);
1279 // Increment the open count on this Fcb
1282 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1284 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1285 AFS_TRACE_LEVEL_VERBOSE,
1286 "AFSOpenAFSRoot Increment count on Fcb %p Cnt %d\n",
1287 AFSGlobalRoot->RootFcb,
1290 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1292 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1293 AFS_TRACE_LEVEL_VERBOSE,
1294 "AFSOpenAFSRoot Increment handle count on Fcb %p Cnt %d\n",
1295 AFSGlobalRoot->RootFcb,
1298 *Fcb = AFSGlobalRoot->RootFcb;
1301 // Return the open result for this file
1304 Irp->IoStatus.Information = FILE_OPENED;
1315 AFSOpenRoot( IN PIRP Irp,
1316 IN AFSVolumeCB *VolumeCB,
1318 OUT AFSFcb **RootFcb,
1322 NTSTATUS ntStatus = STATUS_SUCCESS;
1323 PFILE_OBJECT pFileObject = NULL;
1324 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1325 PACCESS_MASK pDesiredAccess = NULL;
1326 USHORT usShareAccess;
1328 BOOLEAN bAllocatedCcb = FALSE;
1329 BOOLEAN bReleaseFcb = FALSE;
1330 AFSFileOpenCB stOpenCB;
1331 AFSFileOpenResultCB stOpenResultCB;
1332 ULONG ulResultLen = 0;
1338 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1339 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1340 ulOptions = pIrpSp->Parameters.Create.Options;
1342 pFileObject = pIrpSp->FileObject;
1344 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1347 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1349 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1350 AFS_TRACE_LEVEL_ERROR,
1351 "AFSOpenRoot (%p) Attempt to open root as file Status %08lX\n",
1355 try_return( ntStatus);
1359 // Check if we should go and retrieve updated information for the node
1362 ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1367 if( !NT_SUCCESS( ntStatus))
1370 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1371 AFS_TRACE_LEVEL_ERROR,
1372 "AFSOpenRoot (%p) Failed to validate root entry Status %08lX\n",
1376 try_return( ntStatus);
1380 // Check with the service that we can open the file
1383 RtlZeroMemory( &stOpenCB,
1384 sizeof( AFSFileOpenCB));
1386 stOpenCB.DesiredAccess = *pDesiredAccess;
1388 stOpenCB.ShareAccess = usShareAccess;
1390 stOpenResultCB.GrantedAccess = 0;
1392 ulResultLen = sizeof( AFSFileOpenResultCB);
1394 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1395 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1398 &VolumeCB->ObjectInformation.FileId,
1400 sizeof( AFSFileOpenCB),
1401 (void *)&stOpenResultCB,
1404 if( !NT_SUCCESS( ntStatus))
1407 UNICODE_STRING uniGUID;
1410 uniGUID.MaximumLength = 0;
1411 uniGUID.Buffer = NULL;
1413 if( AuthGroup != NULL)
1415 RtlStringFromGUID( *AuthGroup,
1419 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1420 AFS_TRACE_LEVEL_ERROR,
1421 "AFSOpenRoot (%p) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1423 VolumeCB->ObjectInformation.FileId.Cell,
1424 VolumeCB->ObjectInformation.FileId.Volume,
1428 if( AuthGroup != NULL)
1430 RtlFreeUnicodeString( &uniGUID);
1433 try_return( ntStatus);
1437 // If the entry is not initialized then do it now
1440 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1443 AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1446 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1449 ntStatus = AFSEnumerateDirectory( AuthGroup,
1450 &VolumeCB->ObjectInformation,
1453 if( !NT_SUCCESS( ntStatus))
1456 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1458 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1459 AFS_TRACE_LEVEL_ERROR,
1460 "AFSOpenRoot (%p) Failed to enumerate directory Status %08lX\n",
1464 try_return( ntStatus);
1467 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1470 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1474 // If the root fcb has been initialized then check access otherwise
1475 // init the volume fcb
1478 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1481 if( !NT_SUCCESS( ntStatus))
1484 try_return( ntStatus);
1487 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1489 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1490 AFS_TRACE_LEVEL_VERBOSE,
1491 "AFSOpenRoot Increment count on Fcb %p Cnt %d\n",
1498 // If there are current opens on the Fcb, check the access.
1501 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1504 ntStatus = IoCheckShareAccess( *pDesiredAccess,
1507 &VolumeCB->RootFcb->ShareAccess,
1510 if( !NT_SUCCESS( ntStatus))
1513 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1514 AFS_TRACE_LEVEL_ERROR,
1515 "AFSOpenRoot (%p) Access check failure Status %08lX\n",
1519 try_return( ntStatus);
1524 // Initialize the Ccb for the file.
1527 ntStatus = AFSInitCcb( Ccb,
1528 VolumeCB->DirectoryCB,
1532 if( !NT_SUCCESS( ntStatus))
1535 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1536 AFS_TRACE_LEVEL_ERROR,
1537 "AFSOpenRoot (%p) Failed to allocate Ccb Status %08lX\n",
1541 try_return( ntStatus);
1544 bAllocatedCcb = TRUE;
1547 // OK, update the share access on the fileobject
1550 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1553 IoUpdateShareAccess( pFileObject,
1554 &VolumeCB->RootFcb->ShareAccess);
1563 IoSetShareAccess( *pDesiredAccess,
1566 &VolumeCB->RootFcb->ShareAccess);
1570 // Increment the open count on this Fcb
1573 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1575 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1576 AFS_TRACE_LEVEL_VERBOSE,
1577 "AFSOpenRoot Increment handle count on Fcb %p Cnt %d\n",
1582 // Indicate the object is held
1585 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1588 // Return the open result for this file
1591 Irp->IoStatus.Information = FILE_OPENED;
1593 *RootFcb = VolumeCB->RootFcb;
1599 if ( !NT_SUCCESS( ntStatus))
1602 lCount = InterlockedDecrement( &VolumeCB->RootFcb->OpenReferenceCount);
1604 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1605 AFS_TRACE_LEVEL_VERBOSE,
1606 "AFSOpenRoot Decrement count on Fcb %p Cnt %d\n",
1611 AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1614 if( !NT_SUCCESS( ntStatus))
1626 Irp->IoStatus.Information = 0;
1634 AFSProcessCreate( IN PIRP Irp,
1636 IN AFSVolumeCB *VolumeCB,
1637 IN AFSDirectoryCB *ParentDirCB,
1638 IN PUNICODE_STRING FileName,
1639 IN PUNICODE_STRING ComponentName,
1640 IN PUNICODE_STRING FullFileName,
1645 NTSTATUS ntStatus = STATUS_SUCCESS;
1646 PFILE_OBJECT pFileObject = NULL;
1647 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1648 ULONG ulOptions = 0;
1649 ULONG ulAttributes = 0;
1650 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1651 PACCESS_MASK pDesiredAccess = NULL;
1652 USHORT usShareAccess;
1653 AFSDirectoryCB *pDirEntry = NULL;
1654 AFSObjectInfoCB *pParentObjectInfo = NULL;
1655 AFSObjectInfoCB *pObjectInfo = NULL;
1661 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1662 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1664 pFileObject = pIrpSp->FileObject;
1667 // Extract out the options
1670 ulOptions = pIrpSp->Parameters.Create.Options;
1673 // We pass all attributes they want to apply to the file to the create
1676 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1679 // If this is a directory create then set the attribute correctly
1682 if( ulOptions & FILE_DIRECTORY_FILE)
1685 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1688 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1689 AFS_TRACE_LEVEL_VERBOSE,
1690 "AFSProcessCreate (%p) Creating file %wZ Attributes %08lX\n",
1695 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1698 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1699 AFS_TRACE_LEVEL_ERROR,
1700 "AFSProcessCreate Request failed due to read only volume %wZ\n",
1703 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
1706 pParentObjectInfo = ParentDirCB->ObjectInformation;
1709 // Allocate and insert the direntry into the parent node
1712 ntStatus = AFSCreateDirEntry( AuthGroup,
1720 if( !NT_SUCCESS( ntStatus))
1723 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1724 AFS_TRACE_LEVEL_ERROR,
1725 "AFSProcessCreate (%p) Failed to create directory entry %wZ Status %08lX\n",
1730 try_return( ntStatus);
1733 bFileCreated = TRUE;
1735 pObjectInfo = pDirEntry->ObjectInformation;
1737 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1738 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1741 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1742 AFS_TRACE_LEVEL_VERBOSE,
1743 "AFSProcessCreate (%p) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1745 &pDirEntry->NameInformation.FileName,
1746 pObjectInfo->FileId.Cell,
1747 pObjectInfo->FileId.Volume,
1748 pObjectInfo->FileId.Vnode,
1749 pObjectInfo->FileId.Unique);
1751 ntStatus = AFSEvaluateNode( AuthGroup,
1754 if( !NT_SUCCESS( ntStatus))
1757 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
1760 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1763 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1764 AFS_TRACE_LEVEL_ERROR,
1765 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
1767 &pDirEntry->NameInformation.FileName,
1768 pObjectInfo->FileId.Cell,
1769 pObjectInfo->FileId.Volume,
1770 pObjectInfo->FileId.Vnode,
1771 pObjectInfo->FileId.Unique,
1772 pParentObjectInfo->FileId.Cell,
1773 pParentObjectInfo->FileId.Volume,
1774 pParentObjectInfo->FileId.Vnode,
1775 pParentObjectInfo->FileId.Unique,
1778 else if ( AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId))
1781 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1782 AFS_TRACE_LEVEL_ERROR,
1783 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1785 &pDirEntry->NameInformation.FileName,
1786 pObjectInfo->FileId.Cell,
1787 pObjectInfo->FileId.Volume,
1788 pObjectInfo->FileId.Vnode,
1789 pObjectInfo->FileId.Unique,
1790 pParentObjectInfo->FileId.Cell,
1791 pParentObjectInfo->FileId.Volume,
1792 pParentObjectInfo->FileId.Vnode,
1793 pParentObjectInfo->FileId.Unique,
1799 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1800 AFS_TRACE_LEVEL_ERROR,
1801 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1803 &pDirEntry->NameInformation.FileName,
1804 pObjectInfo->FileId.Cell,
1805 pObjectInfo->FileId.Volume,
1806 pObjectInfo->FileId.Vnode,
1807 pObjectInfo->FileId.Unique,
1808 pParentObjectInfo->FileId.Cell,
1809 pParentObjectInfo->FileId.Volume,
1810 pParentObjectInfo->FileId.Vnode,
1811 pParentObjectInfo->FileId.Unique,
1812 pObjectInfo->ParentFileId.Cell,
1813 pObjectInfo->ParentFileId.Volume,
1814 pObjectInfo->ParentFileId.Vnode,
1815 pObjectInfo->ParentFileId.Unique,
1822 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1823 AFS_TRACE_LEVEL_ERROR,
1824 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1826 &pDirEntry->NameInformation.FileName,
1827 pObjectInfo->FileId.Cell,
1828 pObjectInfo->FileId.Volume,
1829 pObjectInfo->FileId.Vnode,
1830 pObjectInfo->FileId.Unique,
1834 try_return( ntStatus);
1837 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1840 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
1841 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
1844 // We may have raced and the Fcb is already created
1848 // Allocate and initialize the Fcb for the file.
1851 ntStatus = AFSInitFcb( pDirEntry);
1853 *Fcb = pObjectInfo->Fcb;
1855 if( !NT_SUCCESS( ntStatus))
1858 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1859 AFS_TRACE_LEVEL_ERROR,
1860 "AFSProcessCreate (%p) Failed to initialize fcb %wZ Status %08lX\n",
1865 try_return( ntStatus);
1868 ntStatus = STATUS_SUCCESS;
1871 // Increment the open count on this Fcb
1874 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1876 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1877 AFS_TRACE_LEVEL_VERBOSE,
1878 "AFSProcessCreate Increment count on Fcb %p Cnt %d\n",
1885 // Initialize the Ccb for the file.
1888 ntStatus = AFSInitCcb( Ccb,
1893 if( !NT_SUCCESS( ntStatus))
1896 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1897 AFS_TRACE_LEVEL_ERROR,
1898 "AFSProcessCreate (%p) Failed to initialize ccb %wZ Status %08lX\n",
1903 try_return( ntStatus);
1906 bAllocatedCcb = TRUE;
1909 // If this is a file, update the headers filesizes.
1912 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1916 // Update the sizes with the information passed in
1919 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
1920 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1921 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1924 // Notify the system of the addition
1927 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1929 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1930 (ULONG)FILE_ACTION_ADDED);
1932 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
1934 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1938 // This is a new directory node so indicate it has been enumerated
1941 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1944 // And the parent directory entry
1947 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1950 // Notify the system of the addition
1953 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1955 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1956 (ULONG)FILE_ACTION_ADDED);
1958 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
1959 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
1960 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
1961 (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
1965 // And the parent directory entry
1968 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1971 // Notify the system of the addition
1974 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1976 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1977 (ULONG)FILE_ACTION_ADDED);
1981 // Save off the access for the open
1984 IoSetShareAccess( *pDesiredAccess,
1987 &(*Fcb)->ShareAccess);
1989 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
1991 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1992 AFS_TRACE_LEVEL_VERBOSE,
1993 "AFSProcessCreate Increment handle count on Fcb %p Cnt %d\n",
1998 // Increment the open reference and handle on the parent node
2001 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2003 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2004 AFS_TRACE_LEVEL_VERBOSE,
2005 "AFSProcessCreate Increment child open handle count on Parent object %p Cnt %d\n",
2009 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2011 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2012 AFS_TRACE_LEVEL_VERBOSE,
2013 "AFSProcessCreate Increment child open ref count on Parent object %p Cnt %d\n",
2017 if( ulOptions & FILE_DELETE_ON_CLOSE)
2021 // Mark it for delete on close
2024 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2025 AFS_TRACE_LEVEL_VERBOSE,
2026 "AFSProcessCreate (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2031 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2035 // Indicate the object is locked in the service
2038 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2041 // Return the open result for this file
2044 Irp->IoStatus.Information = FILE_CREATED;
2049 // If we created the Fcb we need to release the resources
2055 if( !NT_SUCCESS( ntStatus))
2058 // Decrement the open count on this Fcb
2061 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2063 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2064 AFS_TRACE_LEVEL_VERBOSE,
2065 "AFSProcessCreate Decrement count on Fcb %p Cnt %d\n",
2070 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2077 // Decrement the reference added during initialization of the DE
2078 // AFSInitCcb allocates its own reference count.
2081 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2083 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2084 AFS_TRACE_LEVEL_VERBOSE,
2085 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2086 &pDirEntry->NameInformation.FileName,
2090 ASSERT( lCount >= 0);
2093 if( !NT_SUCCESS( ntStatus))
2099 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2100 AFS_TRACE_LEVEL_VERBOSE,
2101 "AFSProcessCreate Create failed, removing DE %p from parent object %p Status %08lX\n",
2107 // Remove the dir entry from the parent
2110 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2113 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2115 AFSNotifyDelete( pDirEntry,
2120 // Pull the directory entry from the parent
2123 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2125 FALSE); // Leave it in the enum list so the worker cleans it up
2128 // Tag the parent as needing verification
2131 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2133 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2135 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2146 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2159 AFSOpenTargetDirectory( IN PIRP Irp,
2160 IN AFSVolumeCB *VolumeCB,
2161 IN AFSDirectoryCB *ParentDirectoryCB,
2162 IN AFSDirectoryCB *TargetDirectoryCB,
2163 IN UNICODE_STRING *TargetName,
2167 UNREFERENCED_PARAMETER(VolumeCB);
2168 NTSTATUS ntStatus = STATUS_SUCCESS;
2169 PFILE_OBJECT pFileObject = NULL;
2170 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2171 PACCESS_MASK pDesiredAccess = NULL;
2172 USHORT usShareAccess;
2173 BOOLEAN bAllocatedCcb = FALSE;
2174 BOOLEAN bReleaseFcb = FALSE;
2175 AFSObjectInfoCB *pParentObject = NULL;
2176 AFSObjectInfoCB *pGrandParentObject = NULL;
2177 UNICODE_STRING uniTargetName;
2183 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2184 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2186 pFileObject = pIrpSp->FileObject;
2188 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2189 AFS_TRACE_LEVEL_VERBOSE,
2190 "AFSOpenTargetDirectory (%p) Processing file %wZ\n",
2194 pParentObject = ParentDirectoryCB->ObjectInformation;
2196 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2199 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2203 // Make sure we have an Fcb for the access
2206 // Allocate and initialize the Fcb for the file.
2209 ntStatus = AFSInitFcb( ParentDirectoryCB);
2211 *Fcb = pParentObject->Fcb;
2213 if( !NT_SUCCESS( ntStatus))
2216 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2217 AFS_TRACE_LEVEL_ERROR,
2218 "AFSOpenTargetDirectory (%p) Failed to initialize fcb %wZ Status %08lX\n",
2220 &ParentDirectoryCB->NameInformation.FileName,
2223 try_return( ntStatus);
2226 ntStatus = STATUS_SUCCESS;
2229 // Increment the open count on this Fcb
2232 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2234 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2235 AFS_TRACE_LEVEL_VERBOSE,
2236 "AFSOpenTargetDirectory Increment count on Fcb %p Cnt %d\n",
2243 // If there are current opens on the Fcb, check the access.
2246 if( pParentObject->Fcb->OpenHandleCount > 0)
2249 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2252 &pParentObject->Fcb->ShareAccess,
2255 if( !NT_SUCCESS( ntStatus))
2258 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2259 AFS_TRACE_LEVEL_ERROR,
2260 "AFSOpenTargetDirectory (%p) Access check failure %wZ Status %08lX\n",
2262 &ParentDirectoryCB->NameInformation.FileName,
2265 try_return( ntStatus);
2270 // Initialize the Ccb for the file.
2273 ntStatus = AFSInitCcb( Ccb,
2278 if( !NT_SUCCESS( ntStatus))
2281 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2282 AFS_TRACE_LEVEL_ERROR,
2283 "AFSOpenTargetDirectory (%p) Failed to initialize ccb %wZ Status %08lX\n",
2285 &ParentDirectoryCB->NameInformation.FileName,
2288 try_return( ntStatus);
2291 bAllocatedCcb = TRUE;
2293 if( TargetDirectoryCB != NULL &&
2294 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2300 Irp->IoStatus.Information = FILE_EXISTS;
2302 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2307 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2309 uniTargetName = *TargetName;
2313 // Update the filename in the fileobject for rename processing
2316 RtlCopyMemory( pFileObject->FileName.Buffer,
2317 uniTargetName.Buffer,
2318 uniTargetName.Length);
2320 pFileObject->FileName.Length = uniTargetName.Length;
2323 // OK, update the share access on the fileobject
2326 if( pParentObject->Fcb->OpenHandleCount > 0)
2329 IoUpdateShareAccess( pFileObject,
2330 &pParentObject->Fcb->ShareAccess);
2339 IoSetShareAccess( *pDesiredAccess,
2342 &pParentObject->Fcb->ShareAccess);
2345 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2347 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2348 AFS_TRACE_LEVEL_VERBOSE,
2349 "AFSOpenTargetDirectory Increment handle count on Fcb %p Cnt %d\n",
2354 // Increment the open reference and handle on the parent node
2357 if( BooleanFlagOn( pParentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2360 pGrandParentObject = AFSFindObjectInfo( pParentObject->VolumeCB,
2361 &pParentObject->ParentFileId);
2363 if ( pGrandParentObject)
2366 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenHandleCount);
2368 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2369 AFS_TRACE_LEVEL_VERBOSE,
2370 "AFSOpenTargetDirectory Increment child open handle count on Parent object %p Cnt %d\n",
2374 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenReferenceCount);
2376 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2377 AFS_TRACE_LEVEL_VERBOSE,
2378 "AFSOpenTargetDirectory Increment child open ref count on Parent object %p Cnt %d\n",
2382 AFSReleaseObjectInfo( &pGrandParentObject);
2391 if( !NT_SUCCESS( ntStatus))
2394 // Decrement the open count on this Fcb
2397 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2399 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2400 AFS_TRACE_LEVEL_VERBOSE,
2401 "AFSOpenTargetDirectory Decrement count on Fcb %p Cnt %d\n",
2406 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2409 if( !NT_SUCCESS( ntStatus))
2422 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2433 AFSProcessOpen( IN PIRP Irp,
2435 IN AFSVolumeCB *VolumeCB,
2436 IN AFSDirectoryCB *ParentDirCB,
2437 IN AFSDirectoryCB *DirectoryCB,
2441 UNREFERENCED_PARAMETER(VolumeCB);
2442 NTSTATUS ntStatus = STATUS_SUCCESS;
2443 PFILE_OBJECT pFileObject = NULL;
2444 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2445 PACCESS_MASK pDesiredAccess = NULL;
2446 USHORT usShareAccess;
2447 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE;
2448 ULONG ulOptions = 0;
2449 AFSFileOpenCB stOpenCB;
2450 AFSFileOpenResultCB stOpenResultCB;
2451 ULONG ulResultLen = 0;
2452 AFSObjectInfoCB *pParentObjectInfo = NULL;
2453 AFSObjectInfoCB *pObjectInfo = NULL;
2454 ULONG ulFileAccess = 0;
2455 AFSFileAccessReleaseCB stReleaseFileAccess;
2461 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2462 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2464 pFileObject = pIrpSp->FileObject;
2466 pParentObjectInfo = ParentDirCB->ObjectInformation;
2468 pObjectInfo = DirectoryCB->ObjectInformation;
2470 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2471 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
2474 // Check if the entry is pending a deletion
2477 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2480 ntStatus = STATUS_DELETE_PENDING;
2482 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2483 AFS_TRACE_LEVEL_ERROR,
2484 "AFSProcessOpen (%p) Entry pending delete %wZ Status %08lX\n",
2486 &DirectoryCB->NameInformation.FileName,
2489 try_return( ntStatus);
2493 // Extract out the options
2496 ulOptions = pIrpSp->Parameters.Create.Options;
2499 // Check if we should go and retrieve updated information for the node
2502 ntStatus = AFSValidateEntry( DirectoryCB,
2507 if( !NT_SUCCESS( ntStatus))
2510 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2511 AFS_TRACE_LEVEL_ERROR,
2512 "AFSProcessOpen (%p) Failed to validate entry %wZ Status %08lX\n",
2514 &DirectoryCB->NameInformation.FileName,
2517 try_return( ntStatus);
2521 // If this is marked for delete on close then be sure we can delete the entry
2524 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2527 ntStatus = AFSNotifyDelete( DirectoryCB,
2531 if( !NT_SUCCESS( ntStatus))
2534 ntStatus = STATUS_CANNOT_DELETE;
2536 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2537 AFS_TRACE_LEVEL_ERROR,
2538 "AFSProcessOpen (%p) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2540 &DirectoryCB->NameInformation.FileName,
2543 try_return( ntStatus);
2548 // Be sure we have an Fcb for the current object
2551 ntStatus = AFSInitFcb( DirectoryCB);
2553 if( !NT_SUCCESS( ntStatus))
2556 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2557 AFS_TRACE_LEVEL_ERROR,
2558 "AFSProcessOpen (%p) Failed to init fcb on %wZ Status %08lX\n",
2560 &DirectoryCB->NameInformation.FileName,
2563 try_return( ntStatus);
2566 ntStatus = STATUS_SUCCESS;
2569 // AFSInitFcb returns the Fcb resource held
2575 // Increment the open count on this Fcb
2578 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2580 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2581 AFS_TRACE_LEVEL_VERBOSE,
2582 "AFSProcessOpen Increment2 count on Fcb %p Cnt %d\n",
2587 // Check access on the entry
2590 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2593 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2596 &pObjectInfo->Fcb->ShareAccess,
2599 if( !NT_SUCCESS( ntStatus))
2602 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2603 AFS_TRACE_LEVEL_ERROR,
2604 "AFSProcessOpen (%p) Failed to check share access on %wZ Status %08lX\n",
2606 &DirectoryCB->NameInformation.FileName,
2609 try_return( ntStatus);
2614 // Additional checks
2617 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2621 // If the caller is asking for write access then try to flush the image section
2624 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2625 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2630 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2631 AFS_TRACE_LEVEL_VERBOSE,
2632 "AFSProcessOpen Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2633 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2634 PsGetCurrentThread());
2636 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2639 bMmFlushed = MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2642 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2643 AFS_TRACE_LEVEL_VERBOSE,
2644 "AFSProcessOpen Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2645 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2646 PsGetCurrentThread());
2648 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
2653 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2654 STATUS_SHARING_VIOLATION;
2656 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2657 AFS_TRACE_LEVEL_ERROR,
2658 "AFSProcessOpen (%p) Failed to flush image section %wZ Status %08lX\n",
2660 &DirectoryCB->NameInformation.FileName,
2663 try_return( ntStatus);
2667 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2670 ntStatus = STATUS_NOT_A_DIRECTORY;
2672 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2673 AFS_TRACE_LEVEL_ERROR,
2674 "AFSProcessOpen (%p) Attempt to open file as directory %wZ Status %08lX\n",
2676 &DirectoryCB->NameInformation.FileName,
2679 try_return( ntStatus);
2682 pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2684 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2685 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2688 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2691 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2693 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2694 AFS_TRACE_LEVEL_ERROR,
2695 "AFSProcessOpen (%p) Attempt to open directory as file %wZ Status %08lX\n",
2697 &DirectoryCB->NameInformation.FileName,
2700 try_return( ntStatus);
2703 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2704 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2705 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2706 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2713 try_return( ntStatus = STATUS_UNSUCCESSFUL);
2717 // Check with the service that we can open the file
2720 stOpenCB.ParentId = pParentObjectInfo->FileId;
2722 stOpenCB.DesiredAccess = *pDesiredAccess;
2724 stOpenCB.ShareAccess = usShareAccess;
2726 stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2728 stOpenCB.Identifier = (ULONGLONG)pFileObject;
2730 stOpenResultCB.GrantedAccess = 0;
2732 ulResultLen = sizeof( AFSFileOpenResultCB);
2734 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2735 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2737 &DirectoryCB->NameInformation.FileName,
2738 &pObjectInfo->FileId,
2740 sizeof( AFSFileOpenCB),
2741 (void *)&stOpenResultCB,
2744 if( !NT_SUCCESS( ntStatus))
2747 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2748 AFS_TRACE_LEVEL_ERROR,
2749 "AFSProcessOpen (%p) Failed open in service %wZ Status %08lX\n",
2751 &DirectoryCB->NameInformation.FileName,
2754 try_return( ntStatus);
2758 // Save the granted access in case we need to release it below
2761 ulFileAccess = stOpenResultCB.FileAccess;
2764 // Check if there is a conflict
2767 if( !AFSCheckAccess( *pDesiredAccess,
2768 stOpenResultCB.GrantedAccess,
2769 BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2772 ntStatus = STATUS_ACCESS_DENIED;
2774 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2775 AFS_TRACE_LEVEL_ERROR,
2776 "AFSProcessOpen (%p) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2779 stOpenResultCB.GrantedAccess,
2780 &DirectoryCB->NameInformation.FileName,
2783 try_return( ntStatus);
2787 // Initialize the Ccb for the file.
2790 ntStatus = AFSInitCcb( Ccb,
2795 if( !NT_SUCCESS( ntStatus))
2798 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2799 AFS_TRACE_LEVEL_ERROR,
2800 "AFSProcessOpen (%p) Failed to initialize ccb %wZ Status %08lX\n",
2802 &DirectoryCB->NameInformation.FileName,
2805 try_return( ntStatus);
2808 bAllocatedCcb = TRUE;
2811 // Perform the access check on the target if this is a mount point or symlink
2814 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2817 IoUpdateShareAccess( pFileObject,
2818 &pObjectInfo->Fcb->ShareAccess);
2827 IoSetShareAccess( *pDesiredAccess,
2830 &pObjectInfo->Fcb->ShareAccess);
2833 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2835 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2836 AFS_TRACE_LEVEL_VERBOSE,
2837 "AFSProcessOpen Increment handle count on Fcb %p Cnt %d\n",
2842 // Increment the open reference and handle on the parent node
2845 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2847 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2848 AFS_TRACE_LEVEL_VERBOSE,
2849 "AFSProcessOpen Increment child open handle count on Parent object %p Cnt %d\n",
2853 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2855 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2856 AFS_TRACE_LEVEL_VERBOSE,
2857 "AFSProcessOpen Increment child open ref count on Parent object %p Cnt %d\n",
2861 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2865 // Mark it for delete on close
2868 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2869 AFS_TRACE_LEVEL_VERBOSE,
2870 "AFSProcessOpen (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2873 &DirectoryCB->NameInformation.FileName);
2875 SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2879 // Indicate the object is held
2882 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2885 // Return the open result for this file
2888 Irp->IoStatus.Information = FILE_OPENED;
2890 *Fcb = pObjectInfo->Fcb;
2897 if( !NT_SUCCESS( ntStatus))
2900 // Decrement the open count on this Fcb
2903 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2905 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2906 AFS_TRACE_LEVEL_VERBOSE,
2907 "AFSProcessOpen Decrement2 count on Fcb %p Cnt %d\n",
2912 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2915 if( !NT_SUCCESS( ntStatus))
2918 if ( ulFileAccess > 0)
2921 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2923 stReleaseFileAccess.FileAccess = ulFileAccess;
2925 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2927 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2928 AFS_REQUEST_FLAG_SYNCHRONOUS,
2930 &DirectoryCB->NameInformation.FileName,
2931 &pObjectInfo->FileId,
2932 (void *)&stReleaseFileAccess,
2933 sizeof( AFSFileAccessReleaseCB),
2948 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2959 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
2961 IN AFSVolumeCB *VolumeCB,
2963 IN AFSDirectoryCB *ParentDirCB,
2964 IN AFSDirectoryCB *DirectoryCB,
2968 UNREFERENCED_PARAMETER(DeviceObject);
2969 NTSTATUS ntStatus = STATUS_SUCCESS;
2970 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2971 PFILE_OBJECT pFileObject = NULL;
2972 LARGE_INTEGER liZero = {0,0};
2973 BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
2974 ULONG ulAttributes = 0;
2975 ULONG ulCreateDisposition = 0;
2976 BOOLEAN bAllocatedCcb = FALSE;
2977 BOOLEAN bUserMapped = FALSE;
2978 PACCESS_MASK pDesiredAccess = NULL;
2979 USHORT usShareAccess;
2980 AFSObjectInfoCB *pParentObjectInfo = NULL;
2981 AFSObjectInfoCB *pObjectInfo = NULL;
2983 LARGE_INTEGER liSaveSize;
2984 LARGE_INTEGER liSaveVDL;
2985 LARGE_INTEGER liSaveAlloc;
2990 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2992 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2994 pFileObject = pIrpSp->FileObject;
2996 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
2998 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
3000 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
3003 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3004 AFS_TRACE_LEVEL_ERROR,
3005 "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3007 &DirectoryCB->NameInformation.FileName);
3009 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3012 pParentObjectInfo = ParentDirCB->ObjectInformation;
3014 pObjectInfo = DirectoryCB->ObjectInformation;
3016 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3017 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
3020 // Check if we should go and retrieve updated information for the node
3023 ntStatus = AFSValidateEntry( DirectoryCB,
3028 if( !NT_SUCCESS( ntStatus))
3031 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3032 AFS_TRACE_LEVEL_ERROR,
3033 "AFSProcessOverwriteSupersede (%p) Failed to validate entry %wZ Status %08lX\n",
3035 &DirectoryCB->NameInformation.FileName,
3038 try_return( ntStatus);
3042 // Be sure we have an Fcb for the object block
3045 ntStatus = AFSInitFcb( DirectoryCB);
3047 *Fcb = pObjectInfo->Fcb;
3049 if( !NT_SUCCESS( ntStatus))
3052 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3053 AFS_TRACE_LEVEL_ERROR,
3054 "AFSProcessOverwriteSupersede (%p) Failed to initialize fcb %wZ Status %08lX\n",
3056 &DirectoryCB->NameInformation.FileName,
3059 try_return( ntStatus);
3062 ntStatus = STATUS_SUCCESS;
3065 // Increment the open count on this Fcb.
3068 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3070 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3071 AFS_TRACE_LEVEL_VERBOSE,
3072 "AFSProcessOverwriteSupersede Increment2 count on Fcb %p Cnt %d\n",
3079 // Check access on the entry
3082 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3085 ntStatus = IoCheckShareAccess( *pDesiredAccess,
3088 &pObjectInfo->Fcb->ShareAccess,
3091 if( !NT_SUCCESS( ntStatus))
3094 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3095 AFS_TRACE_LEVEL_ERROR,
3096 "AFSProcessOverwriteSupersede (%p) Access check failure %wZ Status %08lX\n",
3098 &DirectoryCB->NameInformation.FileName,
3101 try_return( ntStatus);
3105 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3106 AFS_TRACE_LEVEL_VERBOSE,
3107 "AFSProcessOverwriteSupercede Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3108 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3109 PsGetCurrentThread());
3111 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3115 // Before we actually truncate, check to see if the purge
3116 // is going to fail.
3119 bUserMapped = !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3122 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3123 AFS_TRACE_LEVEL_VERBOSE,
3124 "AFSProcessOverwriteSupercede Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3125 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3126 PsGetCurrentThread());
3128 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3133 ntStatus = STATUS_USER_MAPPED_FILE;
3135 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3136 AFS_TRACE_LEVEL_ERROR,
3137 "AFSProcessOverwriteSupersede (%p) File user mapped %wZ Status %08lX\n",
3139 &DirectoryCB->NameInformation.FileName,
3142 try_return( ntStatus);
3146 // Initialize the Ccb for the file.