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 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
419 AFS_TRACE_LEVEL_VERBOSE,
420 "AFSCommonCreate (%p) Invalid name %wZ Status %08lX\n",
425 try_return( ntStatus);
429 // Opening a reparse point directly?
432 ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
434 if( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
436 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
437 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
438 AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
441 uniSubstitutedPathName = uniRootFileName;
443 ntStatus = AFSLocateNameEntry( &stAuthGroup,
448 ulNameProcessingFlags,
452 &NewVolumeReferenceReason,
453 &pNewParentDirectoryCB,
458 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
459 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
460 // the reference on pVolumeCB that was held prior to the call.
461 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
462 // will be released second.
465 lCount = AFSVolumeDecrement( pVolumeCB,
466 VolumeReferenceReason);
468 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
469 AFS_TRACE_LEVEL_VERBOSE,
470 "AFSCommonCreate Decrement count on volume %p Reason %u Cnt %d\n",
472 VolumeReferenceReason,
475 pVolumeCB = pNewVolumeCB;
479 VolumeReferenceReason = NewVolumeReferenceReason;
481 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
483 bReleaseVolume = (pVolumeCB != NULL);
486 // AFSLocateNameEntry does not alter the reference count of
487 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
491 if ( bReleaseParentDir)
494 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
496 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
497 AFS_TRACE_LEVEL_VERBOSE,
498 "AFSCommonCreate DecrementX count on %wZ DE %p Ccb %p Cnt %d\n",
499 &pParentDirectoryCB->NameInformation.FileName,
505 pParentDirectoryCB = pNewParentDirectoryCB;
507 pNewParentDirectoryCB = NULL;
509 bReleaseParentDir = (pParentDirectoryCB != NULL);
517 if( !NT_SUCCESS( ntStatus) &&
518 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
521 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
523 uniSubstitutedPathName.Buffer = NULL;
527 // AFSLocateNameEntry released the Parent while walking the
531 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
532 AFS_TRACE_LEVEL_VERBOSE,
533 "AFSCommonCreate (%p) Failed to locate name entry for %wZ Status %08lX\n",
538 try_return( ntStatus);
542 // Check for STATUS_REPARSE
545 if( ntStatus == STATUS_REPARSE)
548 uniSubstitutedPathName.Buffer = NULL;
551 // Update the information and return
554 Irp->IoStatus.Information = IO_REPARSE;
556 try_return( ntStatus);
560 // If we re-allocated the name, then update our substitute name
563 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
566 uniSubstitutedPathName = uniRootFileName;
571 uniSubstitutedPathName.Buffer = NULL;
575 // Check for a symlink access
578 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
579 pParentDirectoryCB != NULL)
583 // pParentDirectoryCB DirOpenReferenceCount is still held
586 UNICODE_STRING uniFinalComponent;
588 uniFinalComponent.Length = 0;
589 uniFinalComponent.MaximumLength = 0;
590 uniFinalComponent.Buffer = NULL;
592 AFSRetrieveFinalComponent( &uniFileName,
595 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
598 if( !NT_SUCCESS( ntStatus) &&
599 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
602 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
603 AFS_TRACE_LEVEL_VERBOSE,
604 "AFSCommonCreate (%p) Failing access to symlink %wZ Status %08lX\n",
609 try_return( ntStatus);
615 // If we have no parent then this is a root open, be sure there is a directory entry
619 else if( pParentDirectoryCB == NULL &&
620 pDirectoryCB == NULL)
623 pDirectoryCB = pVolumeCB->DirectoryCB;
625 lCount = InterlockedIncrement( &pDirectoryCB->DirOpenReferenceCount);
627 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
628 AFS_TRACE_LEVEL_VERBOSE,
629 "AFSCommonCreate Increment0 count on %wZ DE %p Ccb %p Cnt %d\n",
630 &pDirectoryCB->NameInformation.FileName,
638 if( bOpenTargetDirectory)
642 // If we have a directory cb for the entry then dereference it and reference the parent
645 if( pDirectoryCB != NULL)
648 if ( !bReleaseParentDir)
652 // Perform in this order to prevent thrashing
655 lCount = InterlockedIncrement( &pParentDirectoryCB->DirOpenReferenceCount);
657 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
658 AFS_TRACE_LEVEL_VERBOSE,
659 "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
660 &pParentDirectoryCB->NameInformation.FileName,
665 bReleaseParentDir = TRUE;
669 // Do NOT decrement the reference count on the pDirectoryCB yet.
670 // The BackupEntry below might drop the count to zero leaving
671 // the entry subject to being deleted and we need some of the
672 // contents during later processing
675 AFSBackupEntry( pNameArray);
679 // OK, open the target directory
682 if( uniComponentName.Length == 0)
684 AFSRetrieveFinalComponent( &uniFileName,
688 ntStatus = AFSOpenTargetDirectory( Irp,
696 if( !NT_SUCCESS( ntStatus))
699 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
700 AFS_TRACE_LEVEL_ERROR,
701 "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
702 &pParentDirectoryCB->NameInformation.FileName,
706 try_return( ntStatus);
709 if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
712 if( pDirectoryCB == NULL ||
713 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
715 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
716 AFS_TRACE_LEVEL_VERBOSE,
717 "AFSCommonCreate (%p) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
721 pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0);
725 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
726 AFS_TRACE_LEVEL_VERBOSE,
727 "AFSCommonCreate (%p) Opening as reparse point %wZ Type %08lX\n",
730 pDirectoryCB->ObjectInformation->FileType);
732 bOpenedReparsePoint = TRUE;
737 // Based on the options passed in, process the file accordingly.
740 if( ulCreateDisposition == FILE_CREATE ||
741 ( ( ulCreateDisposition == FILE_OPEN_IF ||
742 ulCreateDisposition == FILE_OVERWRITE_IF) &&
743 pDirectoryCB == NULL))
746 if( uniComponentName.Length == 0 ||
747 pDirectoryCB != NULL)
751 // We traversed the entire path so we found each entry,
752 // fail with collision
755 if( pDirectoryCB != NULL)
758 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
759 AFS_TRACE_LEVEL_VERBOSE,
760 "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
761 &pDirectoryCB->NameInformation.FileName,
767 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
768 AFS_TRACE_LEVEL_VERBOSE,
769 "AFSCommonCreate Object name collision on create Status %08lX\n",
773 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
777 // OK, go and create the node
780 ntStatus = AFSProcessCreate( Irp,
790 if( !NT_SUCCESS( ntStatus))
793 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
794 AFS_TRACE_LEVEL_ERROR,
795 "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
797 &pParentDirectoryCB->NameInformation.FileName,
801 try_return( ntStatus);
805 // We should not have an extra component except for PIOCtl opens
808 if( uniComponentName.Length > 0)
812 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
815 if( RtlCompareUnicodeString( &AFSPIOCtlName,
821 // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
822 // pParentDirectoryCB.
825 ntStatus = AFSOpenIOCtlFcb( Irp,
831 if( !NT_SUCCESS( ntStatus))
834 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
835 AFS_TRACE_LEVEL_ERROR,
836 "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
844 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
845 AFS_TRACE_LEVEL_VERBOSE,
846 "AFSCommonCreate (%p) File %wZ name not found\n",
850 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
853 try_return( ntStatus);
857 // For root opens the parent will be NULL
860 if( pParentDirectoryCB == NULL)
864 // Check for the delete on close flag for the root
867 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
870 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
871 AFS_TRACE_LEVEL_ERROR,
872 "AFSCommonCreate (%p) Attempt to open root as delete on close\n",
875 try_return( ntStatus = STATUS_CANNOT_DELETE);
879 // If this is the target directory, then bail
882 if( bOpenTargetDirectory)
885 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
886 AFS_TRACE_LEVEL_ERROR,
887 "AFSCommonCreate (%p) Attempt to open root as target directory\n",
890 try_return( ntStatus = STATUS_INVALID_PARAMETER);
894 // Go and open the root of the volume
897 ntStatus = AFSOpenRoot( Irp,
903 if( !NT_SUCCESS( ntStatus))
906 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
907 AFS_TRACE_LEVEL_ERROR,
908 "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
909 pVolumeCB->ObjectInformation.FileId.Cell,
910 pVolumeCB->ObjectInformation.FileId.Volume,
914 try_return( ntStatus);
918 // At this point if we have no pDirectoryCB it was not found.
921 if( pDirectoryCB == NULL)
924 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
925 AFS_TRACE_LEVEL_ERROR,
926 "AFSCommonCreate Failing access to %wZ Name not found\n",
929 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
932 if( ulCreateDisposition == FILE_OVERWRITE ||
933 ulCreateDisposition == FILE_SUPERSEDE ||
934 ulCreateDisposition == FILE_OVERWRITE_IF)
938 // Go process a file for overwrite or supersede.
941 ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
950 if( !NT_SUCCESS( ntStatus))
953 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
954 AFS_TRACE_LEVEL_ERROR,
955 "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
956 &pDirectoryCB->NameInformation.FileName,
960 try_return( ntStatus);
964 // Trying to open the file
967 ntStatus = AFSProcessOpen( Irp,
975 if( !NT_SUCCESS( ntStatus))
978 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
979 AFS_TRACE_LEVEL_ERROR,
980 "AFSCommonCreate Failed open on %wZ Status %08lX\n",
981 &pDirectoryCB->NameInformation.FileName,
987 if( NT_SUCCESS( ntStatus) &&
988 ntStatus != STATUS_REPARSE)
994 AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
997 RtlCopyMemory( &pCcb->AuthGroup,
1002 // If we have a substitute name, then use it
1005 if( uniSubstitutedPathName.Buffer != NULL)
1008 pCcb->FullFileName = uniSubstitutedPathName;
1010 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1012 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1017 pCcb->FullFileName = uniRootFileName;
1019 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1022 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1024 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1028 if( bOpenedReparsePoint)
1030 SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1033 lCount = pCcb->DirectoryCB->DirOpenReferenceCount;
1035 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1036 AFS_TRACE_LEVEL_VERBOSE,
1037 "AFSCommonCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1038 &pCcb->DirectoryCB->NameInformation.FileName,
1043 ASSERT( lCount >= 0);
1045 pCcb->CurrentDirIndex = 0;
1047 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1050 SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1054 // Save off the name array for this instance
1057 pCcb->NameArray = pNameArray;
1061 AFSReleaseResource( &pCcb->NPCcb->CcbLock);
1065 // If we make it here then init the FO for the request.
1068 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1069 AFS_TRACE_LEVEL_VERBOSE_2,
1070 "AFSCommonCreate (%p) FileObject %p FsContext %p FsContext2 %p\n",
1076 pFileObject->FsContext = (void *)pFcb;
1078 pFileObject->FsContext2 = (void *)pCcb;
1083 ASSERT( pFcb->OpenHandleCount > 0);
1085 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1088 // For files perform additional processing
1091 switch( pFcb->Header.NodeTypeCode)
1098 pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1103 // If the user did not request nobuffering then mark the FO as cacheable
1106 if( bNoIntermediateBuffering)
1109 pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1114 pFileObject->Flags |= FO_CACHE_SUPPORTED;
1118 // If the file was opened for execution then we need to set the bit in the FO
1121 if( BooleanFlagOn( *pDesiredAccess,
1125 SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1129 // Update the last access time
1132 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1143 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1144 AFS_TRACE_LEVEL_ERROR,
1145 "AFSCommonCreate (%p) Returning with NULL Fcb FileObject %p FsContext %p FsContext2 %p\n",
1154 if( NT_SUCCESS( ntStatus) &&
1155 ntStatus == STATUS_REPARSE)
1158 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1159 AFS_TRACE_LEVEL_ERROR,
1160 "AFSCommonCreate (%p) STATUS_REPARSE FileObject %p FsContext %p FsContext2 %p\n",
1168 // Free up the sub name if we have one
1171 if( uniSubstitutedPathName.Buffer != NULL)
1174 AFSExFreePoolWithTag( uniSubstitutedPathName.Buffer, 0);
1176 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1181 // Free up the name array ...
1184 if( pNameArray != NULL)
1187 AFSFreeNameArray( pNameArray);
1190 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1193 AFSExFreePoolWithTag( uniRootFileName.Buffer, 0);
1199 lCount = AFSVolumeDecrement( pVolumeCB,
1200 VolumeReferenceReason);
1202 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1203 AFS_TRACE_LEVEL_VERBOSE,
1204 "AFSCommonCreate Decrement count on Volume %08lX Reason %u Cnt %d\n",
1206 VolumeReferenceReason,
1214 // Release the reference from AFSLocateNameEntry
1217 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
1219 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1220 AFS_TRACE_LEVEL_VERBOSE,
1221 "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1222 &pDirectoryCB->NameInformation.FileName,
1227 ASSERT( lCount >= 0);
1230 if ( bReleaseParentDir)
1234 // Release the reference from AFSLocateNameEntry
1237 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
1239 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1240 AFS_TRACE_LEVEL_VERBOSE,
1241 "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1242 &pParentDirectoryCB->NameInformation.FileName,
1247 ASSERT( lCount >= 0);
1251 // Setup the Irp for completion, the Information has been set previously
1254 Irp->IoStatus.Status = ntStatus;
1261 AFSOpenAFSRoot( IN PIRP Irp,
1266 NTSTATUS ntStatus = STATUS_SUCCESS;
1273 // Initialize the Ccb for the file.
1276 ntStatus = AFSInitCcb( Ccb,
1277 AFSGlobalRoot->DirectoryCB,
1281 if( !NT_SUCCESS( ntStatus))
1284 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1285 AFS_TRACE_LEVEL_ERROR,
1286 "AFSOpenAFSRoot (%p) Failed to allocate Ccb\n",
1289 try_return( ntStatus);
1293 // Increment the open count on this Fcb
1296 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1298 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1299 AFS_TRACE_LEVEL_VERBOSE,
1300 "AFSOpenAFSRoot Increment count on Fcb %p Cnt %d\n",
1301 AFSGlobalRoot->RootFcb,
1304 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1306 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1307 AFS_TRACE_LEVEL_VERBOSE,
1308 "AFSOpenAFSRoot Increment handle count on Fcb %p Cnt %d\n",
1309 AFSGlobalRoot->RootFcb,
1312 *Fcb = AFSGlobalRoot->RootFcb;
1315 // Return the open result for this file
1318 Irp->IoStatus.Information = FILE_OPENED;
1329 AFSOpenRoot( IN PIRP Irp,
1330 IN AFSVolumeCB *VolumeCB,
1332 OUT AFSFcb **RootFcb,
1336 NTSTATUS ntStatus = STATUS_SUCCESS;
1337 PFILE_OBJECT pFileObject = NULL;
1338 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1339 PACCESS_MASK pDesiredAccess = NULL;
1340 USHORT usShareAccess;
1342 BOOLEAN bAllocatedCcb = FALSE;
1343 BOOLEAN bReleaseFcb = FALSE;
1344 AFSFileOpenCB stOpenCB;
1345 AFSFileOpenResultCB stOpenResultCB;
1346 ULONG ulResultLen = 0;
1352 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1353 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1354 ulOptions = pIrpSp->Parameters.Create.Options;
1356 pFileObject = pIrpSp->FileObject;
1358 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1361 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1363 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1364 AFS_TRACE_LEVEL_ERROR,
1365 "AFSOpenRoot (%p) Attempt to open root as file Status %08lX\n",
1369 try_return( ntStatus);
1373 // Check if we should go and retrieve updated information for the node
1376 ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1381 if( !NT_SUCCESS( ntStatus))
1384 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1385 AFS_TRACE_LEVEL_ERROR,
1386 "AFSOpenRoot (%p) Failed to validate root entry Status %08lX\n",
1390 try_return( ntStatus);
1394 // Check with the service that we can open the file
1397 RtlZeroMemory( &stOpenCB,
1398 sizeof( AFSFileOpenCB));
1400 stOpenCB.DesiredAccess = *pDesiredAccess;
1402 stOpenCB.ShareAccess = usShareAccess;
1404 stOpenResultCB.GrantedAccess = 0;
1406 ulResultLen = sizeof( AFSFileOpenResultCB);
1408 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1409 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1412 &VolumeCB->ObjectInformation.FileId,
1413 VolumeCB->VolumeInformation.Cell,
1414 VolumeCB->VolumeInformation.CellLength,
1416 sizeof( AFSFileOpenCB),
1417 (void *)&stOpenResultCB,
1420 if( !NT_SUCCESS( ntStatus))
1423 UNICODE_STRING uniGUID;
1426 uniGUID.MaximumLength = 0;
1427 uniGUID.Buffer = NULL;
1429 if( AuthGroup != NULL)
1431 RtlStringFromGUID( *AuthGroup,
1435 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1436 AFS_TRACE_LEVEL_ERROR,
1437 "AFSOpenRoot (%p) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1439 VolumeCB->ObjectInformation.FileId.Cell,
1440 VolumeCB->ObjectInformation.FileId.Volume,
1444 if( AuthGroup != NULL)
1446 RtlFreeUnicodeString( &uniGUID);
1449 try_return( ntStatus);
1453 // If the entry is not initialized then do it now
1456 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1459 AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1462 ntStatus = AFSEnumerateDirectory( AuthGroup,
1463 &VolumeCB->ObjectInformation,
1466 if( !NT_SUCCESS( ntStatus))
1469 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1471 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1472 AFS_TRACE_LEVEL_ERROR,
1473 "AFSOpenRoot (%p) Failed to enumerate directory Status %08lX\n",
1477 try_return( ntStatus);
1480 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1484 // If the root fcb has been initialized then check access otherwise
1485 // init the volume fcb
1488 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1491 if( !NT_SUCCESS( ntStatus))
1494 try_return( ntStatus);
1497 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1499 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1500 AFS_TRACE_LEVEL_VERBOSE,
1501 "AFSOpenRoot Increment count on Fcb %p Cnt %d\n",
1508 // If there are current opens on the Fcb, check the access.
1511 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1514 ntStatus = IoCheckShareAccess( *pDesiredAccess,
1517 &VolumeCB->RootFcb->ShareAccess,
1520 if( !NT_SUCCESS( ntStatus))
1523 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1524 AFS_TRACE_LEVEL_ERROR,
1525 "AFSOpenRoot (%p) Access check failure Status %08lX\n",
1529 try_return( ntStatus);
1534 // Initialize the Ccb for the file.
1537 ntStatus = AFSInitCcb( Ccb,
1538 VolumeCB->DirectoryCB,
1542 if( !NT_SUCCESS( ntStatus))
1545 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1546 AFS_TRACE_LEVEL_ERROR,
1547 "AFSOpenRoot (%p) Failed to allocate Ccb Status %08lX\n",
1551 try_return( ntStatus);
1554 bAllocatedCcb = TRUE;
1557 // OK, update the share access on the fileobject
1560 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1563 IoUpdateShareAccess( pFileObject,
1564 &VolumeCB->RootFcb->ShareAccess);
1573 IoSetShareAccess( *pDesiredAccess,
1576 &VolumeCB->RootFcb->ShareAccess);
1580 // Increment the open count on this Fcb
1583 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1585 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1586 AFS_TRACE_LEVEL_VERBOSE,
1587 "AFSOpenRoot Increment handle count on Fcb %p Cnt %d\n",
1592 // Indicate the object is held
1595 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1598 // Return the open result for this file
1601 Irp->IoStatus.Information = FILE_OPENED;
1603 *RootFcb = VolumeCB->RootFcb;
1609 if ( !NT_SUCCESS( ntStatus))
1612 lCount = InterlockedDecrement( &VolumeCB->RootFcb->OpenReferenceCount);
1614 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1615 AFS_TRACE_LEVEL_VERBOSE,
1616 "AFSOpenRoot Decrement count on Fcb %p Cnt %d\n",
1621 AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1624 if( !NT_SUCCESS( ntStatus))
1636 Irp->IoStatus.Information = 0;
1644 AFSProcessCreate( IN PIRP Irp,
1646 IN AFSVolumeCB *VolumeCB,
1647 IN AFSDirectoryCB *ParentDirCB,
1648 IN PUNICODE_STRING FileName,
1649 IN PUNICODE_STRING ComponentName,
1650 IN PUNICODE_STRING FullFileName,
1655 NTSTATUS ntStatus = STATUS_SUCCESS;
1656 PFILE_OBJECT pFileObject = NULL;
1657 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1658 ULONG ulOptions = 0;
1659 ULONG ulAttributes = 0;
1660 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1661 PACCESS_MASK pDesiredAccess = NULL;
1662 USHORT usShareAccess;
1663 AFSDirectoryCB *pDirEntry = NULL;
1664 AFSObjectInfoCB *pParentObjectInfo = NULL;
1665 AFSObjectInfoCB *pObjectInfo = NULL;
1671 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1672 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1674 pFileObject = pIrpSp->FileObject;
1677 // Extract out the options
1680 ulOptions = pIrpSp->Parameters.Create.Options;
1683 // We pass all attributes they want to apply to the file to the create
1686 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1689 // If this is a directory create then set the attribute correctly
1692 if( ulOptions & FILE_DIRECTORY_FILE)
1695 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1698 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1699 AFS_TRACE_LEVEL_VERBOSE,
1700 "AFSProcessCreate (%p) Creating file %wZ Attributes %08lX\n",
1705 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1708 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1709 AFS_TRACE_LEVEL_ERROR,
1710 "AFSProcessCreate Request failed due to read only volume %wZ\n",
1713 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
1716 pParentObjectInfo = ParentDirCB->ObjectInformation;
1719 // Allocate and insert the direntry into the parent node
1722 ntStatus = AFSCreateDirEntry( AuthGroup,
1730 if( !NT_SUCCESS( ntStatus))
1733 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1734 AFS_TRACE_LEVEL_ERROR,
1735 "AFSProcessCreate (%p) Failed to create directory entry %wZ Status %08lX\n",
1740 try_return( ntStatus);
1743 bFileCreated = TRUE;
1745 pObjectInfo = pDirEntry->ObjectInformation;
1747 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1748 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1751 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1752 AFS_TRACE_LEVEL_VERBOSE,
1753 "AFSProcessCreate (%p) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1755 &pDirEntry->NameInformation.FileName,
1756 pObjectInfo->FileId.Cell,
1757 pObjectInfo->FileId.Volume,
1758 pObjectInfo->FileId.Vnode,
1759 pObjectInfo->FileId.Unique);
1761 ntStatus = AFSEvaluateNode( AuthGroup,
1764 if( !NT_SUCCESS( ntStatus))
1767 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
1770 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1773 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1774 AFS_TRACE_LEVEL_ERROR,
1775 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
1777 &pDirEntry->NameInformation.FileName,
1778 pObjectInfo->FileId.Cell,
1779 pObjectInfo->FileId.Volume,
1780 pObjectInfo->FileId.Vnode,
1781 pObjectInfo->FileId.Unique,
1782 pParentObjectInfo->FileId.Cell,
1783 pParentObjectInfo->FileId.Volume,
1784 pParentObjectInfo->FileId.Vnode,
1785 pParentObjectInfo->FileId.Unique,
1788 else if ( AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId))
1791 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1792 AFS_TRACE_LEVEL_ERROR,
1793 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1795 &pDirEntry->NameInformation.FileName,
1796 pObjectInfo->FileId.Cell,
1797 pObjectInfo->FileId.Volume,
1798 pObjectInfo->FileId.Vnode,
1799 pObjectInfo->FileId.Unique,
1800 pParentObjectInfo->FileId.Cell,
1801 pParentObjectInfo->FileId.Volume,
1802 pParentObjectInfo->FileId.Vnode,
1803 pParentObjectInfo->FileId.Unique,
1809 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1810 AFS_TRACE_LEVEL_ERROR,
1811 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1813 &pDirEntry->NameInformation.FileName,
1814 pObjectInfo->FileId.Cell,
1815 pObjectInfo->FileId.Volume,
1816 pObjectInfo->FileId.Vnode,
1817 pObjectInfo->FileId.Unique,
1818 pParentObjectInfo->FileId.Cell,
1819 pParentObjectInfo->FileId.Volume,
1820 pParentObjectInfo->FileId.Vnode,
1821 pParentObjectInfo->FileId.Unique,
1822 pObjectInfo->ParentFileId.Cell,
1823 pObjectInfo->ParentFileId.Volume,
1824 pObjectInfo->ParentFileId.Vnode,
1825 pObjectInfo->ParentFileId.Unique,
1832 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1833 AFS_TRACE_LEVEL_ERROR,
1834 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1836 &pDirEntry->NameInformation.FileName,
1837 pObjectInfo->FileId.Cell,
1838 pObjectInfo->FileId.Volume,
1839 pObjectInfo->FileId.Vnode,
1840 pObjectInfo->FileId.Unique,
1844 try_return( ntStatus);
1847 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1850 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
1851 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
1854 // We may have raced and the Fcb is already created
1858 // Allocate and initialize the Fcb for the file.
1861 ntStatus = AFSInitFcb( pDirEntry);
1863 *Fcb = pObjectInfo->Fcb;
1865 if( !NT_SUCCESS( ntStatus))
1868 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1869 AFS_TRACE_LEVEL_ERROR,
1870 "AFSProcessCreate (%p) Failed to initialize fcb %wZ Status %08lX\n",
1875 try_return( ntStatus);
1878 ntStatus = STATUS_SUCCESS;
1881 // Increment the open count on this Fcb
1884 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1886 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1887 AFS_TRACE_LEVEL_VERBOSE,
1888 "AFSProcessCreate Increment count on Fcb %p Cnt %d\n",
1895 // Initialize the Ccb for the file.
1898 ntStatus = AFSInitCcb( Ccb,
1903 if( !NT_SUCCESS( ntStatus))
1906 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1907 AFS_TRACE_LEVEL_ERROR,
1908 "AFSProcessCreate (%p) Failed to initialize ccb %wZ Status %08lX\n",
1913 try_return( ntStatus);
1916 bAllocatedCcb = TRUE;
1919 // If this is a file, update the headers filesizes.
1922 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1926 // Update the sizes with the information passed in
1929 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
1930 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1931 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1934 // Notify the system of the addition
1937 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1939 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1940 (ULONG)FILE_ACTION_ADDED);
1942 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
1944 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1948 // This is a new directory node so indicate it has been enumerated
1951 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1954 // And the parent directory entry
1957 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1960 // Notify the system of the addition
1963 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1965 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1966 (ULONG)FILE_ACTION_ADDED);
1968 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
1969 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
1970 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
1971 (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
1975 // And the parent directory entry
1978 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1981 // Notify the system of the addition
1984 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1986 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1987 (ULONG)FILE_ACTION_ADDED);
1991 // Save off the access for the open
1994 IoSetShareAccess( *pDesiredAccess,
1997 &(*Fcb)->ShareAccess);
1999 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2001 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2002 AFS_TRACE_LEVEL_VERBOSE,
2003 "AFSProcessCreate Increment handle count on Fcb %p Cnt %d\n",
2008 // Increment the open reference and handle on the parent node
2011 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2013 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2014 AFS_TRACE_LEVEL_VERBOSE,
2015 "AFSProcessCreate Increment child open handle count on Parent object %p Cnt %d\n",
2019 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2021 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2022 AFS_TRACE_LEVEL_VERBOSE,
2023 "AFSProcessCreate Increment child open ref count on Parent object %p Cnt %d\n",
2027 if( ulOptions & FILE_DELETE_ON_CLOSE)
2031 // Mark it for delete on close
2034 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2035 AFS_TRACE_LEVEL_VERBOSE,
2036 "AFSProcessCreate (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2041 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2045 // Indicate the object is locked in the service
2048 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2051 // Return the open result for this file
2054 Irp->IoStatus.Information = FILE_CREATED;
2059 // If we created the Fcb we need to release the resources
2065 if( !NT_SUCCESS( ntStatus))
2068 // Decrement the open count on this Fcb
2071 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2073 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2074 AFS_TRACE_LEVEL_VERBOSE,
2075 "AFSProcessCreate Decrement count on Fcb %p Cnt %d\n",
2080 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2087 // Decrement the reference added during initialization of the DE
2088 // AFSInitCcb allocates its own reference count.
2091 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2093 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2094 AFS_TRACE_LEVEL_VERBOSE,
2095 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2096 &pDirEntry->NameInformation.FileName,
2100 ASSERT( lCount >= 0);
2103 if( !NT_SUCCESS( ntStatus))
2109 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2110 AFS_TRACE_LEVEL_VERBOSE,
2111 "AFSProcessCreate Create failed, removing DE %p from parent object %p Status %08lX\n",
2117 // Remove the dir entry from the parent
2120 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2123 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2125 AFSNotifyDelete( pDirEntry,
2130 // Pull the directory entry from the parent
2133 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2135 FALSE); // Leave it in the enum list so the worker cleans it up
2138 // Tag the parent as needing verification
2141 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2143 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2145 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2156 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2169 AFSOpenTargetDirectory( IN PIRP Irp,
2170 IN AFSVolumeCB *VolumeCB,
2171 IN AFSDirectoryCB *ParentDirectoryCB,
2172 IN AFSDirectoryCB *TargetDirectoryCB,
2173 IN UNICODE_STRING *TargetName,
2177 UNREFERENCED_PARAMETER(VolumeCB);
2178 NTSTATUS ntStatus = STATUS_SUCCESS;
2179 PFILE_OBJECT pFileObject = NULL;
2180 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2181 PACCESS_MASK pDesiredAccess = NULL;
2182 USHORT usShareAccess;
2183 BOOLEAN bAllocatedCcb = FALSE;
2184 BOOLEAN bReleaseFcb = FALSE;
2185 AFSObjectInfoCB *pParentObject = NULL;
2186 AFSObjectInfoCB *pGrandParentObject = NULL;
2187 UNICODE_STRING uniTargetName;
2193 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2194 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2196 pFileObject = pIrpSp->FileObject;
2198 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2199 AFS_TRACE_LEVEL_VERBOSE,
2200 "AFSOpenTargetDirectory (%p) Processing file %wZ\n",
2204 pParentObject = ParentDirectoryCB->ObjectInformation;
2206 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2209 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2213 // Make sure we have an Fcb for the access
2216 // Allocate and initialize the Fcb for the file.
2219 ntStatus = AFSInitFcb( ParentDirectoryCB);
2221 *Fcb = pParentObject->Fcb;
2223 if( !NT_SUCCESS( ntStatus))
2226 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2227 AFS_TRACE_LEVEL_ERROR,
2228 "AFSOpenTargetDirectory (%p) Failed to initialize fcb %wZ Status %08lX\n",
2230 &ParentDirectoryCB->NameInformation.FileName,
2233 try_return( ntStatus);
2236 ntStatus = STATUS_SUCCESS;
2239 // Increment the open count on this Fcb
2242 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2244 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2245 AFS_TRACE_LEVEL_VERBOSE,
2246 "AFSOpenTargetDirectory Increment count on Fcb %p Cnt %d\n",
2253 // If there are current opens on the Fcb, check the access.
2256 if( pParentObject->Fcb->OpenHandleCount > 0)
2259 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2262 &pParentObject->Fcb->ShareAccess,
2265 if( !NT_SUCCESS( ntStatus))
2268 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2269 AFS_TRACE_LEVEL_ERROR,
2270 "AFSOpenTargetDirectory (%p) Access check failure %wZ Status %08lX\n",
2272 &ParentDirectoryCB->NameInformation.FileName,
2275 try_return( ntStatus);
2280 // Initialize the Ccb for the file.
2283 ntStatus = AFSInitCcb( Ccb,
2288 if( !NT_SUCCESS( ntStatus))
2291 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2292 AFS_TRACE_LEVEL_ERROR,
2293 "AFSOpenTargetDirectory (%p) Failed to initialize ccb %wZ Status %08lX\n",
2295 &ParentDirectoryCB->NameInformation.FileName,
2298 try_return( ntStatus);
2301 bAllocatedCcb = TRUE;
2303 if( TargetDirectoryCB != NULL &&
2304 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2310 Irp->IoStatus.Information = FILE_EXISTS;
2312 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2317 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2319 uniTargetName = *TargetName;
2323 // Update the filename in the fileobject for rename processing
2326 RtlCopyMemory( pFileObject->FileName.Buffer,
2327 uniTargetName.Buffer,
2328 uniTargetName.Length);
2330 pFileObject->FileName.Length = uniTargetName.Length;
2333 // OK, update the share access on the fileobject
2336 if( pParentObject->Fcb->OpenHandleCount > 0)
2339 IoUpdateShareAccess( pFileObject,
2340 &pParentObject->Fcb->ShareAccess);
2349 IoSetShareAccess( *pDesiredAccess,
2352 &pParentObject->Fcb->ShareAccess);
2355 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2357 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2358 AFS_TRACE_LEVEL_VERBOSE,
2359 "AFSOpenTargetDirectory Increment handle count on Fcb %p Cnt %d\n",
2364 // Increment the open reference and handle on the parent node
2367 if( BooleanFlagOn( pParentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2370 pGrandParentObject = AFSFindObjectInfo( pParentObject->VolumeCB,
2371 &pParentObject->ParentFileId);
2373 if ( pGrandParentObject)
2376 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenHandleCount);
2378 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2379 AFS_TRACE_LEVEL_VERBOSE,
2380 "AFSOpenTargetDirectory Increment child open handle count on Parent object %p Cnt %d\n",
2384 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenReferenceCount);
2386 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2387 AFS_TRACE_LEVEL_VERBOSE,
2388 "AFSOpenTargetDirectory Increment child open ref count on Parent object %p Cnt %d\n",
2392 AFSReleaseObjectInfo( &pGrandParentObject);
2401 if( !NT_SUCCESS( ntStatus))
2404 // Decrement the open count on this Fcb
2407 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2409 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2410 AFS_TRACE_LEVEL_VERBOSE,
2411 "AFSOpenTargetDirectory Decrement count on Fcb %p Cnt %d\n",
2416 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2419 if( !NT_SUCCESS( ntStatus))
2432 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2443 AFSProcessOpen( IN PIRP Irp,
2445 IN AFSVolumeCB *VolumeCB,
2446 IN AFSDirectoryCB *ParentDirCB,
2447 IN AFSDirectoryCB *DirectoryCB,
2451 UNREFERENCED_PARAMETER(VolumeCB);
2452 NTSTATUS ntStatus = STATUS_SUCCESS;
2453 PFILE_OBJECT pFileObject = NULL;
2454 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2455 PACCESS_MASK pDesiredAccess = NULL;
2456 USHORT usShareAccess;
2457 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE;
2458 ULONG ulOptions = 0;
2459 AFSFileOpenCB stOpenCB;
2460 AFSFileOpenResultCB stOpenResultCB;
2461 ULONG ulResultLen = 0;
2462 AFSObjectInfoCB *pParentObjectInfo = NULL;
2463 AFSObjectInfoCB *pObjectInfo = NULL;
2464 ULONG ulFileAccess = 0;
2465 AFSFileAccessReleaseCB stReleaseFileAccess;
2471 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2472 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2474 pFileObject = pIrpSp->FileObject;
2476 pParentObjectInfo = ParentDirCB->ObjectInformation;
2478 pObjectInfo = DirectoryCB->ObjectInformation;
2480 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2481 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
2484 // Check if the entry is pending a deletion
2487 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2490 ntStatus = STATUS_DELETE_PENDING;
2492 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2493 AFS_TRACE_LEVEL_ERROR,
2494 "AFSProcessOpen (%p) Entry pending delete %wZ Status %08lX\n",
2496 &DirectoryCB->NameInformation.FileName,
2499 try_return( ntStatus);
2503 // Extract out the options
2506 ulOptions = pIrpSp->Parameters.Create.Options;
2509 // Check if we should go and retrieve updated information for the node
2512 ntStatus = AFSValidateEntry( DirectoryCB,
2517 if( !NT_SUCCESS( ntStatus))
2520 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2521 AFS_TRACE_LEVEL_ERROR,
2522 "AFSProcessOpen (%p) Failed to validate entry %wZ Status %08lX\n",
2524 &DirectoryCB->NameInformation.FileName,
2527 try_return( ntStatus);
2531 // If this is marked for delete on close then be sure we can delete the entry
2534 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2537 ntStatus = AFSNotifyDelete( DirectoryCB,
2541 if( !NT_SUCCESS( ntStatus))
2544 ntStatus = STATUS_CANNOT_DELETE;
2546 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2547 AFS_TRACE_LEVEL_ERROR,
2548 "AFSProcessOpen (%p) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2550 &DirectoryCB->NameInformation.FileName,
2553 try_return( ntStatus);
2558 // Be sure we have an Fcb for the current object
2561 ntStatus = AFSInitFcb( DirectoryCB);
2563 if( !NT_SUCCESS( ntStatus))
2566 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2567 AFS_TRACE_LEVEL_ERROR,
2568 "AFSProcessOpen (%p) Failed to init fcb on %wZ Status %08lX\n",
2570 &DirectoryCB->NameInformation.FileName,
2573 try_return( ntStatus);
2576 ntStatus = STATUS_SUCCESS;
2579 // AFSInitFcb returns the Fcb resource held
2585 // Increment the open count on this Fcb
2588 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2590 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2591 AFS_TRACE_LEVEL_VERBOSE,
2592 "AFSProcessOpen Increment2 count on Fcb %p Cnt %d\n",
2597 // Check access on the entry
2600 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2603 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2606 &pObjectInfo->Fcb->ShareAccess,
2609 if( !NT_SUCCESS( ntStatus))
2612 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2613 AFS_TRACE_LEVEL_ERROR,
2614 "AFSProcessOpen (%p) Failed to check share access on %wZ Status %08lX\n",
2616 &DirectoryCB->NameInformation.FileName,
2619 try_return( ntStatus);
2624 // Additional checks
2627 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2631 // If the caller is asking for write access then try to flush the image section
2634 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2635 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2640 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2641 AFS_TRACE_LEVEL_VERBOSE,
2642 "AFSProcessOpen Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2643 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2644 PsGetCurrentThread());
2646 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2649 bMmFlushed = MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2652 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2653 AFS_TRACE_LEVEL_VERBOSE,
2654 "AFSProcessOpen Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2655 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2656 PsGetCurrentThread());
2658 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
2663 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2664 STATUS_SHARING_VIOLATION;
2666 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2667 AFS_TRACE_LEVEL_ERROR,
2668 "AFSProcessOpen (%p) Failed to flush image section %wZ Status %08lX\n",
2670 &DirectoryCB->NameInformation.FileName,
2673 try_return( ntStatus);
2677 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2680 ntStatus = STATUS_NOT_A_DIRECTORY;
2682 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2683 AFS_TRACE_LEVEL_ERROR,
2684 "AFSProcessOpen (%p) Attempt to open file as directory %wZ Status %08lX\n",
2686 &DirectoryCB->NameInformation.FileName,
2689 try_return( ntStatus);
2692 pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2694 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2695 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2698 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2701 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2703 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2704 AFS_TRACE_LEVEL_ERROR,
2705 "AFSProcessOpen (%p) Attempt to open directory as file %wZ Status %08lX\n",
2707 &DirectoryCB->NameInformation.FileName,
2710 try_return( ntStatus);
2713 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2714 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2715 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2716 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2723 try_return( ntStatus = STATUS_UNSUCCESSFUL);
2727 // Check with the service that we can open the file
2730 stOpenCB.ParentId = pParentObjectInfo->FileId;
2732 stOpenCB.DesiredAccess = *pDesiredAccess;
2734 stOpenCB.ShareAccess = usShareAccess;
2736 stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2738 stOpenCB.Identifier = (ULONGLONG)pFileObject;
2740 stOpenResultCB.GrantedAccess = 0;
2742 ulResultLen = sizeof( AFSFileOpenResultCB);
2744 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2745 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2747 &DirectoryCB->NameInformation.FileName,
2748 &pObjectInfo->FileId,
2749 pObjectInfo->VolumeCB->VolumeInformation.Cell,
2750 pObjectInfo->VolumeCB->VolumeInformation.CellLength,
2752 sizeof( AFSFileOpenCB),
2753 (void *)&stOpenResultCB,
2756 if( !NT_SUCCESS( ntStatus))
2759 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2760 AFS_TRACE_LEVEL_ERROR,
2761 "AFSProcessOpen (%p) Failed open in service %wZ Status %08lX\n",
2763 &DirectoryCB->NameInformation.FileName,
2766 try_return( ntStatus);
2770 // Save the granted access in case we need to release it below
2773 ulFileAccess = stOpenResultCB.FileAccess;
2776 // Check if there is a conflict
2779 if( !AFSCheckAccess( *pDesiredAccess,
2780 stOpenResultCB.GrantedAccess,
2781 BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2784 ntStatus = STATUS_ACCESS_DENIED;
2786 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2787 AFS_TRACE_LEVEL_ERROR,
2788 "AFSProcessOpen (%p) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2791 stOpenResultCB.GrantedAccess,
2792 &DirectoryCB->NameInformation.FileName,
2795 try_return( ntStatus);
2799 // Initialize the Ccb for the file.
2802 ntStatus = AFSInitCcb( Ccb,
2807 if( !NT_SUCCESS( ntStatus))
2810 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2811 AFS_TRACE_LEVEL_ERROR,
2812 "AFSProcessOpen (%p) Failed to initialize ccb %wZ Status %08lX\n",
2814 &DirectoryCB->NameInformation.FileName,
2817 try_return( ntStatus);
2820 bAllocatedCcb = TRUE;
2823 // Perform the access check on the target if this is a mount point or symlink
2826 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2829 IoUpdateShareAccess( pFileObject,
2830 &pObjectInfo->Fcb->ShareAccess);
2839 IoSetShareAccess( *pDesiredAccess,
2842 &pObjectInfo->Fcb->ShareAccess);
2845 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2847 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2848 AFS_TRACE_LEVEL_VERBOSE,
2849 "AFSProcessOpen Increment handle count on Fcb %p Cnt %d\n",
2854 // Increment the open reference and handle on the parent node
2857 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2859 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2860 AFS_TRACE_LEVEL_VERBOSE,
2861 "AFSProcessOpen Increment child open handle count on Parent object %p Cnt %d\n",
2865 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2867 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2868 AFS_TRACE_LEVEL_VERBOSE,
2869 "AFSProcessOpen Increment child open ref count on Parent object %p Cnt %d\n",
2873 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2877 // Mark it for delete on close
2880 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2881 AFS_TRACE_LEVEL_VERBOSE,
2882 "AFSProcessOpen (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2885 &DirectoryCB->NameInformation.FileName);
2887 SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2891 // Indicate the object is held
2894 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2897 // Return the open result for this file
2900 Irp->IoStatus.Information = FILE_OPENED;
2902 *Fcb = pObjectInfo->Fcb;
2909 if( !NT_SUCCESS( ntStatus))
2912 // Decrement the open count on this Fcb
2915 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2917 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2918 AFS_TRACE_LEVEL_VERBOSE,
2919 "AFSProcessOpen Decrement2 count on Fcb %p Cnt %d\n",
2924 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2927 if( !NT_SUCCESS( ntStatus))
2930 if ( ulFileAccess > 0)
2933 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2935 stReleaseFileAccess.FileAccess = ulFileAccess;
2937 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2939 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2940 AFS_REQUEST_FLAG_SYNCHRONOUS,
2942 &DirectoryCB->NameInformation.FileName,
2943 &pObjectInfo->FileId,
2944 pObjectInfo->VolumeCB->VolumeInformation.Cell,
2945 pObjectInfo->VolumeCB->VolumeInformation.CellLength,
2946 (void *)&stReleaseFileAccess,
2947 sizeof( AFSFileAccessReleaseCB),
2962 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2973 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
2975 IN AFSVolumeCB *VolumeCB,
2977 IN AFSDirectoryCB *ParentDirCB,
2978 IN AFSDirectoryCB *DirectoryCB,
2982 UNREFERENCED_PARAMETER(DeviceObject);
2983 NTSTATUS ntStatus = STATUS_SUCCESS;
2984 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2985 PFILE_OBJECT pFileObject = NULL;
2986 LARGE_INTEGER liZero = {0,0};
2987 BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
2988 ULONG ulAttributes = 0;
2989 ULONG ulCreateDisposition = 0;
2990 BOOLEAN bAllocatedCcb = FALSE;
2991 BOOLEAN bUserMapped = FALSE;
2992 PACCESS_MASK pDesiredAccess = NULL;
2993 USHORT usShareAccess;
2994 AFSObjectInfoCB *pParentObjectInfo = NULL;
2995 AFSObjectInfoCB *pObjectInfo = NULL;
2997 LARGE_INTEGER liSaveSize;
2998 LARGE_INTEGER liSaveVDL;
2999 LARGE_INTEGER liSaveAlloc;
3004 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3006 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
3008 pFileObject = pIrpSp->FileObject;
3010 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
3012 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
3014 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
3017 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3018 AFS_TRACE_LEVEL_ERROR,
3019 "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3021 &DirectoryCB->NameInformation.FileName);
3023 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3026 pParentObjectInfo = ParentDirCB->ObjectInformation;
3028 pObjectInfo = DirectoryCB->ObjectInformation;
3030 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3031 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
3034 // Check if we should go and retrieve updated information for the node
3037 ntStatus = AFSValidateEntry( DirectoryCB,
3042 if( !NT_SUCCESS( ntStatus))
3045 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3046 AFS_TRACE_LEVEL_ERROR,
3047 "AFSProcessOverwriteSupersede (%p) Failed to validate entry %wZ Status %08lX\n",
3049 &DirectoryCB->NameInformation.FileName,
3052 try_return( ntStatus);
3056 // Be sure we have an Fcb for the object block
3059 ntStatus = AFSInitFcb( DirectoryCB);
3061 *Fcb = pObjectInfo->Fcb;
3063 if( !NT_SUCCESS( ntStatus))
3066 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3067 AFS_TRACE_LEVEL_ERROR,
3068 "AFSProcessOverwriteSupersede (%p) Failed to initialize fcb %wZ Status %08lX\n",
3070 &DirectoryCB->NameInformation.FileName,
3073 try_return( ntStatus);
3076 ntStatus = STATUS_SUCCESS;
3079 // Increment the open count on this Fcb.
3082 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3084 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3085 AFS_TRACE_LEVEL_VERBOSE,
3086 "AFSProcessOverwriteSupersede Increment2 count on Fcb %p Cnt %d\n",
3093 // Check access on the entry
3096 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3099 ntStatus = IoCheckShareAccess( *pDesiredAccess,
3102 &pObjectInfo->Fcb->ShareAccess,
3105 if( !NT_SUCCESS( ntStatus))
3108 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3109 AFS_TRACE_LEVEL_ERROR,
3110 "AFSProcessOverwriteSupersede (%p) Access check failure %wZ Status %08lX\n",
3112 &DirectoryCB->NameInformation.FileName,
3115 try_return( ntStatus);
3119 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3120 AFS_TRACE_LEVEL_VERBOSE,
3121 "AFSProcessOverwriteSupercede Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3122 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3123 PsGetCurrentThread());
3125 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3129 // Before we actually truncate, check to see if the purge
3130 // is going to fail.
3133 bUserMapped = !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3136 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3137 AFS_TRACE_LEVEL_VERBOSE,
3138 "AFSProcessOverwriteSupercede Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3139 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3140 PsGetCurrentThread());
3142 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3147 ntStatus = STATUS_USER_MAPPED_FILE;
3149 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3150 AFS_TRACE_LEVEL_ERROR,
3151 "AFSProcessOverwriteSupersede (%p) File user mapped %wZ Status %08lX\n",
3153 &DirectoryCB->NameInformation.FileName,
3156 try_return( ntStatus);
3160 // Initialize the Ccb for the file.
3163 ntStatus = AFSInitCcb( Ccb,
3168 if( !NT_SUCCESS( ntStatus))
3171 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3172 AFS_TRACE_LEVEL_ERROR,
3173 "AFSProcessOverwriteSupersede (%p) Failed to initialize ccb %wZ Status %08lX\n",
3175 &DirectoryCB->NameInformation.FileName,
3178 try_return( ntStatus);
3181 bAllocatedCcb = TRUE;
3184 // Set the file length to zero
3187 AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3190 bReleasePaging = TRUE;
3192 liSaveSize = pObjectInfo->Fcb->Header.FileSize;
3193 liSaveAlloc = pObjectInfo->Fcb->Header.AllocationSize;
3194 liSaveVDL = pObjectInfo->Fcb->Header.ValidDataLength;
3196 pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3197 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3198 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3200 pObjectInfo->EndOfFile.QuadPart = 0;
3201 pObjectInfo->AllocationSize.QuadPart = 0;
3204 // Trim down the extents. We do this BEFORE telling the service
3205 // the file is truncated since there is a potential race between
3206 // a worker thread releasing extents and us trimming
3209 AFSTrimExtents( pObjectInfo->Fcb,
3210 &pObjectInfo->Fcb->Header.FileSize);
3212 KeQuerySystemTime( &pObjectInfo->ChangeTime);
3214 KeQuerySystemTime( &pObjectInfo->LastAccessTime);
3216 KeQuerySystemTime( &pObjectInfo->LastWriteTime);
3219 // Set the update flag accordingly
3222 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
3223 AFS_FCB_FLAG_UPDATE_CREATE_TIME |
3224 AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
3225 AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
3226 AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
3228 ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
3232 if( !NT_SUCCESS( ntStatus))
3235 pObjectInfo->Fcb->Header.ValidDataLength = liSaveVDL;
3236 pObjectInfo->Fcb->Header.FileSize = liSaveSize;
3237 pObjectInfo->Fcb->Header.AllocationSize = liSaveAlloc;
3238 pObjectInfo->Fcb->ObjectInformation->EndOfFile = liSaveSize;
3239 pObjectInfo->Fcb->ObjectInformation->AllocationSize = liSaveAlloc;
3241 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3242 AFS_TRACE_LEVEL_ERROR,
3243 "AFSProcessOverwriteSupersede (%p) Failed to update file information %wZ Status %08lX\n",
3245 &DirectoryCB->NameInformation.FileName,
3248 try_return( ntStatus);
3251 ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
3253 if( ulCreateDisposition == FILE_SUPERSEDE)
3256 pObjectInfo->FileAttributes = ulAttributes;
3262 pObjectInfo->FileAttributes |= ulAttributes;
3266 // Save off the access for the open
3269 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3272 IoUpdateShareAccess( pFileObject,
3273 &pObjectInfo->Fcb->ShareAccess);
3282 IoSetShareAccess( *pDesiredAccess,
3285 &pObjectInfo->Fcb->ShareAccess);
3289 // Return the correct action
3292 if( ulCreateDisposition == FILE_SUPERSEDE)
3295 Irp->IoStatus.Information = FILE_SUPERSEDED;
3300 Irp->IoStatus.Information = FILE_OVERWRITTEN;
3303 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
3305 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3306 AFS_TRACE_LEVEL_VERBOSE,
3307 "AFSProcessOverwriteSupersede Increment handle count on Fcb %p Cnt %d\n",
3312 // Increment the open reference and handle on the parent node
3315 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3317 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3318 AFS_TRACE_LEVEL_VERBOSE,
3319 "AFSProcessOverwriteSupersede Increment child open handle count on Parent object %p Cnt %d\n",
3323 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3325 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3326 AFS_TRACE_LEVEL_VERBOSE,
3327 "AFSProcessOverwriteSupersede Increment child open ref count on Parent object %p Cnt %d\n",
3331 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3333 bReleaseFcb = FALSE;
3335 *Fcb = pObjectInfo->Fcb;
3338 // Now that the Fcb->Resource has been dropped
3339 // we can call CcSetFileSizes. We are still holding
3340 // the PagingIoResource
3343 pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
3345 pFileObject->FsContext = (void *)pObjectInfo->Fcb;
3347 pFileObject->FsContext2 = (void *)*Ccb;
3349 CcSetFileSizes( pFileObject,
3350 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3357 AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3363 if( !NT_SUCCESS( ntStatus))
3366 // Decrement the open count on this Fcb.
3369 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
3371 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3372 AFS_TRACE_LEVEL_VERBOSE,
3373 "AFSProcessOverwriteSupersede Decrement2 count on Fcb %p Cnt %d\n",
3378 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3381 if( !NT_SUCCESS( ntStatus))
3394 // Fcb will be freed by AFSPrimaryVolumeWorker thread
3405 AFSControlDeviceCreate( IN PIRP Irp)
3408 NTSTATUS ntStatus = STATUS_SUCCESS;
3413 if ( KernelMode == Irp->RequestorMode) {
3415 // For now, just let the open happen
3417 Irp->IoStatus.Information = FILE_OPENED;
3422 // Not from usermode, All access must be via
3423 // the FS component (which will do the
3426 ntStatus = STATUS_ACCESS_DENIED;
3434 // AFSOpenIOCtlFcb does not release a DirOpenReferenceCount on
3439 AFSOpenIOCtlFcb( IN PIRP Irp,
3441 IN AFSDirectoryCB *ParentDirCB,
3446 NTSTATUS ntStatus = STATUS_SUCCESS;
3447 PFILE_OBJECT pFileObject = NULL;
3448 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3449 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
3450 AFSPIOCtlOpenCloseRequestCB stPIOCtlOpen;
3452 AFSObjectInfoCB *pParentObjectInfo = NULL;
3458 pFileObject = pIrpSp->FileObject;
3460 pParentObjectInfo = ParentDirCB->ObjectInformation;
3463 // If we haven't initialized the PIOCtl DirectoryCB for this directory then do it now
3466 if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB == NULL)
3469 ntStatus = AFSInitPIOCtlDirectoryCB( pParentObjectInfo);
3471 if( !NT_SUCCESS( ntStatus))
3474 try_return( ntStatus);
3479 // Allocate and initialize the Fcb for the file.
3482 ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB);
3484 *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
3486 if( !NT_SUCCESS( ntStatus))
3489 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3490 AFS_TRACE_LEVEL_ERROR,
3491 "AFSOpenIOCtlFcb (%p) Failed to initialize fcb Status %08lX\n",
3495 try_return( ntStatus);
3498 ntStatus = STATUS_SUCCESS;
3501 // Increment the open reference and handle on the node
3504 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3506 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3507 AFS_TRACE_LEVEL_VERBOSE,
3508 "AFSOpenIOCtlFcb Increment count on Fcb %p Cnt %d\n",
3515 // Initialize the Ccb for the file.
3518 ntStatus = AFSInitCcb( Ccb,
3519 pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
3523 if( !NT_SUCCESS( ntStatus))
3526 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3527 AFS_TRACE_LEVEL_ERROR,
3528 "AFSOpenIOCtlFcb (%p) Failed to initialize ccb Status %08lX\n",
3532 try_return( ntStatus);
3535 bAllocatedCcb = TRUE;
3538 // Set the PIOCtl index
3541 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3543 RtlZeroMemory( &stPIOCtlOpen,
3544 sizeof( AFSPIOCtlOpenCloseRequestCB));
3546 stPIOCtlOpen.RequestId = (*Ccb)->RequestID;
3548 stPIOCtlOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3550 RtlZeroMemory( &stFileID,
3551 sizeof( AFSFileID));
3554 // The parent directory FID of the node
3557 stFileID = pParentObjectInfo->FileId;
3560 // Issue the open request to the service
3563 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_OPEN,
3564 AFS_REQUEST_FLAG_SYNCHRONOUS,
3570 (void *)&stPIOCtlOpen,
3571 sizeof( AFSPIOCtlOpenCloseRequestCB),
3575 if( !NT_SUCCESS( ntStatus))
3578 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3579 AFS_TRACE_LEVEL_ERROR,
3580 "AFSOpenIOCtlFcb (%p) Failed service open Status %08lX\n",
3584 try_return( ntStatus);
3588 // Increment the handle on the node
3591 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3593 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3594 AFS_TRACE_LEVEL_VERBOSE,
3595 "AFSOpenIOCtlFcb Increment handle count on Fcb %p Cnt %d\n",
3600 // Increment the open reference and handle on the parent node
3603 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3605 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3606 AFS_TRACE_LEVEL_VERBOSE,
3607 "AFSOpenIOCtlFcb Increment child open handle count on Parent object %p Cnt %d\n",
3611 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3613 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3614 AFS_TRACE_LEVEL_VERBOSE,
3615 "AFSOpenIOCtlFcb Increment child open ref count on Parent object %p Cnt %d\n",
3620 // Return the open result for this file
3623 Irp->IoStatus.Information = FILE_OPENED;
3628 // If we created the Fcb we need to release the resources
3634 if( !NT_SUCCESS( ntStatus))
3637 // Decrement the open reference and handle on the node
3640 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3642 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3643 AFS_TRACE_LEVEL_VERBOSE,
3644 "AFSOpenIOCtlFcb Decrement count on Fcb %p Cnt %d\n",
3649 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3652 if( !NT_SUCCESS( ntStatus))
3665 // Fcb will be freed by AFSPrimaryVolumeWorker thread
3676 AFSOpenSpecialShareFcb( IN PIRP Irp,
3678 IN AFSDirectoryCB *DirectoryCB,
3683 NTSTATUS ntStatus = STATUS_SUCCESS;
3684 PFILE_OBJECT pFileObject = NULL;
3685 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3686 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE, bAllocateFcb = FALSE;
3687 AFSObjectInfoCB *pObjectInfo = NULL;
3688 AFSObjectInfoCB *pParentObjectInfo = NULL;
3689 AFSPipeOpenCloseRequestCB stPipeOpen;
3695 pFileObject = pIrpSp->FileObject;
3697 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3698 AFS_TRACE_LEVEL_VERBOSE_2,
3699 "AFSOpenSpecialShareFcb (%p) Processing Share %wZ open\n",
3701 &DirectoryCB->NameInformation.FileName);
3703 pObjectInfo = DirectoryCB->ObjectInformation;
3705 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
3708 pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
3709 &pObjectInfo->ParentFileId);
3712 if( DirectoryCB->ObjectInformation->Fcb == NULL)
3716 // Allocate and initialize the Fcb for the file.
3719 ntStatus = AFSInitFcb( DirectoryCB);
3721 *Fcb = pObjectInfo->Fcb;
3723 if( !NT_SUCCESS( ntStatus))
3726 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3727 AFS_TRACE_LEVEL_ERROR,
3728 "AFSOpenSpecialShareFcb (%p) Failed to initialize fcb Status %08lX\n",
3732 try_return( ntStatus);
3735 if ( ntStatus != STATUS_REPARSE)
3738 bAllocateFcb = TRUE;
3741 ntStatus = STATUS_SUCCESS;
3746 *Fcb = pObjectInfo->Fcb;
3748 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
3753 // Increment the open count on this Fcb
3756 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3758 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3759 AFS_TRACE_LEVEL_VERBOSE,
3760 "AFSOpenSpecialShareFcb Increment count on Fcb %p Cnt %d\n",
3767 // Initialize the Ccb for the file.
3770 ntStatus = AFSInitCcb( Ccb,
3775 if( !NT_SUCCESS( ntStatus))
3778 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3779 AFS_TRACE_LEVEL_ERROR,
3780 "AFSOpenSpecialShareFcb (%p) Failed to initialize ccb Status %08lX\n",
3784 try_return( ntStatus);
3787 bAllocatedCcb = TRUE;
3790 // Call the service to open the share
3793 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3795 RtlZeroMemory( &stPipeOpen,
3796 sizeof( AFSPipeOpenCloseRequestCB));
3798 stPipeOpen.RequestId = (*Ccb)->RequestID;
3800 stPipeOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3803 // Issue the open request to the service
3806 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_OPEN,
3807 AFS_REQUEST_FLAG_SYNCHRONOUS,
3809 &DirectoryCB->NameInformation.FileName,
3813 (void *)&stPipeOpen,
3814 sizeof( AFSPipeOpenCloseRequestCB),
3818 if( !NT_SUCCESS( ntStatus))
3821 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3822 AFS_TRACE_LEVEL_ERROR,
3823 "AFSOpenSpecialShareFcb (%p) Failed service open Status %08lX\n",
3827 try_return( ntStatus);
3830 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3832 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3833 AFS_TRACE_LEVEL_VERBOSE,
3834 "AFSOpenSpecialShareFcb Increment handle count on Fcb %p Cnt %d\n",
3839 // Increment the open reference and handle on the parent node
3842 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3844 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3845 AFS_TRACE_LEVEL_VERBOSE,
3846 "AFSOpenSpecialShareFcb Increment child open handle count on Parent object %p Cnt %d\n",
3850 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3852 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3853 AFS_TRACE_LEVEL_VERBOSE,
3854 "AFSOpenSpecialShareFcb Increment child open ref count on Parent object %p Cnt %d\n",
3859 // Return the open result for this file
3862 Irp->IoStatus.Information = FILE_OPENED;
3869 if( !NT_SUCCESS( ntStatus))
3872 // Decrement the open count on this Fcb
3875 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3877 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3878 AFS_TRACE_LEVEL_VERBOSE,
3879 "AFSOpenSpecialShareFcb Decrement count on Fcb %p Cnt %d\n",
3884 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3887 if( !NT_SUCCESS( ntStatus))
3903 // Need to tear down this Fcb since it is not in the tree for the worker thread
3906 AFSAcquireExcl( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
3909 AFSRemoveFcb( &DirectoryCB->ObjectInformation->Fcb);
3911 AFSReleaseResource( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);