2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSCreate.cpp
39 #include "AFSCommon.h"
42 // Function: AFSCreate
46 // This function is the dispatch handler for the IRP_MJ_CREATE requests. It makes the determination to
47 // which interface this request is destined.
51 // A status is returned for the function. The Irp completion processing is handled in the specific
56 AFSCreate( IN PDEVICE_OBJECT LibDeviceObject,
59 UNREFERENCED_PARAMETER(LibDeviceObject);
60 NTSTATUS ntStatus = STATUS_SUCCESS;
61 IO_STACK_LOCATION *pIrpSp;
62 FILE_OBJECT *pFileObject = NULL;
67 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
68 pFileObject = pIrpSp->FileObject;
70 if( pFileObject == NULL ||
71 pFileObject->FileName.Buffer == NULL)
74 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
75 AFS_TRACE_LEVEL_VERBOSE,
76 "AFSCreate (%p) Processing control device open request\n",
79 ntStatus = AFSControlDeviceCreate( Irp);
81 try_return( ntStatus);
84 if( AFSRDRDeviceObject == NULL)
87 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
88 AFS_TRACE_LEVEL_VERBOSE,
89 "AFSCreate (%p) Invalid request to open before library is initialized\n",
92 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
95 ntStatus = AFSCommonCreate( AFSRDRDeviceObject,
102 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
107 "EXCEPTION - AFSCreate\n"));
109 ntStatus = STATUS_ACCESS_DENIED;
111 AFSDumpTraceFilesFnc();
115 // Complete the request
118 AFSCompleteRequest( Irp,
125 AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
129 NTSTATUS ntStatus = STATUS_SUCCESS;
130 UNICODE_STRING uniFileName;
131 ULONG ulCreateDisposition = 0;
133 BOOLEAN bNoIntermediateBuffering = FALSE;
134 FILE_OBJECT *pFileObject = NULL;
135 IO_STACK_LOCATION *pIrpSp;
138 AFSDeviceExt *pDeviceExt = NULL;
139 BOOLEAN bOpenTargetDirectory = FALSE, bReleaseVolume = FALSE;
140 PACCESS_MASK pDesiredAccess = NULL;
141 UNICODE_STRING uniComponentName, uniRootFileName, uniParsedFileName;
142 UNICODE_STRING uniSubstitutedPathName;
143 UNICODE_STRING uniRelativeName;
144 AFSNameArrayHdr *pNameArray = NULL;
145 AFSVolumeCB *pVolumeCB = NULL;
146 LONG VolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
147 AFSVolumeCB *pNewVolumeCB = NULL;
148 LONG NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
149 AFSDirectoryCB *pParentDirectoryCB = NULL, *pDirectoryCB = NULL;
150 AFSDirectoryCB *pNewParentDirectoryCB = NULL;
151 BOOLEAN bReleaseParentDir = FALSE, bReleaseDir = FALSE;
152 ULONG ulParseFlags = 0;
153 GUID stAuthGroup = {0};
154 ULONG ulNameProcessingFlags = 0;
155 BOOLEAN bOpenedReparsePoint = FALSE;
161 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
162 pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
163 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
164 ulOptions = pIrpSp->Parameters.Create.Options;
165 bNoIntermediateBuffering = BooleanFlagOn( ulOptions, FILE_NO_INTERMEDIATE_BUFFERING);
166 bOpenTargetDirectory = BooleanFlagOn( pIrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
167 pFileObject = pIrpSp->FileObject;
168 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
170 uniFileName.Length = uniFileName.MaximumLength = 0;
171 uniFileName.Buffer = NULL;
173 uniRootFileName.Length = uniRootFileName.MaximumLength = 0;
174 uniRootFileName.Buffer = NULL;
176 uniParsedFileName.Length = uniParsedFileName.MaximumLength = 0;
177 uniParsedFileName.Buffer = NULL;
179 uniSubstitutedPathName.Buffer = NULL;
180 uniSubstitutedPathName.Length = 0;
182 uniRelativeName.Buffer = NULL;
183 uniRelativeName.Length = 0;
185 if( AFSGlobalRoot == NULL)
187 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
190 RtlZeroMemory( &stAuthGroup,
193 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
194 (ULONGLONG)PsGetCurrentThreadId(),
198 // If we are in shutdown mode then fail the request
201 if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
204 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
205 AFS_TRACE_LEVEL_WARNING,
206 "AFSCommonCreate (%p) Open request after shutdown\n",
209 try_return( ntStatus = STATUS_TOO_LATE);
212 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
215 ntStatus = AFSEnumerateGlobalRoot( &stAuthGroup);
217 if( !NT_SUCCESS( ntStatus))
220 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
221 AFS_TRACE_LEVEL_ERROR,
222 "AFSCommonCreate Failed to enumerate global root Status %08lX\n",
225 try_return( ntStatus);
230 // Go and parse the name for processing.
231 // If ulParseFlags is returned with AFS_PARSE_FLAG_FREE_FILE_BUFFER set,
232 // then we are responsible for releasing the uniRootFileName.Buffer.
235 ntStatus = AFSParseName( Irp,
245 if( !NT_SUCCESS( ntStatus))
248 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
249 uniFileName.Length > 0 ? AFS_TRACE_LEVEL_ERROR : AFS_TRACE_LEVEL_VERBOSE,
250 "AFSCommonCreate (%p) Failed to parse name \"%wZ\" Status %08lX\n",
255 try_return( ntStatus);
259 // Check for STATUS_REPARSE
262 if( ntStatus == STATUS_REPARSE)
266 // Update the information and return
269 Irp->IoStatus.Information = IO_REPARSE;
271 try_return( ntStatus);
274 if ( pParentDirectoryCB != NULL)
277 bReleaseParentDir = TRUE;
281 // If the returned volume cb is NULL then we are dealing with the \\Server\GlobalRoot
285 if( pVolumeCB == NULL)
289 // Remove any leading or trailing slashes
292 if( uniFileName.Length >= sizeof( WCHAR) &&
293 uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
296 uniFileName.Length -= sizeof( WCHAR);
299 if( uniFileName.Length >= sizeof( WCHAR) &&
300 uniFileName.Buffer[ 0] == L'\\')
303 uniFileName.Buffer = &uniFileName.Buffer[ 1];
305 uniFileName.Length -= sizeof( WCHAR);
309 // If there is a remaining portion returned for this request then
310 // check if it is for the PIOCtl interface
313 if( uniFileName.Length > 0)
317 // We don't accept any other opens off of the AFS Root
320 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
323 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
326 if( RtlCompareUnicodeString( &AFSPIOCtlName,
332 // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
333 // AFSGlobalRoot->DirectoryCB.
336 ntStatus = AFSOpenIOCtlFcb( Irp,
338 AFSGlobalRoot->DirectoryCB,
342 if( !NT_SUCCESS( ntStatus))
345 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
346 AFS_TRACE_LEVEL_ERROR,
347 "AFSCommonCreate Failed to open root IOCtl Fcb Status %08lX\n",
351 else if( pParentDirectoryCB != NULL)
354 if( pParentDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
357 ntStatus = AFSOpenSpecialShareFcb( Irp,
363 if( !NT_SUCCESS( ntStatus))
366 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
367 AFS_TRACE_LEVEL_ERROR,
368 "AFSCommonCreate Failed to open special share Fcb Status %08lX\n",
374 try_return( ntStatus);
377 ntStatus = AFSOpenAFSRoot( Irp,
381 if( !NT_SUCCESS( ntStatus))
384 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
385 AFS_TRACE_LEVEL_ERROR,
386 "AFSCommonCreate Failed to open root Status %08lX\n",
390 try_return( ntStatus);
394 // We have a reference on the root volume
397 VolumeReferenceReason = AFS_VOLUME_REFERENCE_PARSE_NAME;
399 bReleaseVolume = TRUE;
402 // Attempt to locate the node in the name tree if this is not a target
403 // open and the target is not the root
406 uniComponentName.Length = 0;
407 uniComponentName.Buffer = NULL;
409 if( uniFileName.Length > sizeof( WCHAR) ||
410 uniFileName.Buffer[ 0] != L'\\')
413 if( !AFSValidNameFormat( &uniFileName))
416 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
418 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
419 AFS_TRACE_LEVEL_VERBOSE,
420 "AFSCommonCreate (%p) Invalid name %wZ Status %08lX\n",
425 try_return( ntStatus);
429 // 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,
457 if ( pNewVolumeCB != NULL)
461 // AFSLocateNameEntry returns pNewVolumeCB with a reference held
462 // even if pVolumeCB == pNewVolumeCB. It is always safe to release
463 // the reference on pVolumeCB that was held prior to the call.
464 // If pVolumeCB == pNewVolumeCB, the reference from AFSLocateNameEntry
465 // will be released second.
468 lCount = AFSVolumeDecrement( pVolumeCB,
469 VolumeReferenceReason);
471 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
472 AFS_TRACE_LEVEL_VERBOSE,
473 "AFSCommonCreate Decrement count on volume %p Reason %u Cnt %d\n",
475 VolumeReferenceReason,
478 pVolumeCB = pNewVolumeCB;
482 VolumeReferenceReason = NewVolumeReferenceReason;
484 NewVolumeReferenceReason = AFS_VOLUME_REFERENCE_INVALID;
486 bReleaseVolume = (pVolumeCB != NULL);
490 // AFSLocateNameEntry does not alter the reference count of
491 // pParentDirectoryCB and it returns pNewParentDirectoryCB with
495 if ( bReleaseParentDir)
498 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
500 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
501 AFS_TRACE_LEVEL_VERBOSE,
502 "AFSCommonCreate DecrementX count on %wZ DE %p Ccb %p Cnt %d\n",
503 &pParentDirectoryCB->NameInformation.FileName,
509 pParentDirectoryCB = pNewParentDirectoryCB;
511 pNewParentDirectoryCB = NULL;
513 bReleaseParentDir = (pParentDirectoryCB != NULL);
521 if( !NT_SUCCESS( ntStatus) &&
522 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
525 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
527 uniSubstitutedPathName.Buffer = NULL;
531 // AFSLocateNameEntry released the Parent while walking the
535 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
536 AFS_TRACE_LEVEL_VERBOSE,
537 "AFSCommonCreate (%p) Failed to locate name entry for %wZ Status %08lX\n",
542 try_return( ntStatus);
546 // Check for STATUS_REPARSE
549 if( ntStatus == STATUS_REPARSE)
552 uniSubstitutedPathName.Buffer = NULL;
555 // Update the information and return
558 Irp->IoStatus.Information = IO_REPARSE;
560 try_return( ntStatus);
564 // If we re-allocated the name, then update our substitute name
567 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
570 uniSubstitutedPathName = uniRootFileName;
575 uniSubstitutedPathName.Buffer = NULL;
579 // Check for a symlink access
582 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
583 pParentDirectoryCB != NULL)
587 // pParentDirectoryCB DirOpenReferenceCount is still held
590 UNICODE_STRING uniFinalComponent;
592 uniFinalComponent.Length = 0;
593 uniFinalComponent.MaximumLength = 0;
594 uniFinalComponent.Buffer = NULL;
596 AFSRetrieveFinalComponent( &uniFileName,
599 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
602 if( !NT_SUCCESS( ntStatus) &&
603 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
606 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
607 AFS_TRACE_LEVEL_VERBOSE,
608 "AFSCommonCreate (%p) Failing access to symlink %wZ Status %08lX\n",
613 try_return( ntStatus);
619 // If we have no parent then this is a root open, be sure there is a directory entry
623 else if( pParentDirectoryCB == NULL &&
624 pDirectoryCB == NULL)
627 pDirectoryCB = pVolumeCB->DirectoryCB;
629 lCount = InterlockedIncrement( &pDirectoryCB->DirOpenReferenceCount);
631 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
632 AFS_TRACE_LEVEL_VERBOSE,
633 "AFSCommonCreate Increment0 count on %wZ DE %p Ccb %p Cnt %d\n",
634 &pDirectoryCB->NameInformation.FileName,
642 if( bOpenTargetDirectory)
646 // If we have a directory cb for the entry then dereference it and reference the parent
649 if( pDirectoryCB != NULL)
652 if ( !bReleaseParentDir)
656 // Perform in this order to prevent thrashing
659 lCount = InterlockedIncrement( &pParentDirectoryCB->DirOpenReferenceCount);
661 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
662 AFS_TRACE_LEVEL_VERBOSE,
663 "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
664 &pParentDirectoryCB->NameInformation.FileName,
669 bReleaseParentDir = TRUE;
673 // Do NOT decrement the reference count on the pDirectoryCB yet.
674 // The BackupEntry below might drop the count to zero leaving
675 // the entry subject to being deleted and we need some of the
676 // contents during later processing
679 AFSBackupEntry( pNameArray);
683 // OK, open the target directory
686 if( uniComponentName.Length == 0)
688 AFSRetrieveFinalComponent( &uniFileName,
692 ntStatus = AFSOpenTargetDirectory( Irp,
700 if( !NT_SUCCESS( ntStatus))
703 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
704 AFS_TRACE_LEVEL_ERROR,
705 "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
706 &pParentDirectoryCB->NameInformation.FileName,
710 try_return( ntStatus);
713 if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
716 if( pDirectoryCB == NULL ||
717 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
719 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
720 AFS_TRACE_LEVEL_VERBOSE,
721 "AFSCommonCreate (%p) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
725 pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0));
729 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
730 AFS_TRACE_LEVEL_VERBOSE,
731 "AFSCommonCreate (%p) Opening as reparse point %wZ Type %08lX\n",
734 pDirectoryCB->ObjectInformation->FileType));
736 bOpenedReparsePoint = TRUE;
741 // Based on the options passed in, process the file accordingly.
744 if( ulCreateDisposition == FILE_CREATE ||
745 ( ( ulCreateDisposition == FILE_OPEN_IF ||
746 ulCreateDisposition == FILE_OVERWRITE_IF) &&
747 pDirectoryCB == NULL))
750 if( uniComponentName.Length == 0 ||
751 pDirectoryCB != NULL)
755 // We traversed the entire path so we found each entry,
756 // fail with collision
759 if( pDirectoryCB != NULL)
762 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
763 AFS_TRACE_LEVEL_VERBOSE,
764 "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
765 &pDirectoryCB->NameInformation.FileName,
771 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
772 AFS_TRACE_LEVEL_VERBOSE,
773 "AFSCommonCreate Object name collision on create Status %08lX\n",
777 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
781 // OK, go and create the node
784 ntStatus = AFSProcessCreate( Irp,
794 if( !NT_SUCCESS( ntStatus))
797 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
798 AFS_TRACE_LEVEL_ERROR,
799 "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
801 &pParentDirectoryCB->NameInformation.FileName,
805 try_return( ntStatus);
809 // We should not have an extra component except for PIOCtl opens
812 if( uniComponentName.Length > 0)
816 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
819 if( RtlCompareUnicodeString( &AFSPIOCtlName,
825 // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
826 // pParentDirectoryCB.
829 ntStatus = AFSOpenIOCtlFcb( Irp,
835 if( !NT_SUCCESS( ntStatus))
838 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
839 AFS_TRACE_LEVEL_ERROR,
840 "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
848 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
849 AFS_TRACE_LEVEL_VERBOSE,
850 "AFSCommonCreate (%p) File %wZ name not found\n",
854 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
857 try_return( ntStatus);
861 // For root opens the parent will be NULL
864 if( pParentDirectoryCB == NULL)
868 // Check for the delete on close flag for the root
871 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
874 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
875 AFS_TRACE_LEVEL_ERROR,
876 "AFSCommonCreate (%p) Attempt to open root as delete on close\n",
879 try_return( ntStatus = STATUS_CANNOT_DELETE);
883 // If this is the target directory, then bail
886 if( bOpenTargetDirectory)
889 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
890 AFS_TRACE_LEVEL_ERROR,
891 "AFSCommonCreate (%p) Attempt to open root as target directory\n",
894 try_return( ntStatus = STATUS_INVALID_PARAMETER);
898 // Go and open the root of the volume
901 ntStatus = AFSOpenRoot( Irp,
907 if( !NT_SUCCESS( ntStatus))
910 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
911 AFS_TRACE_LEVEL_ERROR,
912 "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
913 pVolumeCB->ObjectInformation.FileId.Cell,
914 pVolumeCB->ObjectInformation.FileId.Volume,
918 try_return( ntStatus);
922 // At this point if we have no pDirectoryCB it was not found.
925 if( pDirectoryCB == NULL)
928 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
929 AFS_TRACE_LEVEL_ERROR,
930 "AFSCommonCreate Failing access to %wZ Name not found\n",
933 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
936 if( ulCreateDisposition == FILE_OVERWRITE ||
937 ulCreateDisposition == FILE_SUPERSEDE ||
938 ulCreateDisposition == FILE_OVERWRITE_IF)
942 // Go process a file for overwrite or supersede.
945 ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
954 if( !NT_SUCCESS( ntStatus))
957 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
958 AFS_TRACE_LEVEL_ERROR,
959 "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
960 &pDirectoryCB->NameInformation.FileName,
964 try_return( ntStatus);
968 // Trying to open the file
971 ntStatus = AFSProcessOpen( Irp,
979 if( !NT_SUCCESS( ntStatus))
982 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
983 AFS_TRACE_LEVEL_ERROR,
984 "AFSCommonCreate Failed open on %wZ Status %08lX\n",
985 &pDirectoryCB->NameInformation.FileName,
991 if( NT_SUCCESS( ntStatus) &&
992 ntStatus != STATUS_REPARSE)
998 AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
1001 RtlCopyMemory( &pCcb->AuthGroup,
1006 // If we have a substitute name, then use it
1009 if( uniSubstitutedPathName.Buffer != NULL)
1012 pCcb->FullFileName = uniSubstitutedPathName;
1014 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1016 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1021 pCcb->FullFileName = uniRootFileName;
1023 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1026 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1028 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1032 if( bOpenedReparsePoint)
1034 SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1037 lCount = pCcb->DirectoryCB->DirOpenReferenceCount;
1039 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1040 AFS_TRACE_LEVEL_VERBOSE,
1041 "AFSCommonCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1042 &pCcb->DirectoryCB->NameInformation.FileName,
1047 ASSERT( lCount >= 0);
1049 pCcb->CurrentDirIndex = 0;
1051 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1054 SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1058 // Save off the name array for this instance
1061 pCcb->NameArray = pNameArray;
1065 AFSReleaseResource( &pCcb->NPCcb->CcbLock);
1069 // If we make it here then init the FO for the request.
1072 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1073 AFS_TRACE_LEVEL_VERBOSE_2,
1074 "AFSCommonCreate (%p) FileObject %p FsContext %p FsContext2 %p\n",
1080 pFileObject->FsContext = (void *)pFcb;
1082 pFileObject->FsContext2 = (void *)pCcb;
1087 ASSERT( pFcb->OpenHandleCount > 0);
1089 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1092 // For files perform additional processing
1095 switch( pFcb->Header.NodeTypeCode)
1102 pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1107 // If the user did not request nobuffering then mark the FO as cacheable
1110 if( bNoIntermediateBuffering)
1113 pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1118 pFileObject->Flags |= FO_CACHE_SUPPORTED;
1122 // If the file was opened for execution then we need to set the bit in the FO
1125 if( BooleanFlagOn( *pDesiredAccess,
1129 SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1133 // Update the last access time
1136 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1147 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1148 AFS_TRACE_LEVEL_ERROR,
1149 "AFSCommonCreate (%p) Returning with NULL Fcb FileObject %p FsContext %p FsContext2 %p\n",
1158 if( NT_SUCCESS( ntStatus) &&
1159 ntStatus == STATUS_REPARSE)
1162 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1163 AFS_TRACE_LEVEL_ERROR,
1164 "AFSCommonCreate (%p) STATUS_REPARSE FileObject %p FsContext %p FsContext2 %p\n",
1172 // Free up the sub name if we have one
1175 if( uniSubstitutedPathName.Buffer != NULL)
1178 AFSExFreePoolWithTag( uniSubstitutedPathName.Buffer, 0);
1180 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1185 // Free up the name array ...
1188 if( pNameArray != NULL)
1191 AFSFreeNameArray( pNameArray);
1194 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1197 AFSExFreePoolWithTag( uniRootFileName.Buffer, 0);
1203 lCount = AFSVolumeDecrement( pVolumeCB,
1204 VolumeReferenceReason);
1206 AFSDbgTrace(( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1207 AFS_TRACE_LEVEL_VERBOSE,
1208 "AFSCommonCreate Decrement count on Volume %08lX Reason %u Cnt %d\n",
1210 VolumeReferenceReason,
1218 // Release the reference from AFSLocateNameEntry
1221 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
1223 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1224 AFS_TRACE_LEVEL_VERBOSE,
1225 "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1226 &pDirectoryCB->NameInformation.FileName,
1231 ASSERT( lCount >= 0);
1234 if ( bReleaseParentDir)
1238 // Release the reference from AFSLocateNameEntry
1241 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
1243 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1244 AFS_TRACE_LEVEL_VERBOSE,
1245 "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1246 &pParentDirectoryCB->NameInformation.FileName,
1251 ASSERT( lCount >= 0);
1255 // Setup the Irp for completion, the Information has been set previously
1258 Irp->IoStatus.Status = ntStatus;
1265 AFSOpenAFSRoot( IN PIRP Irp,
1270 NTSTATUS ntStatus = STATUS_SUCCESS;
1277 // Initialize the Ccb for the file.
1280 ntStatus = AFSInitCcb( Ccb,
1281 AFSGlobalRoot->DirectoryCB,
1285 if( !NT_SUCCESS( ntStatus))
1288 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1289 AFS_TRACE_LEVEL_ERROR,
1290 "AFSOpenAFSRoot (%p) Failed to allocate Ccb\n",
1293 try_return( ntStatus);
1297 // Increment the open count on this Fcb
1300 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1302 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1303 AFS_TRACE_LEVEL_VERBOSE,
1304 "AFSOpenAFSRoot Increment count on Fcb %p Cnt %d\n",
1305 AFSGlobalRoot->RootFcb,
1308 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1310 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1311 AFS_TRACE_LEVEL_VERBOSE,
1312 "AFSOpenAFSRoot Increment handle count on Fcb %p Cnt %d\n",
1313 AFSGlobalRoot->RootFcb,
1316 *Fcb = AFSGlobalRoot->RootFcb;
1319 // Return the open result for this file
1322 Irp->IoStatus.Information = FILE_OPENED;
1333 AFSOpenRoot( IN PIRP Irp,
1334 IN AFSVolumeCB *VolumeCB,
1336 OUT AFSFcb **RootFcb,
1340 NTSTATUS ntStatus = STATUS_SUCCESS;
1341 PFILE_OBJECT pFileObject = NULL;
1342 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1343 PACCESS_MASK pDesiredAccess = NULL;
1344 USHORT usShareAccess;
1346 BOOLEAN bAllocatedCcb = FALSE;
1347 BOOLEAN bReleaseFcb = FALSE;
1348 AFSFileOpenCB stOpenCB;
1349 AFSFileOpenResultCB stOpenResultCB;
1350 ULONG ulResultLen = 0;
1356 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1357 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1358 ulOptions = pIrpSp->Parameters.Create.Options;
1360 pFileObject = pIrpSp->FileObject;
1362 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1365 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1367 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1368 AFS_TRACE_LEVEL_ERROR,
1369 "AFSOpenRoot (%p) Attempt to open root as file Status %08lX\n",
1373 try_return( ntStatus);
1377 // Check if we should go and retrieve updated information for the node
1380 ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1385 if( !NT_SUCCESS( ntStatus))
1388 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1389 AFS_TRACE_LEVEL_ERROR,
1390 "AFSOpenRoot (%p) Failed to validate root entry Status %08lX\n",
1394 try_return( ntStatus);
1398 // Check with the service that we can open the file
1401 RtlZeroMemory( &stOpenCB,
1402 sizeof( AFSFileOpenCB));
1404 stOpenCB.DesiredAccess = *pDesiredAccess;
1406 stOpenCB.ShareAccess = usShareAccess;
1408 stOpenResultCB.GrantedAccess = 0;
1410 ulResultLen = sizeof( AFSFileOpenResultCB);
1412 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1413 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1416 &VolumeCB->ObjectInformation.FileId,
1417 VolumeCB->VolumeInformation.Cell,
1418 VolumeCB->VolumeInformation.CellLength,
1420 sizeof( AFSFileOpenCB),
1421 (void *)&stOpenResultCB,
1424 if( !NT_SUCCESS( ntStatus))
1427 UNICODE_STRING uniGUID;
1430 uniGUID.MaximumLength = 0;
1431 uniGUID.Buffer = NULL;
1433 if( AuthGroup != NULL)
1435 RtlStringFromGUID( *AuthGroup,
1439 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1440 AFS_TRACE_LEVEL_ERROR,
1441 "AFSOpenRoot (%p) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1443 VolumeCB->ObjectInformation.FileId.Cell,
1444 VolumeCB->ObjectInformation.FileId.Volume,
1448 if( AuthGroup != NULL)
1450 RtlFreeUnicodeString( &uniGUID);
1453 try_return( ntStatus);
1457 // If the entry is not initialized then do it now
1460 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1463 AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1466 ntStatus = AFSEnumerateDirectory( AuthGroup,
1467 &VolumeCB->ObjectInformation,
1470 if( !NT_SUCCESS( ntStatus))
1473 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1475 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1476 AFS_TRACE_LEVEL_ERROR,
1477 "AFSOpenRoot (%p) Failed to enumerate directory Status %08lX\n",
1481 try_return( ntStatus);
1484 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1488 // If the root fcb has been initialized then check access otherwise
1489 // init the volume fcb
1492 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1495 if( !NT_SUCCESS( ntStatus))
1498 try_return( ntStatus);
1501 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1503 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1504 AFS_TRACE_LEVEL_VERBOSE,
1505 "AFSOpenRoot Increment count on Fcb %p Cnt %d\n",
1512 // If there are current opens on the Fcb, check the access.
1515 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1518 ntStatus = IoCheckShareAccess( *pDesiredAccess,
1521 &VolumeCB->RootFcb->ShareAccess,
1524 if( !NT_SUCCESS( ntStatus))
1527 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1528 AFS_TRACE_LEVEL_ERROR,
1529 "AFSOpenRoot (%p) Access check failure Status %08lX\n",
1533 try_return( ntStatus);
1538 // Initialize the Ccb for the file.
1541 ntStatus = AFSInitCcb( Ccb,
1542 VolumeCB->DirectoryCB,
1546 if( !NT_SUCCESS( ntStatus))
1549 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1550 AFS_TRACE_LEVEL_ERROR,
1551 "AFSOpenRoot (%p) Failed to allocate Ccb Status %08lX\n",
1555 try_return( ntStatus);
1558 bAllocatedCcb = TRUE;
1561 // OK, update the share access on the fileobject
1564 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1567 IoUpdateShareAccess( pFileObject,
1568 &VolumeCB->RootFcb->ShareAccess);
1577 IoSetShareAccess( *pDesiredAccess,
1580 &VolumeCB->RootFcb->ShareAccess);
1584 // Increment the open count on this Fcb
1587 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1589 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1590 AFS_TRACE_LEVEL_VERBOSE,
1591 "AFSOpenRoot Increment handle count on Fcb %p Cnt %d\n",
1596 // Indicate the object is held
1599 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1602 // Return the open result for this file
1605 Irp->IoStatus.Information = FILE_OPENED;
1607 *RootFcb = VolumeCB->RootFcb;
1613 if ( !NT_SUCCESS( ntStatus))
1616 lCount = InterlockedDecrement( &VolumeCB->RootFcb->OpenReferenceCount);
1618 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1619 AFS_TRACE_LEVEL_VERBOSE,
1620 "AFSOpenRoot Decrement count on Fcb %p Cnt %d\n",
1625 AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1628 if( !NT_SUCCESS( ntStatus))
1640 Irp->IoStatus.Information = 0;
1648 AFSProcessCreate( IN PIRP Irp,
1650 IN AFSVolumeCB *VolumeCB,
1651 IN AFSDirectoryCB *ParentDirCB,
1652 IN PUNICODE_STRING FileName,
1653 IN PUNICODE_STRING ComponentName,
1654 IN PUNICODE_STRING FullFileName,
1659 NTSTATUS ntStatus = STATUS_SUCCESS;
1660 PFILE_OBJECT pFileObject = NULL;
1661 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1662 ULONG ulOptions = 0;
1663 ULONG ulAttributes = 0;
1664 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1665 PACCESS_MASK pDesiredAccess = NULL;
1666 USHORT usShareAccess;
1667 AFSDirectoryCB *pDirEntry = NULL;
1668 AFSObjectInfoCB *pParentObjectInfo = NULL;
1669 AFSObjectInfoCB *pObjectInfo = NULL;
1675 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1676 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1678 pFileObject = pIrpSp->FileObject;
1681 // Extract out the options
1684 ulOptions = pIrpSp->Parameters.Create.Options;
1687 // We pass all attributes they want to apply to the file to the create
1690 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1693 // If this is a directory create then set the attribute correctly
1696 if( ulOptions & FILE_DIRECTORY_FILE)
1699 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1702 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1703 AFS_TRACE_LEVEL_VERBOSE,
1704 "AFSProcessCreate (%p) Creating file %wZ Attributes %08lX\n",
1709 if( BooleanFlagOn( VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
1712 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1713 AFS_TRACE_LEVEL_ERROR,
1714 "AFSProcessCreate Request failed due to read only volume %wZ\n",
1717 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
1720 pParentObjectInfo = ParentDirCB->ObjectInformation;
1723 // Allocate and insert the direntry into the parent node
1726 ntStatus = AFSCreateDirEntry( AuthGroup,
1734 if( !NT_SUCCESS( ntStatus))
1737 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1738 AFS_TRACE_LEVEL_ERROR,
1739 "AFSProcessCreate (%p) Failed to create directory entry %wZ Status %08lX\n",
1744 try_return( ntStatus);
1747 bFileCreated = TRUE;
1749 pObjectInfo = pDirEntry->ObjectInformation;
1751 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1752 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1755 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1756 AFS_TRACE_LEVEL_VERBOSE,
1757 "AFSProcessCreate (%p) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1759 &pDirEntry->NameInformation.FileName,
1760 pObjectInfo->FileId.Cell,
1761 pObjectInfo->FileId.Volume,
1762 pObjectInfo->FileId.Vnode,
1763 pObjectInfo->FileId.Unique));
1765 ntStatus = AFSEvaluateNode( AuthGroup,
1768 if( !NT_SUCCESS( ntStatus))
1771 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
1774 if ( !BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
1777 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1778 AFS_TRACE_LEVEL_ERROR,
1779 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
1781 &pDirEntry->NameInformation.FileName,
1782 pObjectInfo->FileId.Cell,
1783 pObjectInfo->FileId.Volume,
1784 pObjectInfo->FileId.Vnode,
1785 pObjectInfo->FileId.Unique,
1786 pParentObjectInfo->FileId.Cell,
1787 pParentObjectInfo->FileId.Volume,
1788 pParentObjectInfo->FileId.Vnode,
1789 pParentObjectInfo->FileId.Unique,
1792 else if ( AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId))
1795 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1796 AFS_TRACE_LEVEL_ERROR,
1797 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1799 &pDirEntry->NameInformation.FileName,
1800 pObjectInfo->FileId.Cell,
1801 pObjectInfo->FileId.Volume,
1802 pObjectInfo->FileId.Vnode,
1803 pObjectInfo->FileId.Unique,
1804 pParentObjectInfo->FileId.Cell,
1805 pParentObjectInfo->FileId.Volume,
1806 pParentObjectInfo->FileId.Vnode,
1807 pParentObjectInfo->FileId.Unique,
1813 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1814 AFS_TRACE_LEVEL_ERROR,
1815 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1817 &pDirEntry->NameInformation.FileName,
1818 pObjectInfo->FileId.Cell,
1819 pObjectInfo->FileId.Volume,
1820 pObjectInfo->FileId.Vnode,
1821 pObjectInfo->FileId.Unique,
1822 pParentObjectInfo->FileId.Cell,
1823 pParentObjectInfo->FileId.Volume,
1824 pParentObjectInfo->FileId.Vnode,
1825 pParentObjectInfo->FileId.Unique,
1826 pObjectInfo->ParentFileId.Cell,
1827 pObjectInfo->ParentFileId.Volume,
1828 pObjectInfo->ParentFileId.Vnode,
1829 pObjectInfo->ParentFileId.Unique,
1836 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1837 AFS_TRACE_LEVEL_ERROR,
1838 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1840 &pDirEntry->NameInformation.FileName,
1841 pObjectInfo->FileId.Cell,
1842 pObjectInfo->FileId.Volume,
1843 pObjectInfo->FileId.Vnode,
1844 pObjectInfo->FileId.Unique,
1848 try_return( ntStatus);
1851 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1854 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
1855 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
1858 // We may have raced and the Fcb is already created
1862 // Allocate and initialize the Fcb for the file.
1865 ntStatus = AFSInitFcb( pDirEntry);
1867 *Fcb = pObjectInfo->Fcb;
1869 if( !NT_SUCCESS( ntStatus))
1872 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1873 AFS_TRACE_LEVEL_ERROR,
1874 "AFSProcessCreate (%p) Failed to initialize fcb %wZ Status %08lX\n",
1879 try_return( ntStatus);
1882 ntStatus = STATUS_SUCCESS;
1885 // Increment the open count on this Fcb
1888 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1890 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1891 AFS_TRACE_LEVEL_VERBOSE,
1892 "AFSProcessCreate Increment count on Fcb %p Cnt %d\n",
1899 // Initialize the Ccb for the file.
1902 ntStatus = AFSInitCcb( Ccb,
1907 if( !NT_SUCCESS( ntStatus))
1910 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1911 AFS_TRACE_LEVEL_ERROR,
1912 "AFSProcessCreate (%p) Failed to initialize ccb %wZ Status %08lX\n",
1917 try_return( ntStatus);
1920 bAllocatedCcb = TRUE;
1923 // If this is a file, update the headers filesizes.
1926 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1930 // Update the sizes with the information passed in
1933 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
1934 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1935 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1938 // Notify the system of the addition
1941 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1943 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1944 (ULONG)FILE_ACTION_ADDED);
1946 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
1948 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1952 // This is a new directory node so indicate it has been enumerated
1955 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1958 // And the parent directory entry
1961 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1964 // Notify the system of the addition
1967 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1969 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1970 (ULONG)FILE_ACTION_ADDED);
1972 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
1973 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
1974 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
1975 (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
1979 // And the parent directory entry
1982 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1985 // Notify the system of the addition
1988 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1990 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1991 (ULONG)FILE_ACTION_ADDED);
1995 // Save off the access for the open
1998 IoSetShareAccess( *pDesiredAccess,
2001 &(*Fcb)->ShareAccess);
2003 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2005 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2006 AFS_TRACE_LEVEL_VERBOSE,
2007 "AFSProcessCreate Increment handle count on Fcb %p Cnt %d\n",
2012 // Increment the open reference and handle on the parent node
2015 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2017 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2018 AFS_TRACE_LEVEL_VERBOSE,
2019 "AFSProcessCreate Increment child open handle count on Parent object %p Cnt %d\n",
2023 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2025 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2026 AFS_TRACE_LEVEL_VERBOSE,
2027 "AFSProcessCreate Increment child open ref count on Parent object %p Cnt %d\n",
2031 if( ulOptions & FILE_DELETE_ON_CLOSE)
2035 // Mark it for delete on close
2038 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2039 AFS_TRACE_LEVEL_VERBOSE,
2040 "AFSProcessCreate (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2045 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2049 // Indicate the object is locked in the service
2052 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2055 // Return the open result for this file
2058 Irp->IoStatus.Information = FILE_CREATED;
2063 // If we created the Fcb we need to release the resources
2069 if( !NT_SUCCESS( ntStatus))
2072 // Decrement the open count on this Fcb
2075 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2077 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2078 AFS_TRACE_LEVEL_VERBOSE,
2079 "AFSProcessCreate Decrement count on Fcb %p Cnt %d\n",
2084 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2091 // Decrement the reference added during initialization of the DE
2092 // AFSInitCcb allocates its own reference count.
2095 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2097 AFSDbgTrace(( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2098 AFS_TRACE_LEVEL_VERBOSE,
2099 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2100 &pDirEntry->NameInformation.FileName,
2104 ASSERT( lCount >= 0);
2107 if( !NT_SUCCESS( ntStatus))
2113 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2114 AFS_TRACE_LEVEL_VERBOSE,
2115 "AFSProcessCreate Create failed, removing DE %p from parent object %p Status %08lX\n",
2121 // Remove the dir entry from the parent
2124 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2127 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2129 AFSNotifyDelete( pDirEntry,
2134 // Pull the directory entry from the parent
2137 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2139 FALSE); // Leave it in the enum list so the worker cleans it up
2142 // Tag the parent as needing verification
2145 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2147 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2149 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2160 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2173 AFSOpenTargetDirectory( IN PIRP Irp,
2174 IN AFSVolumeCB *VolumeCB,
2175 IN AFSDirectoryCB *ParentDirectoryCB,
2176 IN AFSDirectoryCB *TargetDirectoryCB,
2177 IN UNICODE_STRING *TargetName,
2181 UNREFERENCED_PARAMETER(VolumeCB);
2182 NTSTATUS ntStatus = STATUS_SUCCESS;
2183 PFILE_OBJECT pFileObject = NULL;
2184 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2185 PACCESS_MASK pDesiredAccess = NULL;
2186 USHORT usShareAccess;
2187 BOOLEAN bAllocatedCcb = FALSE;
2188 BOOLEAN bReleaseFcb = FALSE;
2189 AFSObjectInfoCB *pParentObject = NULL;
2190 AFSObjectInfoCB *pGrandParentObject = NULL;
2191 UNICODE_STRING uniTargetName;
2197 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2198 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2200 pFileObject = pIrpSp->FileObject;
2202 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2203 AFS_TRACE_LEVEL_VERBOSE,
2204 "AFSOpenTargetDirectory (%p) Processing file %wZ\n",
2208 pParentObject = ParentDirectoryCB->ObjectInformation;
2210 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2213 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2217 // Make sure we have an Fcb for the access
2220 // Allocate and initialize the Fcb for the file.
2223 ntStatus = AFSInitFcb( ParentDirectoryCB);
2225 *Fcb = pParentObject->Fcb;
2227 if( !NT_SUCCESS( ntStatus))
2230 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2231 AFS_TRACE_LEVEL_ERROR,
2232 "AFSOpenTargetDirectory (%p) Failed to initialize fcb %wZ Status %08lX\n",
2234 &ParentDirectoryCB->NameInformation.FileName,
2237 try_return( ntStatus);
2240 ntStatus = STATUS_SUCCESS;
2243 // Increment the open count on this Fcb
2246 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2248 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2249 AFS_TRACE_LEVEL_VERBOSE,
2250 "AFSOpenTargetDirectory Increment count on Fcb %p Cnt %d\n",
2257 // If there are current opens on the Fcb, check the access.
2260 if( pParentObject->Fcb->OpenHandleCount > 0)
2263 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2266 &pParentObject->Fcb->ShareAccess,
2269 if( !NT_SUCCESS( ntStatus))
2272 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2273 AFS_TRACE_LEVEL_ERROR,
2274 "AFSOpenTargetDirectory (%p) Access check failure %wZ Status %08lX\n",
2276 &ParentDirectoryCB->NameInformation.FileName,
2279 try_return( ntStatus);
2284 // Initialize the Ccb for the file.
2287 ntStatus = AFSInitCcb( Ccb,
2292 if( !NT_SUCCESS( ntStatus))
2295 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2296 AFS_TRACE_LEVEL_ERROR,
2297 "AFSOpenTargetDirectory (%p) Failed to initialize ccb %wZ Status %08lX\n",
2299 &ParentDirectoryCB->NameInformation.FileName,
2302 try_return( ntStatus);
2305 bAllocatedCcb = TRUE;
2307 if( TargetDirectoryCB != NULL &&
2308 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2314 Irp->IoStatus.Information = FILE_EXISTS;
2316 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2321 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2323 uniTargetName = *TargetName;
2327 // Update the filename in the fileobject for rename processing
2330 RtlCopyMemory( pFileObject->FileName.Buffer,
2331 uniTargetName.Buffer,
2332 uniTargetName.Length);
2334 pFileObject->FileName.Length = uniTargetName.Length;
2337 // OK, update the share access on the fileobject
2340 if( pParentObject->Fcb->OpenHandleCount > 0)
2343 IoUpdateShareAccess( pFileObject,
2344 &pParentObject->Fcb->ShareAccess);
2353 IoSetShareAccess( *pDesiredAccess,
2356 &pParentObject->Fcb->ShareAccess);
2359 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2361 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2362 AFS_TRACE_LEVEL_VERBOSE,
2363 "AFSOpenTargetDirectory Increment handle count on Fcb %p Cnt %d\n",
2368 // Increment the open reference and handle on the parent node
2371 if( BooleanFlagOn( pParentObject->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
2374 pGrandParentObject = AFSFindObjectInfo( pParentObject->VolumeCB,
2375 &pParentObject->ParentFileId);
2377 if ( pGrandParentObject)
2380 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenHandleCount);
2382 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2383 AFS_TRACE_LEVEL_VERBOSE,
2384 "AFSOpenTargetDirectory Increment child open handle count on Parent object %p Cnt %d\n",
2388 lCount = InterlockedIncrement( &pGrandParentObject->Specific.Directory.ChildOpenReferenceCount);
2390 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2391 AFS_TRACE_LEVEL_VERBOSE,
2392 "AFSOpenTargetDirectory Increment child open ref count on Parent object %p Cnt %d\n",
2396 AFSReleaseObjectInfo( &pGrandParentObject);
2405 if( !NT_SUCCESS( ntStatus))
2408 // Decrement the open count on this Fcb
2411 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2413 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2414 AFS_TRACE_LEVEL_VERBOSE,
2415 "AFSOpenTargetDirectory Decrement count on Fcb %p Cnt %d\n",
2420 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2423 if( !NT_SUCCESS( ntStatus))
2436 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2447 AFSProcessOpen( IN PIRP Irp,
2449 IN AFSVolumeCB *VolumeCB,
2450 IN AFSDirectoryCB *ParentDirCB,
2451 IN AFSDirectoryCB *DirectoryCB,
2455 UNREFERENCED_PARAMETER(VolumeCB);
2456 NTSTATUS ntStatus = STATUS_SUCCESS;
2457 PFILE_OBJECT pFileObject = NULL;
2458 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2459 PACCESS_MASK pDesiredAccess = NULL;
2460 USHORT usShareAccess;
2461 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE;
2462 ULONG ulOptions = 0;
2463 AFSFileOpenCB stOpenCB;
2464 AFSFileOpenResultCB stOpenResultCB;
2465 ULONG ulResultLen = 0;
2466 AFSObjectInfoCB *pParentObjectInfo = NULL;
2467 AFSObjectInfoCB *pObjectInfo = NULL;
2468 ULONG ulFileAccess = 0;
2469 AFSFileAccessReleaseCB stReleaseFileAccess;
2475 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2476 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2478 pFileObject = pIrpSp->FileObject;
2480 pParentObjectInfo = ParentDirCB->ObjectInformation;
2482 pObjectInfo = DirectoryCB->ObjectInformation;
2484 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
2485 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
2488 // Check if the entry is pending a deletion
2491 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2494 ntStatus = STATUS_DELETE_PENDING;
2496 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2497 AFS_TRACE_LEVEL_ERROR,
2498 "AFSProcessOpen (%p) Entry pending delete %wZ Status %08lX\n",
2500 &DirectoryCB->NameInformation.FileName,
2503 try_return( ntStatus);
2507 // Extract out the options
2510 ulOptions = pIrpSp->Parameters.Create.Options;
2513 // Check if we should go and retrieve updated information for the node
2516 ntStatus = AFSValidateEntry( DirectoryCB,
2521 if( !NT_SUCCESS( ntStatus))
2524 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2525 AFS_TRACE_LEVEL_ERROR,
2526 "AFSProcessOpen (%p) Failed to validate entry %wZ Status %08lX\n",
2528 &DirectoryCB->NameInformation.FileName,
2531 try_return( ntStatus);
2535 // If this is marked for delete on close then be sure we can delete the entry
2538 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2541 ntStatus = AFSNotifyDelete( DirectoryCB,
2545 if( !NT_SUCCESS( ntStatus))
2548 ntStatus = STATUS_CANNOT_DELETE;
2550 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2551 AFS_TRACE_LEVEL_ERROR,
2552 "AFSProcessOpen (%p) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2554 &DirectoryCB->NameInformation.FileName,
2557 try_return( ntStatus);
2562 // Be sure we have an Fcb for the current object
2565 ntStatus = AFSInitFcb( DirectoryCB);
2567 if( !NT_SUCCESS( ntStatus))
2570 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2571 AFS_TRACE_LEVEL_ERROR,
2572 "AFSProcessOpen (%p) Failed to init fcb on %wZ Status %08lX\n",
2574 &DirectoryCB->NameInformation.FileName,
2577 try_return( ntStatus);
2580 ntStatus = STATUS_SUCCESS;
2583 // AFSInitFcb returns the Fcb resource held
2589 // Increment the open count on this Fcb
2592 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2594 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2595 AFS_TRACE_LEVEL_VERBOSE,
2596 "AFSProcessOpen Increment2 count on Fcb %p Cnt %d\n",
2601 // Check access on the entry
2604 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2607 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2610 &pObjectInfo->Fcb->ShareAccess,
2613 if( !NT_SUCCESS( ntStatus))
2616 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2617 AFS_TRACE_LEVEL_ERROR,
2618 "AFSProcessOpen (%p) Failed to check share access on %wZ Status %08lX\n",
2620 &DirectoryCB->NameInformation.FileName,
2623 try_return( ntStatus);
2628 // Additional checks
2631 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2635 // If the caller is asking for write access then try to flush the image section
2638 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2639 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2644 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2645 AFS_TRACE_LEVEL_VERBOSE,
2646 "AFSProcessOpen Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2647 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2648 PsGetCurrentThread()));
2650 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2653 bMmFlushed = MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2656 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
2657 AFS_TRACE_LEVEL_VERBOSE,
2658 "AFSProcessOpen Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2659 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2660 PsGetCurrentThread()));
2662 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
2667 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2668 STATUS_SHARING_VIOLATION;
2670 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2671 AFS_TRACE_LEVEL_ERROR,
2672 "AFSProcessOpen (%p) Failed to flush image section %wZ Status %08lX\n",
2674 &DirectoryCB->NameInformation.FileName,
2677 try_return( ntStatus);
2681 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2684 ntStatus = STATUS_NOT_A_DIRECTORY;
2686 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2687 AFS_TRACE_LEVEL_ERROR,
2688 "AFSProcessOpen (%p) Attempt to open file as directory %wZ Status %08lX\n",
2690 &DirectoryCB->NameInformation.FileName,
2693 try_return( ntStatus);
2696 pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2698 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2699 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2702 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2705 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2707 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2708 AFS_TRACE_LEVEL_ERROR,
2709 "AFSProcessOpen (%p) Attempt to open directory as file %wZ Status %08lX\n",
2711 &DirectoryCB->NameInformation.FileName,
2714 try_return( ntStatus);
2717 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2718 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2719 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2720 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2727 try_return( ntStatus = STATUS_UNSUCCESSFUL);
2731 // Check with the service that we can open the file
2734 stOpenCB.ParentId = pParentObjectInfo->FileId;
2736 stOpenCB.DesiredAccess = *pDesiredAccess;
2738 stOpenCB.ShareAccess = usShareAccess;
2740 stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2742 stOpenCB.Identifier = (ULONGLONG)pFileObject;
2744 stOpenResultCB.GrantedAccess = 0;
2746 ulResultLen = sizeof( AFSFileOpenResultCB);
2748 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2749 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2751 &DirectoryCB->NameInformation.FileName,
2752 &pObjectInfo->FileId,
2753 pObjectInfo->VolumeCB->VolumeInformation.Cell,
2754 pObjectInfo->VolumeCB->VolumeInformation.CellLength,
2756 sizeof( AFSFileOpenCB),
2757 (void *)&stOpenResultCB,
2760 if( !NT_SUCCESS( ntStatus))
2763 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2764 AFS_TRACE_LEVEL_ERROR,
2765 "AFSProcessOpen (%p) Failed open in service %wZ Status %08lX\n",
2767 &DirectoryCB->NameInformation.FileName,
2770 try_return( ntStatus);
2774 // Save the granted access in case we need to release it below
2777 ulFileAccess = stOpenResultCB.FileAccess;
2780 // Check if there is a conflict
2783 if( !AFSCheckAccess( *pDesiredAccess,
2784 stOpenResultCB.GrantedAccess,
2785 BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2788 ntStatus = STATUS_ACCESS_DENIED;
2790 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2791 AFS_TRACE_LEVEL_ERROR,
2792 "AFSProcessOpen (%p) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2795 stOpenResultCB.GrantedAccess,
2796 &DirectoryCB->NameInformation.FileName,
2799 try_return( ntStatus);
2803 // Initialize the Ccb for the file.
2806 ntStatus = AFSInitCcb( Ccb,
2811 if( !NT_SUCCESS( ntStatus))
2814 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2815 AFS_TRACE_LEVEL_ERROR,
2816 "AFSProcessOpen (%p) Failed to initialize ccb %wZ Status %08lX\n",
2818 &DirectoryCB->NameInformation.FileName,
2821 try_return( ntStatus);
2824 bAllocatedCcb = TRUE;
2827 // Perform the access check on the target if this is a mount point or symlink
2830 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2833 IoUpdateShareAccess( pFileObject,
2834 &pObjectInfo->Fcb->ShareAccess);
2843 IoSetShareAccess( *pDesiredAccess,
2846 &pObjectInfo->Fcb->ShareAccess);
2849 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2851 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2852 AFS_TRACE_LEVEL_VERBOSE,
2853 "AFSProcessOpen Increment handle count on Fcb %p Cnt %d\n",
2858 // Increment the open reference and handle on the parent node
2861 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
2863 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2864 AFS_TRACE_LEVEL_VERBOSE,
2865 "AFSProcessOpen Increment child open handle count on Parent object %p Cnt %d\n",
2869 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
2871 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2872 AFS_TRACE_LEVEL_VERBOSE,
2873 "AFSProcessOpen Increment child open ref count on Parent object %p Cnt %d\n",
2877 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2881 // Mark it for delete on close
2884 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
2885 AFS_TRACE_LEVEL_VERBOSE,
2886 "AFSProcessOpen (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2889 &DirectoryCB->NameInformation.FileName));
2891 SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2895 // Indicate the object is held
2898 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2901 // Return the open result for this file
2904 Irp->IoStatus.Information = FILE_OPENED;
2906 *Fcb = pObjectInfo->Fcb;
2913 if( !NT_SUCCESS( ntStatus))
2916 // Decrement the open count on this Fcb
2919 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2921 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2922 AFS_TRACE_LEVEL_VERBOSE,
2923 "AFSProcessOpen Decrement2 count on Fcb %p Cnt %d\n",
2928 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2931 if( !NT_SUCCESS( ntStatus))
2934 if ( ulFileAccess > 0)
2937 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2939 stReleaseFileAccess.FileAccess = ulFileAccess;
2941 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2943 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2944 AFS_REQUEST_FLAG_SYNCHRONOUS,
2946 &DirectoryCB->NameInformation.FileName,
2947 &pObjectInfo->FileId,
2948 pObjectInfo->VolumeCB->VolumeInformation.Cell,
2949 pObjectInfo->VolumeCB->VolumeInformation.CellLength,
2950 (void *)&stReleaseFileAccess,
2951 sizeof( AFSFileAccessReleaseCB),
2966 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2977 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
2979 IN AFSVolumeCB *VolumeCB,
2981 IN AFSDirectoryCB *ParentDirCB,
2982 IN AFSDirectoryCB *DirectoryCB,
2986 UNREFERENCED_PARAMETER(DeviceObject);
2987 NTSTATUS ntStatus = STATUS_SUCCESS;
2988 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2989 PFILE_OBJECT pFileObject = NULL;
2990 LARGE_INTEGER liZero = {0,0};
2991 BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
2992 ULONG ulAttributes = 0;
2993 ULONG ulCreateDisposition = 0;
2994 BOOLEAN bAllocatedCcb = FALSE;
2995 BOOLEAN bUserMapped = FALSE;
2996 PACCESS_MASK pDesiredAccess = NULL;
2997 USHORT usShareAccess;
2998 AFSObjectInfoCB *pParentObjectInfo = NULL;
2999 AFSObjectInfoCB *pObjectInfo = NULL;
3001 LARGE_INTEGER liSaveSize;
3002 LARGE_INTEGER liSaveVDL;
3003 LARGE_INTEGER liSaveAlloc;
3008 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3010 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
3012 pFileObject = pIrpSp->FileObject;
3014 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
3016 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
3018 if( BooleanFlagOn( VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
3021 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3022 AFS_TRACE_LEVEL_ERROR,
3023 "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3025 &DirectoryCB->NameInformation.FileName));
3027 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3030 pParentObjectInfo = ParentDirCB->ObjectInformation;
3032 pObjectInfo = DirectoryCB->ObjectInformation;
3034 ASSERT( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID) &&
3035 AFSIsEqualFID( &pParentObjectInfo->FileId, &pObjectInfo->ParentFileId));
3038 // Check if we should go and retrieve updated information for the node
3041 ntStatus = AFSValidateEntry( DirectoryCB,
3046 if( !NT_SUCCESS( ntStatus))
3049 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3050 AFS_TRACE_LEVEL_ERROR,
3051 "AFSProcessOverwriteSupersede (%p) Failed to validate entry %wZ Status %08lX\n",
3053 &DirectoryCB->NameInformation.FileName,
3056 try_return( ntStatus);
3060 // Be sure we have an Fcb for the object block
3063 ntStatus = AFSInitFcb( DirectoryCB);
3065 *Fcb = pObjectInfo->Fcb;
3067 if( !NT_SUCCESS( ntStatus))
3070 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3071 AFS_TRACE_LEVEL_ERROR,
3072 "AFSProcessOverwriteSupersede (%p) Failed to initialize fcb %wZ Status %08lX\n",
3074 &DirectoryCB->NameInformation.FileName,
3077 try_return( ntStatus);
3080 ntStatus = STATUS_SUCCESS;
3083 // Increment the open count on this Fcb.
3086 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3088 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3089 AFS_TRACE_LEVEL_VERBOSE,
3090 "AFSProcessOverwriteSupersede Increment2 count on Fcb %p Cnt %d\n",
3097 // Check access on the entry
3100 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3103 ntStatus = IoCheckShareAccess( *pDesiredAccess,
3106 &pObjectInfo->Fcb->ShareAccess,
3109 if( !NT_SUCCESS( ntStatus))
3112 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3113 AFS_TRACE_LEVEL_ERROR,
3114 "AFSProcessOverwriteSupersede (%p) Access check failure %wZ Status %08lX\n",
3116 &DirectoryCB->NameInformation.FileName,
3119 try_return( ntStatus);
3123 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3124 AFS_TRACE_LEVEL_VERBOSE,
3125 "AFSProcessOverwriteSupercede Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3126 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3127 PsGetCurrentThread()));
3129 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3133 // Before we actually truncate, check to see if the purge
3134 // is going to fail.
3137 bUserMapped = !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3140 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
3141 AFS_TRACE_LEVEL_VERBOSE,
3142 "AFSProcessOverwriteSupercede Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3143 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3144 PsGetCurrentThread()));
3146 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3151 ntStatus = STATUS_USER_MAPPED_FILE;
3153 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3154 AFS_TRACE_LEVEL_ERROR,
3155 "AFSProcessOverwriteSupersede (%p) File user mapped %wZ Status %08lX\n",
3157 &DirectoryCB->NameInformation.FileName,
3160 try_return( ntStatus);
3164 // Initialize the Ccb for the file.
3167 ntStatus = AFSInitCcb( Ccb,
3172 if( !NT_SUCCESS( ntStatus))
3175 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3176 AFS_TRACE_LEVEL_ERROR,
3177 "AFSProcessOverwriteSupersede (%p) Failed to initialize ccb %wZ Status %08lX\n",
3179 &DirectoryCB->NameInformation.FileName,
3182 try_return( ntStatus);
3185 bAllocatedCcb = TRUE;
3188 // Set the file length to zero
3191 AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3194 bReleasePaging = TRUE;
3196 liSaveSize = pObjectInfo->Fcb->Header.FileSize;
3197 liSaveAlloc = pObjectInfo->Fcb->Header.AllocationSize;
3198 liSaveVDL = pObjectInfo->Fcb->Header.ValidDataLength;
3200 pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3201 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3202 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3204 pObjectInfo->EndOfFile.QuadPart = 0;
3205 pObjectInfo->AllocationSize.QuadPart = 0;
3208 // Trim down the extents. We do this BEFORE telling the service
3209 // the file is truncated since there is a potential race between
3210 // a worker thread releasing extents and us trimming
3213 AFSTrimExtents( pObjectInfo->Fcb,
3214 &pObjectInfo->Fcb->Header.FileSize);
3216 KeQuerySystemTime( &pObjectInfo->ChangeTime);
3218 KeQuerySystemTime( &pObjectInfo->LastAccessTime);
3220 KeQuerySystemTime( &pObjectInfo->LastWriteTime);
3223 // Set the update flag accordingly
3226 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
3227 AFS_FCB_FLAG_UPDATE_CREATE_TIME |
3228 AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
3229 AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
3230 AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
3232 ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
3236 if( !NT_SUCCESS( ntStatus))
3239 pObjectInfo->Fcb->Header.ValidDataLength = liSaveVDL;
3240 pObjectInfo->Fcb->Header.FileSize = liSaveSize;
3241 pObjectInfo->Fcb->Header.AllocationSize = liSaveAlloc;
3242 pObjectInfo->Fcb->ObjectInformation->EndOfFile = liSaveSize;
3243 pObjectInfo->Fcb->ObjectInformation->AllocationSize = liSaveAlloc;
3245 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3246 AFS_TRACE_LEVEL_ERROR,
3247 "AFSProcessOverwriteSupersede (%p) Failed to update file information %wZ Status %08lX\n",
3249 &DirectoryCB->NameInformation.FileName,
3252 try_return( ntStatus);
3255 ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
3257 if( ulCreateDisposition == FILE_SUPERSEDE)
3260 pObjectInfo->FileAttributes = ulAttributes;
3266 pObjectInfo->FileAttributes |= ulAttributes;
3270 // Save off the access for the open
3273 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3276 IoUpdateShareAccess( pFileObject,
3277 &pObjectInfo->Fcb->ShareAccess);
3286 IoSetShareAccess( *pDesiredAccess,
3289 &pObjectInfo->Fcb->ShareAccess);
3293 // Return the correct action
3296 if( ulCreateDisposition == FILE_SUPERSEDE)
3299 Irp->IoStatus.Information = FILE_SUPERSEDED;
3304 Irp->IoStatus.Information = FILE_OVERWRITTEN;
3307 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
3309 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3310 AFS_TRACE_LEVEL_VERBOSE,
3311 "AFSProcessOverwriteSupersede Increment handle count on Fcb %p Cnt %d\n",
3316 // Increment the open reference and handle on the parent node
3319 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3321 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3322 AFS_TRACE_LEVEL_VERBOSE,
3323 "AFSProcessOverwriteSupersede Increment child open handle count on Parent object %p Cnt %d\n",
3327 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3329 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3330 AFS_TRACE_LEVEL_VERBOSE,
3331 "AFSProcessOverwriteSupersede Increment child open ref count on Parent object %p Cnt %d\n",
3335 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3337 bReleaseFcb = FALSE;
3339 *Fcb = pObjectInfo->Fcb;
3342 // Now that the Fcb->Resource has been dropped
3343 // we can call CcSetFileSizes. We are still holding
3344 // the PagingIoResource
3347 pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
3349 pFileObject->FsContext = (void *)pObjectInfo->Fcb;
3351 pFileObject->FsContext2 = (void *)*Ccb;
3353 CcSetFileSizes( pFileObject,
3354 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3361 AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3367 if( !NT_SUCCESS( ntStatus))
3370 // Decrement the open count on this Fcb.
3373 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
3375 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3376 AFS_TRACE_LEVEL_VERBOSE,
3377 "AFSProcessOverwriteSupersede Decrement2 count on Fcb %p Cnt %d\n",
3382 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3385 if( !NT_SUCCESS( ntStatus))
3398 // Fcb will be freed by AFSPrimaryVolumeWorker thread
3409 AFSControlDeviceCreate( IN PIRP Irp)
3412 NTSTATUS ntStatus = STATUS_SUCCESS;
3417 if ( KernelMode == Irp->RequestorMode) {
3419 // For now, just let the open happen
3421 Irp->IoStatus.Information = FILE_OPENED;
3426 // Not from usermode, All access must be via
3427 // the FS component (which will do the
3430 ntStatus = STATUS_ACCESS_DENIED;
3438 // AFSOpenIOCtlFcb does not release a DirOpenReferenceCount on
3443 AFSOpenIOCtlFcb( IN PIRP Irp,
3445 IN AFSDirectoryCB *ParentDirCB,
3450 NTSTATUS ntStatus = STATUS_SUCCESS;
3451 PFILE_OBJECT pFileObject = NULL;
3452 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3453 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
3454 AFSPIOCtlOpenCloseRequestCB stPIOCtlOpen;
3456 AFSObjectInfoCB *pParentObjectInfo = NULL;
3462 pFileObject = pIrpSp->FileObject;
3464 pParentObjectInfo = ParentDirCB->ObjectInformation;
3467 // If we haven't initialized the PIOCtl DirectoryCB for this directory then do it now
3470 if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB == NULL)
3473 ntStatus = AFSInitPIOCtlDirectoryCB( pParentObjectInfo);
3475 if( !NT_SUCCESS( ntStatus))
3478 try_return( ntStatus);
3483 // Allocate and initialize the Fcb for the file.
3486 ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB);
3488 *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
3490 if( !NT_SUCCESS( ntStatus))
3493 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3494 AFS_TRACE_LEVEL_ERROR,
3495 "AFSOpenIOCtlFcb (%p) Failed to initialize fcb Status %08lX\n",
3499 try_return( ntStatus);
3502 ntStatus = STATUS_SUCCESS;
3505 // Increment the open reference and handle on the node
3508 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3510 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3511 AFS_TRACE_LEVEL_VERBOSE,
3512 "AFSOpenIOCtlFcb Increment count on Fcb %p Cnt %d\n",
3519 // Initialize the Ccb for the file.
3522 ntStatus = AFSInitCcb( Ccb,
3523 pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
3527 if( !NT_SUCCESS( ntStatus))
3530 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3531 AFS_TRACE_LEVEL_ERROR,
3532 "AFSOpenIOCtlFcb (%p) Failed to initialize ccb Status %08lX\n",
3536 try_return( ntStatus);
3539 bAllocatedCcb = TRUE;
3542 // Set the PIOCtl index
3545 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3547 RtlZeroMemory( &stPIOCtlOpen,
3548 sizeof( AFSPIOCtlOpenCloseRequestCB));
3550 stPIOCtlOpen.RequestId = (*Ccb)->RequestID;
3552 stPIOCtlOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3554 RtlZeroMemory( &stFileID,
3555 sizeof( AFSFileID));
3558 // The parent directory FID of the node
3561 stFileID = pParentObjectInfo->FileId;
3564 // Issue the open request to the service
3567 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_OPEN,
3568 AFS_REQUEST_FLAG_SYNCHRONOUS,
3574 (void *)&stPIOCtlOpen,
3575 sizeof( AFSPIOCtlOpenCloseRequestCB),
3579 if( !NT_SUCCESS( ntStatus))
3582 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
3583 AFS_TRACE_LEVEL_ERROR,
3584 "AFSOpenIOCtlFcb (%p) Failed service open Status %08lX\n",
3588 try_return( ntStatus);
3592 // Increment the handle on the node
3595 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3597 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3598 AFS_TRACE_LEVEL_VERBOSE,
3599 "AFSOpenIOCtlFcb Increment handle count on Fcb %p Cnt %d\n",
3604 // Increment the open reference and handle on the parent node
3607 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3609 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3610 AFS_TRACE_LEVEL_VERBOSE,
3611 "AFSOpenIOCtlFcb Increment child open handle count on Parent object %p Cnt %d\n",
3615 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3617 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3618 AFS_TRACE_LEVEL_VERBOSE,
3619 "AFSOpenIOCtlFcb Increment child open ref count on Parent object %p Cnt %d\n",
3624 // Return the open result for this file
3627 Irp->IoStatus.Information = FILE_OPENED;
3632 // If we created the Fcb we need to release the resources
3638 if( !NT_SUCCESS( ntStatus))
3641 // Decrement the open reference and handle on the node
3644 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3646 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3647 AFS_TRACE_LEVEL_VERBOSE,
3648 "AFSOpenIOCtlFcb Decrement count on Fcb %p Cnt %d\n",
3653 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3656 if( !NT_SUCCESS( ntStatus))
3669 // Fcb will be freed by AFSPrimaryVolumeWorker thread
3680 AFSOpenSpecialShareFcb( IN PIRP Irp,
3682 IN AFSDirectoryCB *DirectoryCB,
3687 NTSTATUS ntStatus = STATUS_SUCCESS;
3688 PFILE_OBJECT pFileObject = NULL;
3689 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3690 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE, bAllocateFcb = FALSE;
3691 AFSObjectInfoCB *pObjectInfo = NULL;
3692 AFSObjectInfoCB *pParentObjectInfo = NULL;
3693 AFSPipeOpenCloseRequestCB stPipeOpen;
3699 pFileObject = pIrpSp->FileObject;
3701 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
3702 AFS_TRACE_LEVEL_VERBOSE_2,
3703 "AFSOpenSpecialShareFcb (%p) Processing Share %wZ open\n",
3705 &DirectoryCB->NameInformation.FileName));
3707 pObjectInfo = DirectoryCB->ObjectInformation;
3709 if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
3712 pParentObjectInfo = AFSFindObjectInfo( pObjectInfo->VolumeCB,
3713 &pObjectInfo->ParentFileId);
3716 if( DirectoryCB->ObjectInformation->Fcb == NULL)
3720 // Allocate and initialize the Fcb for the file.
3723 ntStatus = AFSInitFcb( DirectoryCB);
3725 *Fcb = pObjectInfo->Fcb;
3727 if( !NT_SUCCESS( ntStatus))
3730 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
3731 AFS_TRACE_LEVEL_ERROR,
3732 "AFSOpenSpecialShareFcb (%p) Failed to initialize fcb Status %08lX\n",
3736 try_return( ntStatus);
3739 if ( ntStatus != STATUS_REPARSE)
3742 bAllocateFcb = TRUE;
3745 ntStatus = STATUS_SUCCESS;
3750 *Fcb = pObjectInfo->Fcb;
3752 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
3757 // Increment the open count on this Fcb
3760 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3762 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3763 AFS_TRACE_LEVEL_VERBOSE,
3764 "AFSOpenSpecialShareFcb Increment count on Fcb %p Cnt %d\n",
3771 // Initialize the Ccb for the file.
3774 ntStatus = AFSInitCcb( Ccb,
3779 if( !NT_SUCCESS( ntStatus))
3782 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
3783 AFS_TRACE_LEVEL_ERROR,
3784 "AFSOpenSpecialShareFcb (%p) Failed to initialize ccb Status %08lX\n",
3788 try_return( ntStatus);
3791 bAllocatedCcb = TRUE;
3794 // Call the service to open the share
3797 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3799 RtlZeroMemory( &stPipeOpen,
3800 sizeof( AFSPipeOpenCloseRequestCB));
3802 stPipeOpen.RequestId = (*Ccb)->RequestID;
3804 stPipeOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3807 // Issue the open request to the service
3810 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_OPEN,
3811 AFS_REQUEST_FLAG_SYNCHRONOUS,
3813 &DirectoryCB->NameInformation.FileName,
3817 (void *)&stPipeOpen,
3818 sizeof( AFSPipeOpenCloseRequestCB),
3822 if( !NT_SUCCESS( ntStatus))
3825 AFSDbgTrace(( AFS_SUBSYSTEM_PIPE_PROCESSING,
3826 AFS_TRACE_LEVEL_ERROR,
3827 "AFSOpenSpecialShareFcb (%p) Failed service open Status %08lX\n",
3831 try_return( ntStatus);
3834 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3836 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3837 AFS_TRACE_LEVEL_VERBOSE,
3838 "AFSOpenSpecialShareFcb Increment handle count on Fcb %p Cnt %d\n",
3843 // Increment the open reference and handle on the parent node
3846 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3848 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3849 AFS_TRACE_LEVEL_VERBOSE,
3850 "AFSOpenSpecialShareFcb Increment child open handle count on Parent object %p Cnt %d\n",
3854 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3856 AFSDbgTrace(( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
3857 AFS_TRACE_LEVEL_VERBOSE,
3858 "AFSOpenSpecialShareFcb Increment child open ref count on Parent object %p Cnt %d\n",
3863 // Return the open result for this file
3866 Irp->IoStatus.Information = FILE_OPENED;
3873 if( !NT_SUCCESS( ntStatus))
3876 // Decrement the open count on this Fcb
3879 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3881 AFSDbgTrace(( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3882 AFS_TRACE_LEVEL_VERBOSE,
3883 "AFSOpenSpecialShareFcb Decrement count on Fcb %p Cnt %d\n",
3888 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3891 if( !NT_SUCCESS( ntStatus))
3907 // Need to tear down this Fcb since it is not in the tree for the worker thread
3910 AFSAcquireExcl( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
3913 AFSRemoveFcb( &DirectoryCB->ObjectInformation->Fcb);
3915 AFSReleaseResource( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);