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 AFSDirectoryCB *pParentDirectoryCB = NULL, *pDirectoryCB = NULL;
147 BOOLEAN bReleaseParentDir = FALSE, bReleaseDir = FALSE;
148 ULONG ulParseFlags = 0;
149 GUID stAuthGroup = {0};
150 ULONG ulNameProcessingFlags = 0;
151 BOOLEAN bOpenedReparsePoint = FALSE;
157 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
158 pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
159 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
160 ulOptions = pIrpSp->Parameters.Create.Options;
161 bNoIntermediateBuffering = BooleanFlagOn( ulOptions, FILE_NO_INTERMEDIATE_BUFFERING);
162 bOpenTargetDirectory = BooleanFlagOn( pIrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
163 pFileObject = pIrpSp->FileObject;
164 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
166 uniFileName.Length = uniFileName.MaximumLength = 0;
167 uniFileName.Buffer = NULL;
169 uniRootFileName.Length = uniRootFileName.MaximumLength = 0;
170 uniRootFileName.Buffer = NULL;
172 uniParsedFileName.Length = uniParsedFileName.MaximumLength = 0;
173 uniParsedFileName.Buffer = NULL;
175 uniSubstitutedPathName.Buffer = NULL;
176 uniSubstitutedPathName.Length = 0;
178 uniRelativeName.Buffer = NULL;
179 uniRelativeName.Length = 0;
181 if( AFSGlobalRoot == NULL)
183 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
186 RtlZeroMemory( &stAuthGroup,
189 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
190 (ULONGLONG)PsGetCurrentThreadId(),
194 // If we are in shutdown mode then fail the request
197 if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
200 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
201 AFS_TRACE_LEVEL_WARNING,
202 "AFSCommonCreate (%p) Open request after shutdown\n",
205 try_return( ntStatus = STATUS_TOO_LATE);
208 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
211 ntStatus = AFSEnumerateGlobalRoot( &stAuthGroup);
213 if( !NT_SUCCESS( ntStatus))
216 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
217 AFS_TRACE_LEVEL_ERROR,
218 "AFSCommonCreate Failed to enumerate global root Status %08lX\n",
221 try_return( ntStatus);
226 // Go and parse the name for processing.
227 // If ulParseFlags is returned with AFS_PARSE_FLAG_FREE_FILE_BUFFER set,
228 // then we are responsible for releasing the uniRootFileName.Buffer.
231 ntStatus = AFSParseName( Irp,
241 if( !NT_SUCCESS( ntStatus))
244 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
245 uniFileName.Length > 0 ? AFS_TRACE_LEVEL_ERROR : AFS_TRACE_LEVEL_VERBOSE,
246 "AFSCommonCreate (%p) Failed to parse name \"%wZ\" Status %08lX\n",
251 try_return( ntStatus);
255 // Check for STATUS_REPARSE
258 if( ntStatus == STATUS_REPARSE)
262 // Update the information and return
265 Irp->IoStatus.Information = IO_REPARSE;
267 try_return( ntStatus);
270 if ( pParentDirectoryCB != NULL)
273 bReleaseParentDir = TRUE;
277 // If the returned volume cb is NULL then we are dealing with the \\Server\GlobalRoot
281 if( pVolumeCB == NULL)
285 // Remove any leading or trailing slashes
288 if( uniFileName.Length >= sizeof( WCHAR) &&
289 uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
292 uniFileName.Length -= sizeof( WCHAR);
295 if( uniFileName.Length >= sizeof( WCHAR) &&
296 uniFileName.Buffer[ 0] == L'\\')
299 uniFileName.Buffer = &uniFileName.Buffer[ 1];
301 uniFileName.Length -= sizeof( WCHAR);
305 // If there is a remaining portion returned for this request then
306 // check if it is for the PIOCtl interface
309 if( uniFileName.Length > 0)
313 // We don't accept any other opens off of the AFS Root
316 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
319 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
322 if( RtlCompareUnicodeString( &AFSPIOCtlName,
328 // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
329 // AFSGlobalRoot->DirectoryCB.
332 ntStatus = AFSOpenIOCtlFcb( Irp,
334 AFSGlobalRoot->DirectoryCB,
338 if( !NT_SUCCESS( ntStatus))
341 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
342 AFS_TRACE_LEVEL_ERROR,
343 "AFSCommonCreate Failed to open root IOCtl Fcb Status %08lX\n",
347 else if( pParentDirectoryCB != NULL)
350 if( pParentDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
353 ntStatus = AFSOpenSpecialShareFcb( Irp,
359 if( !NT_SUCCESS( ntStatus))
362 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
363 AFS_TRACE_LEVEL_ERROR,
364 "AFSCommonCreate Failed to open special share Fcb Status %08lX\n",
370 try_return( ntStatus);
373 ntStatus = AFSOpenAFSRoot( Irp,
377 if( !NT_SUCCESS( ntStatus))
380 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
381 AFS_TRACE_LEVEL_ERROR,
382 "AFSCommonCreate Failed to open root Status %08lX\n",
386 try_return( ntStatus);
390 // We have a reference on the root volume
393 bReleaseVolume = TRUE;
396 // Attempt to locate the node in the name tree if this is not a target
397 // open and the target is not the root
400 uniComponentName.Length = 0;
401 uniComponentName.Buffer = NULL;
403 if( uniFileName.Length > sizeof( WCHAR) ||
404 uniFileName.Buffer[ 0] != L'\\')
407 if( !AFSValidNameFormat( &uniFileName))
410 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
412 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
413 AFS_TRACE_LEVEL_VERBOSE,
414 "AFSCommonCreate (%p) Invalid name %wZ Status %08lX\n",
419 try_return( ntStatus);
423 // Opening a reparse point directly?
426 ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
428 if( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
430 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
431 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
432 AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
435 uniSubstitutedPathName = uniRootFileName;
437 ntStatus = AFSLocateNameEntry( &stAuthGroup,
442 ulNameProcessingFlags,
448 if( !NT_SUCCESS( ntStatus) &&
449 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
452 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
454 uniSubstitutedPathName.Buffer = NULL;
458 // AFSLocateNameEntry released the Parent while walking the
462 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
463 AFS_TRACE_LEVEL_VERBOSE,
464 "AFSCommonCreate (%p) Failed to locate name entry for %wZ Status %08lX\n",
470 // We released any root volume locks in the above on failure
473 bReleaseVolume = FALSE;
475 bReleaseParentDir = FALSE;
477 try_return( ntStatus);
481 // Check for STATUS_REPARSE
484 if( ntStatus == STATUS_REPARSE)
487 uniSubstitutedPathName.Buffer = NULL;
490 // Update the information and return
493 Irp->IoStatus.Information = IO_REPARSE;
496 // We released the volume lock above
499 bReleaseVolume = FALSE;
501 bReleaseParentDir = FALSE;
503 try_return( ntStatus);
507 // If we re-allocated the name, then update our substitute name
510 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
513 uniSubstitutedPathName = uniRootFileName;
518 uniSubstitutedPathName.Buffer = NULL;
522 // Check for a symlink access
525 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
526 pParentDirectoryCB != NULL)
530 // pParentDirectoryCB DirOpenReferenceCount is still held
533 UNICODE_STRING uniFinalComponent;
535 uniFinalComponent.Length = 0;
536 uniFinalComponent.MaximumLength = 0;
537 uniFinalComponent.Buffer = NULL;
539 AFSRetrieveFinalComponent( &uniFileName,
542 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
545 if( !NT_SUCCESS( ntStatus) &&
546 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
549 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
550 AFS_TRACE_LEVEL_VERBOSE,
551 "AFSCommonCreate (%p) Failing access to symlink %wZ Status %08lX\n",
556 try_return( ntStatus);
563 // AFSLocateNameEntry succeeded. The parent directory reference
564 // has been released and if there is a directory returned, it is
568 bReleaseParentDir = FALSE;
579 // If we have no parent then this is a root open, be sure there is a directory entry
583 else if( pParentDirectoryCB == NULL &&
584 pDirectoryCB == NULL)
587 pDirectoryCB = pVolumeCB->DirectoryCB;
589 lCount = InterlockedIncrement( &pDirectoryCB->DirOpenReferenceCount);
591 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
592 AFS_TRACE_LEVEL_VERBOSE,
593 "AFSCommonCreate Increment0 count on %wZ DE %p Ccb %p Cnt %d\n",
594 &pDirectoryCB->NameInformation.FileName,
602 if( bOpenTargetDirectory)
606 // If we have a directory cb for the entry then dereference it and reference the parent
609 if( pDirectoryCB != NULL)
612 if ( !bReleaseParentDir)
616 // Perform in this order to prevent thrashing
619 lCount = InterlockedIncrement( &pParentDirectoryCB->DirOpenReferenceCount);
621 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
622 AFS_TRACE_LEVEL_VERBOSE,
623 "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
624 &pParentDirectoryCB->NameInformation.FileName,
629 bReleaseParentDir = TRUE;
633 // Do NOT decrement the reference count on the pDirectoryCB yet.
634 // The BackupEntry below might drop the count to zero leaving
635 // the entry subject to being deleted and we need some of the
636 // contents during later processing
639 AFSBackupEntry( pNameArray);
643 // OK, open the target directory
646 if( uniComponentName.Length == 0)
648 AFSRetrieveFinalComponent( &uniFileName,
652 ntStatus = AFSOpenTargetDirectory( Irp,
660 if( !NT_SUCCESS( ntStatus))
663 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
664 AFS_TRACE_LEVEL_ERROR,
665 "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
666 &pParentDirectoryCB->NameInformation.FileName,
670 try_return( ntStatus);
673 if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
676 if( pDirectoryCB == NULL ||
677 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
679 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
680 AFS_TRACE_LEVEL_VERBOSE,
681 "AFSCommonCreate (%p) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
685 pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0);
689 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
690 AFS_TRACE_LEVEL_VERBOSE,
691 "AFSCommonCreate (%p) Opening as reparse point %wZ Type %08lX\n",
694 pDirectoryCB->ObjectInformation->FileType);
696 bOpenedReparsePoint = TRUE;
701 // Based on the options passed in, process the file accordingly.
704 if( ulCreateDisposition == FILE_CREATE ||
705 ( ( ulCreateDisposition == FILE_OPEN_IF ||
706 ulCreateDisposition == FILE_OVERWRITE_IF) &&
707 pDirectoryCB == NULL))
710 if( uniComponentName.Length == 0 ||
711 pDirectoryCB != NULL)
715 // We traversed the entire path so we found each entry,
716 // fail with collision
719 if( pDirectoryCB != NULL)
722 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
723 AFS_TRACE_LEVEL_VERBOSE,
724 "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
725 &pDirectoryCB->NameInformation.FileName,
731 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
732 AFS_TRACE_LEVEL_VERBOSE,
733 "AFSCommonCreate Object name collision on create Status %08lX\n",
737 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
741 // OK, go and create the node
744 ntStatus = AFSProcessCreate( Irp,
754 if( !NT_SUCCESS( ntStatus))
757 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
758 AFS_TRACE_LEVEL_ERROR,
759 "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
761 &pParentDirectoryCB->NameInformation.FileName,
765 try_return( ntStatus);
769 // We should not have an extra component except for PIOCtl opens
772 if( uniComponentName.Length > 0)
776 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
779 if( RtlCompareUnicodeString( &AFSPIOCtlName,
785 // AFSOpenIOCtlFcb does not free a DirOpenReferenceCount for
786 // pParentDirectoryCB.
789 ntStatus = AFSOpenIOCtlFcb( Irp,
795 if( !NT_SUCCESS( ntStatus))
798 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
799 AFS_TRACE_LEVEL_ERROR,
800 "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
808 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
809 AFS_TRACE_LEVEL_VERBOSE,
810 "AFSCommonCreate (%p) File %wZ name not found\n",
814 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
817 try_return( ntStatus);
821 // For root opens the parent will be NULL
824 if( pParentDirectoryCB == NULL)
828 // Check for the delete on close flag for the root
831 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
834 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
835 AFS_TRACE_LEVEL_ERROR,
836 "AFSCommonCreate (%p) Attempt to open root as delete on close\n",
839 try_return( ntStatus = STATUS_CANNOT_DELETE);
843 // If this is the target directory, then bail
846 if( bOpenTargetDirectory)
849 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
850 AFS_TRACE_LEVEL_ERROR,
851 "AFSCommonCreate (%p) Attempt to open root as target directory\n",
854 try_return( ntStatus = STATUS_INVALID_PARAMETER);
858 // Go and open the root of the volume
861 ntStatus = AFSOpenRoot( Irp,
867 if( !NT_SUCCESS( ntStatus))
870 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
871 AFS_TRACE_LEVEL_ERROR,
872 "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
873 pVolumeCB->ObjectInformation.FileId.Cell,
874 pVolumeCB->ObjectInformation.FileId.Volume,
878 try_return( ntStatus);
882 // At this point if we have no pDirectoryCB it was not found.
885 if( pDirectoryCB == NULL)
888 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
889 AFS_TRACE_LEVEL_ERROR,
890 "AFSCommonCreate Failing access to %wZ Name not found\n",
893 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
896 if( ulCreateDisposition == FILE_OVERWRITE ||
897 ulCreateDisposition == FILE_SUPERSEDE ||
898 ulCreateDisposition == FILE_OVERWRITE_IF)
902 // Go process a file for overwrite or supersede.
905 ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
914 if( !NT_SUCCESS( ntStatus))
917 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
918 AFS_TRACE_LEVEL_ERROR,
919 "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
920 &pDirectoryCB->NameInformation.FileName,
924 try_return( ntStatus);
928 // Trying to open the file
931 ntStatus = AFSProcessOpen( Irp,
939 if( !NT_SUCCESS( ntStatus))
942 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
943 AFS_TRACE_LEVEL_ERROR,
944 "AFSCommonCreate Failed open on %wZ Status %08lX\n",
945 &pDirectoryCB->NameInformation.FileName,
951 if( NT_SUCCESS( ntStatus) &&
952 ntStatus != STATUS_REPARSE)
958 AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
961 RtlCopyMemory( &pCcb->AuthGroup,
966 // If we have a substitute name, then use it
969 if( uniSubstitutedPathName.Buffer != NULL)
972 pCcb->FullFileName = uniSubstitutedPathName;
974 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
976 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
981 pCcb->FullFileName = uniRootFileName;
983 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
986 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
988 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
992 if( bOpenedReparsePoint)
994 SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
997 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
998 AFS_TRACE_LEVEL_VERBOSE,
999 "AFSCommonCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1000 &pCcb->DirectoryCB->NameInformation.FileName,
1003 lCount = pCcb->DirectoryCB->DirOpenReferenceCount);
1005 ASSERT( lCount >= 0);
1007 pCcb->CurrentDirIndex = 0;
1009 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1012 SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1016 // Save off the name array for this instance
1019 pCcb->NameArray = pNameArray;
1023 AFSReleaseResource( &pCcb->NPCcb->CcbLock);
1027 // If we make it here then init the FO for the request.
1030 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1031 AFS_TRACE_LEVEL_VERBOSE_2,
1032 "AFSCommonCreate (%p) FileObject %p FsContext %p FsContext2 %p\n",
1038 pFileObject->FsContext = (void *)pFcb;
1040 pFileObject->FsContext2 = (void *)pCcb;
1045 ASSERT( pFcb->OpenHandleCount > 0);
1047 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1050 // For files perform additional processing
1053 switch( pFcb->Header.NodeTypeCode)
1060 pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1065 // If the user did not request nobuffering then mark the FO as cacheable
1068 if( bNoIntermediateBuffering)
1071 pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1076 pFileObject->Flags |= FO_CACHE_SUPPORTED;
1080 // If the file was opened for execution then we need to set the bit in the FO
1083 if( BooleanFlagOn( *pDesiredAccess,
1087 SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1091 // Update the last access time
1094 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1105 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1106 AFS_TRACE_LEVEL_ERROR,
1107 "AFSCommonCreate (%p) Returning with NULL Fcb FileObject %p FsContext %p FsContext2 %p\n",
1116 if( NT_SUCCESS( ntStatus) &&
1117 ntStatus == STATUS_REPARSE)
1120 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1121 AFS_TRACE_LEVEL_ERROR,
1122 "AFSCommonCreate (%p) STATUS_REPARSE FileObject %p FsContext %p FsContext2 %p\n",
1130 // Free up the sub name if we have one
1133 if( uniSubstitutedPathName.Buffer != NULL)
1136 AFSExFreePoolWithTag( uniSubstitutedPathName.Buffer, 0);
1138 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1143 // Free up the name array ...
1146 if( pNameArray != NULL)
1149 AFSFreeNameArray( pNameArray);
1152 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1155 AFSExFreePoolWithTag( uniRootFileName.Buffer, 0);
1161 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1163 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1164 AFS_TRACE_LEVEL_VERBOSE,
1165 "AFSCommonCreate Decrement count on Volume %08lX Cnt %d\n",
1174 // Release the reference from AFSLocateNameEntry
1177 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
1179 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1180 AFS_TRACE_LEVEL_VERBOSE,
1181 "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1182 &pDirectoryCB->NameInformation.FileName,
1187 ASSERT( lCount >= 0);
1190 if ( bReleaseParentDir)
1194 // Release the reference from AFSLocateNameEntry
1197 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
1199 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1200 AFS_TRACE_LEVEL_VERBOSE,
1201 "AFSCommonCreate Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
1202 &pParentDirectoryCB->NameInformation.FileName,
1207 ASSERT( lCount >= 0);
1211 // Setup the Irp for completion, the Information has been set previously
1214 Irp->IoStatus.Status = ntStatus;
1221 AFSOpenAFSRoot( IN PIRP Irp,
1226 NTSTATUS ntStatus = STATUS_SUCCESS;
1233 // Initialize the Ccb for the file.
1236 ntStatus = AFSInitCcb( Ccb,
1237 AFSGlobalRoot->DirectoryCB,
1241 if( !NT_SUCCESS( ntStatus))
1244 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1245 AFS_TRACE_LEVEL_ERROR,
1246 "AFSOpenAFSRoot (%p) Failed to allocate Ccb\n",
1249 try_return( ntStatus);
1253 // Increment the open count on this Fcb
1256 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1258 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1259 AFS_TRACE_LEVEL_VERBOSE,
1260 "AFSOpenAFSRoot Increment count on Fcb %p Cnt %d\n",
1261 AFSGlobalRoot->RootFcb,
1264 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1266 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1267 AFS_TRACE_LEVEL_VERBOSE,
1268 "AFSOpenAFSRoot Increment handle count on Fcb %p Cnt %d\n",
1269 AFSGlobalRoot->RootFcb,
1272 *Fcb = AFSGlobalRoot->RootFcb;
1275 // Return the open result for this file
1278 Irp->IoStatus.Information = FILE_OPENED;
1289 AFSOpenRoot( IN PIRP Irp,
1290 IN AFSVolumeCB *VolumeCB,
1292 OUT AFSFcb **RootFcb,
1296 NTSTATUS ntStatus = STATUS_SUCCESS;
1297 PFILE_OBJECT pFileObject = NULL;
1298 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1299 PACCESS_MASK pDesiredAccess = NULL;
1300 USHORT usShareAccess;
1302 BOOLEAN bAllocatedCcb = FALSE;
1303 BOOLEAN bReleaseFcb = FALSE;
1304 AFSFileOpenCB stOpenCB;
1305 AFSFileOpenResultCB stOpenResultCB;
1306 ULONG ulResultLen = 0;
1312 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1313 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1314 ulOptions = pIrpSp->Parameters.Create.Options;
1316 pFileObject = pIrpSp->FileObject;
1318 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1321 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1323 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1324 AFS_TRACE_LEVEL_ERROR,
1325 "AFSOpenRoot (%p) Attempt to open root as file Status %08lX\n",
1329 try_return( ntStatus);
1333 // Check if we should go and retrieve updated information for the node
1336 ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1341 if( !NT_SUCCESS( ntStatus))
1344 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1345 AFS_TRACE_LEVEL_ERROR,
1346 "AFSOpenRoot (%p) Failed to validate root entry Status %08lX\n",
1350 try_return( ntStatus);
1354 // Check with the service that we can open the file
1357 RtlZeroMemory( &stOpenCB,
1358 sizeof( AFSFileOpenCB));
1360 stOpenCB.DesiredAccess = *pDesiredAccess;
1362 stOpenCB.ShareAccess = usShareAccess;
1364 stOpenResultCB.GrantedAccess = 0;
1366 ulResultLen = sizeof( AFSFileOpenResultCB);
1368 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1369 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1372 &VolumeCB->ObjectInformation.FileId,
1374 sizeof( AFSFileOpenCB),
1375 (void *)&stOpenResultCB,
1378 if( !NT_SUCCESS( ntStatus))
1381 UNICODE_STRING uniGUID;
1384 uniGUID.MaximumLength = 0;
1385 uniGUID.Buffer = NULL;
1387 if( AuthGroup != NULL)
1389 RtlStringFromGUID( *AuthGroup,
1393 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1394 AFS_TRACE_LEVEL_ERROR,
1395 "AFSOpenRoot (%p) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1397 VolumeCB->ObjectInformation.FileId.Cell,
1398 VolumeCB->ObjectInformation.FileId.Volume,
1402 if( AuthGroup != NULL)
1404 RtlFreeUnicodeString( &uniGUID);
1407 try_return( ntStatus);
1411 // If the entry is not initialized then do it now
1414 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1417 AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1420 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1423 ntStatus = AFSEnumerateDirectory( AuthGroup,
1424 &VolumeCB->ObjectInformation,
1427 if( !NT_SUCCESS( ntStatus))
1430 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1432 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1433 AFS_TRACE_LEVEL_ERROR,
1434 "AFSOpenRoot (%p) Failed to enumerate directory Status %08lX\n",
1438 try_return( ntStatus);
1441 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1444 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1448 // If the root fcb has been initialized then check access otherwise
1449 // init the volume fcb
1452 if( VolumeCB->RootFcb == NULL)
1455 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1458 if( !NT_SUCCESS( ntStatus))
1461 try_return( ntStatus);
1467 AFSAcquireExcl( VolumeCB->RootFcb->Header.Resource,
1471 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1473 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1474 AFS_TRACE_LEVEL_VERBOSE,
1475 "AFSOpenRoot Increment count on Fcb %p Cnt %d\n",
1482 // If there are current opens on the Fcb, check the access.
1485 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1488 ntStatus = IoCheckShareAccess( *pDesiredAccess,
1491 &VolumeCB->RootFcb->ShareAccess,
1494 if( !NT_SUCCESS( ntStatus))
1497 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1498 AFS_TRACE_LEVEL_ERROR,
1499 "AFSOpenRoot (%p) Access check failure Status %08lX\n",
1503 try_return( ntStatus);
1508 // Initialize the Ccb for the file.
1511 ntStatus = AFSInitCcb( Ccb,
1512 VolumeCB->DirectoryCB,
1516 if( !NT_SUCCESS( ntStatus))
1519 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1520 AFS_TRACE_LEVEL_ERROR,
1521 "AFSOpenRoot (%p) Failed to allocate Ccb Status %08lX\n",
1525 try_return( ntStatus);
1528 bAllocatedCcb = TRUE;
1531 // OK, update the share access on the fileobject
1534 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1537 IoUpdateShareAccess( pFileObject,
1538 &VolumeCB->RootFcb->ShareAccess);
1547 IoSetShareAccess( *pDesiredAccess,
1550 &VolumeCB->RootFcb->ShareAccess);
1554 // Increment the open count on this Fcb
1557 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1559 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1560 AFS_TRACE_LEVEL_VERBOSE,
1561 "AFSOpenRoot Increment handle count on Fcb %p Cnt %d\n",
1566 // Indicate the object is held
1569 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1572 // Return the open result for this file
1575 Irp->IoStatus.Information = FILE_OPENED;
1577 *RootFcb = VolumeCB->RootFcb;
1583 if ( !NT_SUCCESS( ntStatus))
1586 lCount = InterlockedDecrement( &VolumeCB->RootFcb->OpenReferenceCount);
1588 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1589 AFS_TRACE_LEVEL_VERBOSE,
1590 "AFSOpenRoot Decrement count on Fcb %p Cnt %d\n",
1595 AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1598 if( !NT_SUCCESS( ntStatus))
1610 Irp->IoStatus.Information = 0;
1618 AFSProcessCreate( IN PIRP Irp,
1620 IN AFSVolumeCB *VolumeCB,
1621 IN AFSDirectoryCB *ParentDirCB,
1622 IN PUNICODE_STRING FileName,
1623 IN PUNICODE_STRING ComponentName,
1624 IN PUNICODE_STRING FullFileName,
1629 NTSTATUS ntStatus = STATUS_SUCCESS;
1630 PFILE_OBJECT pFileObject = NULL;
1631 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1632 ULONG ulOptions = 0;
1633 ULONG ulAttributes = 0;
1634 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1635 PACCESS_MASK pDesiredAccess = NULL;
1636 USHORT usShareAccess;
1637 AFSDirectoryCB *pDirEntry = NULL;
1638 AFSObjectInfoCB *pParentObjectInfo = NULL;
1639 AFSObjectInfoCB *pObjectInfo = NULL;
1645 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1646 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1648 pFileObject = pIrpSp->FileObject;
1651 // Extract out the options
1654 ulOptions = pIrpSp->Parameters.Create.Options;
1657 // We pass all attributes they want to apply to the file to the create
1660 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1663 // If this is a directory create then set the attribute correctly
1666 if( ulOptions & FILE_DIRECTORY_FILE)
1669 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1672 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1673 AFS_TRACE_LEVEL_VERBOSE,
1674 "AFSProcessCreate (%p) Creating file %wZ Attributes %08lX\n",
1679 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1682 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1683 AFS_TRACE_LEVEL_ERROR,
1684 "AFSProcessCreate Request failed due to read only volume %wZ\n",
1687 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
1690 pParentObjectInfo = ParentDirCB->ObjectInformation;
1693 // Allocate and insert the direntry into the parent node
1696 ntStatus = AFSCreateDirEntry( AuthGroup,
1704 if( !NT_SUCCESS( ntStatus))
1707 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1708 AFS_TRACE_LEVEL_ERROR,
1709 "AFSProcessCreate (%p) Failed to create directory entry %wZ Status %08lX\n",
1714 try_return( ntStatus);
1717 bFileCreated = TRUE;
1719 pObjectInfo = pDirEntry->ObjectInformation;
1721 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1722 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1725 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1726 AFS_TRACE_LEVEL_VERBOSE,
1727 "AFSProcessCreate (%p) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1729 &pDirEntry->NameInformation.FileName,
1730 pObjectInfo->FileId.Cell,
1731 pObjectInfo->FileId.Volume,
1732 pObjectInfo->FileId.Vnode,
1733 pObjectInfo->FileId.Unique);
1735 ntStatus = AFSEvaluateNode( AuthGroup,
1738 if( !NT_SUCCESS( ntStatus))
1741 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
1744 if ( pParentObjectInfo == pObjectInfo->ParentObjectInformation)
1747 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1748 AFS_TRACE_LEVEL_ERROR,
1749 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1751 &pDirEntry->NameInformation.FileName,
1752 pObjectInfo->FileId.Cell,
1753 pObjectInfo->FileId.Volume,
1754 pObjectInfo->FileId.Vnode,
1755 pObjectInfo->FileId.Unique,
1756 pParentObjectInfo->FileId.Cell,
1757 pParentObjectInfo->FileId.Volume,
1758 pParentObjectInfo->FileId.Vnode,
1759 pParentObjectInfo->FileId.Unique,
1762 else if ( pObjectInfo->ParentObjectInformation == NULL)
1765 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1766 AFS_TRACE_LEVEL_ERROR,
1767 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
1769 &pDirEntry->NameInformation.FileName,
1770 pObjectInfo->FileId.Cell,
1771 pObjectInfo->FileId.Volume,
1772 pObjectInfo->FileId.Vnode,
1773 pObjectInfo->FileId.Unique,
1774 pParentObjectInfo->FileId.Cell,
1775 pParentObjectInfo->FileId.Volume,
1776 pParentObjectInfo->FileId.Vnode,
1777 pParentObjectInfo->FileId.Unique,
1783 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1784 AFS_TRACE_LEVEL_ERROR,
1785 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1787 &pDirEntry->NameInformation.FileName,
1788 pObjectInfo->FileId.Cell,
1789 pObjectInfo->FileId.Volume,
1790 pObjectInfo->FileId.Vnode,
1791 pObjectInfo->FileId.Unique,
1792 pParentObjectInfo->FileId.Cell,
1793 pParentObjectInfo->FileId.Volume,
1794 pParentObjectInfo->FileId.Vnode,
1795 pParentObjectInfo->FileId.Unique,
1796 pObjectInfo->ParentObjectInformation->FileId.Cell,
1797 pObjectInfo->ParentObjectInformation->FileId.Volume,
1798 pObjectInfo->ParentObjectInformation->FileId.Vnode,
1799 pObjectInfo->ParentObjectInformation->FileId.Unique,
1806 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1807 AFS_TRACE_LEVEL_ERROR,
1808 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1810 &pDirEntry->NameInformation.FileName,
1811 pObjectInfo->FileId.Cell,
1812 pObjectInfo->FileId.Volume,
1813 pObjectInfo->FileId.Vnode,
1814 pObjectInfo->FileId.Unique,
1818 try_return( ntStatus);
1821 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1825 // We may have raced and the Fcb is already created
1829 // Allocate and initialize the Fcb for the file.
1832 ntStatus = AFSInitFcb( pDirEntry);
1834 *Fcb = pObjectInfo->Fcb;
1836 if( !NT_SUCCESS( ntStatus))
1839 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1840 AFS_TRACE_LEVEL_ERROR,
1841 "AFSProcessCreate (%p) Failed to initialize fcb %wZ Status %08lX\n",
1846 try_return( ntStatus);
1849 ntStatus = STATUS_SUCCESS;
1852 // Increment the open count on this Fcb
1855 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1857 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1858 AFS_TRACE_LEVEL_VERBOSE,
1859 "AFSProcessCreate Increment count on Fcb %p Cnt %d\n",
1866 // Initialize the Ccb for the file.
1869 ntStatus = AFSInitCcb( Ccb,
1874 if( !NT_SUCCESS( ntStatus))
1877 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1878 AFS_TRACE_LEVEL_ERROR,
1879 "AFSProcessCreate (%p) Failed to initialize ccb %wZ Status %08lX\n",
1884 try_return( ntStatus);
1887 bAllocatedCcb = TRUE;
1890 // If this is a file, update the headers filesizes.
1893 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1897 // Update the sizes with the information passed in
1900 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
1901 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1902 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1905 // Notify the system of the addition
1908 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1910 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1911 (ULONG)FILE_ACTION_ADDED);
1913 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
1915 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1919 // This is a new directory node so indicate it has been enumerated
1922 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1925 // And the parent directory entry
1928 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1931 // Notify the system of the addition
1934 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1936 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1937 (ULONG)FILE_ACTION_ADDED);
1939 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
1940 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
1941 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
1942 (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
1946 // And the parent directory entry
1949 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1952 // Notify the system of the addition
1955 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1957 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1958 (ULONG)FILE_ACTION_ADDED);
1962 // Save off the access for the open
1965 IoSetShareAccess( *pDesiredAccess,
1968 &(*Fcb)->ShareAccess);
1970 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
1972 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1973 AFS_TRACE_LEVEL_VERBOSE,
1974 "AFSProcessCreate Increment handle count on Fcb %p Cnt %d\n",
1979 // Increment the open reference and handle on the parent node
1982 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
1984 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
1985 AFS_TRACE_LEVEL_VERBOSE,
1986 "AFSProcessCreate Increment child open handle count on Parent object %p Cnt %d\n",
1987 pObjectInfo->ParentObjectInformation,
1990 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
1992 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1993 AFS_TRACE_LEVEL_VERBOSE,
1994 "AFSProcessCreate Increment child open ref count on Parent object %p Cnt %d\n",
1995 pObjectInfo->ParentObjectInformation,
1998 if( ulOptions & FILE_DELETE_ON_CLOSE)
2002 // Mark it for delete on close
2005 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2006 AFS_TRACE_LEVEL_VERBOSE,
2007 "AFSProcessCreate (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2012 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2016 // Indicate the object is locked in the service
2019 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2022 // Return the open result for this file
2025 Irp->IoStatus.Information = FILE_CREATED;
2030 // If we created the Fcb we need to release the resources
2036 if( !NT_SUCCESS( ntStatus))
2039 // Decrement the open count on this Fcb
2042 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2044 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2045 AFS_TRACE_LEVEL_VERBOSE,
2046 "AFSProcessCreate Decrement count on Fcb %p Cnt %d\n",
2051 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2058 // Decrement the reference added during initialization of the DE
2059 // AFSInitCcb allocates its own reference count.
2062 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2064 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2065 AFS_TRACE_LEVEL_VERBOSE,
2066 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2067 &pDirEntry->NameInformation.FileName,
2071 ASSERT( lCount >= 0);
2074 if( !NT_SUCCESS( ntStatus))
2080 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2081 AFS_TRACE_LEVEL_VERBOSE,
2082 "AFSProcessCreate Create failed, removing DE %p from parent object %p Status %08lX\n",
2088 // Remove the dir entry from the parent
2091 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2094 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2096 AFSNotifyDelete( pDirEntry,
2101 // Pull the directory entry from the parent
2104 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2106 FALSE); // Leave it in the enum list so the worker cleans it up
2109 // Tag the parent as needing verification
2112 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2114 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2116 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2127 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2140 AFSOpenTargetDirectory( IN PIRP Irp,
2141 IN AFSVolumeCB *VolumeCB,
2142 IN AFSDirectoryCB *ParentDirectoryCB,
2143 IN AFSDirectoryCB *TargetDirectoryCB,
2144 IN UNICODE_STRING *TargetName,
2148 UNREFERENCED_PARAMETER(VolumeCB);
2149 NTSTATUS ntStatus = STATUS_SUCCESS;
2150 PFILE_OBJECT pFileObject = NULL;
2151 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2152 PACCESS_MASK pDesiredAccess = NULL;
2153 USHORT usShareAccess;
2154 BOOLEAN bAllocatedCcb = FALSE;
2155 BOOLEAN bReleaseFcb = FALSE;
2156 AFSObjectInfoCB *pParentObject = NULL;
2157 UNICODE_STRING uniTargetName;
2163 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2164 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2166 pFileObject = pIrpSp->FileObject;
2168 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2169 AFS_TRACE_LEVEL_VERBOSE,
2170 "AFSOpenTargetDirectory (%p) Processing file %wZ\n",
2174 pParentObject = ParentDirectoryCB->ObjectInformation;
2176 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2179 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2183 // Make sure we have an Fcb for the access
2186 // Allocate and initialize the Fcb for the file.
2189 ntStatus = AFSInitFcb( ParentDirectoryCB);
2191 *Fcb = pParentObject->Fcb;
2193 if( !NT_SUCCESS( ntStatus))
2196 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2197 AFS_TRACE_LEVEL_ERROR,
2198 "AFSOpenTargetDirectory (%p) Failed to initialize fcb %wZ Status %08lX\n",
2200 &ParentDirectoryCB->NameInformation.FileName,
2203 try_return( ntStatus);
2206 ntStatus = STATUS_SUCCESS;
2209 // Increment the open count on this Fcb
2212 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2214 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2215 AFS_TRACE_LEVEL_VERBOSE,
2216 "AFSOpenTargetDirectory Increment count on Fcb %p Cnt %d\n",
2223 // If there are current opens on the Fcb, check the access.
2226 if( pParentObject->Fcb->OpenHandleCount > 0)
2229 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2232 &pParentObject->Fcb->ShareAccess,
2235 if( !NT_SUCCESS( ntStatus))
2238 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2239 AFS_TRACE_LEVEL_ERROR,
2240 "AFSOpenTargetDirectory (%p) Access check failure %wZ Status %08lX\n",
2242 &ParentDirectoryCB->NameInformation.FileName,
2245 try_return( ntStatus);
2250 // Initialize the Ccb for the file.
2253 ntStatus = AFSInitCcb( Ccb,
2258 if( !NT_SUCCESS( ntStatus))
2261 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2262 AFS_TRACE_LEVEL_ERROR,
2263 "AFSOpenTargetDirectory (%p) Failed to initialize ccb %wZ Status %08lX\n",
2265 &ParentDirectoryCB->NameInformation.FileName,
2268 try_return( ntStatus);
2271 bAllocatedCcb = TRUE;
2273 if( TargetDirectoryCB != NULL &&
2274 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2280 Irp->IoStatus.Information = FILE_EXISTS;
2282 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2287 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2289 uniTargetName = *TargetName;
2293 // Update the filename in the fileobject for rename processing
2296 RtlCopyMemory( pFileObject->FileName.Buffer,
2297 uniTargetName.Buffer,
2298 uniTargetName.Length);
2300 pFileObject->FileName.Length = uniTargetName.Length;
2303 // OK, update the share access on the fileobject
2306 if( pParentObject->Fcb->OpenHandleCount > 0)
2309 IoUpdateShareAccess( pFileObject,
2310 &pParentObject->Fcb->ShareAccess);
2319 IoSetShareAccess( *pDesiredAccess,
2322 &pParentObject->Fcb->ShareAccess);
2325 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2327 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2328 AFS_TRACE_LEVEL_VERBOSE,
2329 "AFSOpenTargetDirectory Increment handle count on Fcb %p Cnt %d\n",
2334 // Increment the open reference and handle on the parent node
2337 if( pParentObject->ParentObjectInformation != NULL)
2340 lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2342 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2343 AFS_TRACE_LEVEL_VERBOSE,
2344 "AFSOpenTargetDirectory Increment child open handle count on Parent object %p Cnt %d\n",
2345 pParentObject->ParentObjectInformation,
2348 lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2350 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2351 AFS_TRACE_LEVEL_VERBOSE,
2352 "AFSOpenTargetDirectory Increment child open ref count on Parent object %p Cnt %d\n",
2353 pParentObject->ParentObjectInformation,
2362 if( !NT_SUCCESS( ntStatus))
2365 // Decrement the open count on this Fcb
2368 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2370 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2371 AFS_TRACE_LEVEL_VERBOSE,
2372 "AFSOpenTargetDirectory Decrement count on Fcb %p Cnt %d\n",
2377 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2380 if( !NT_SUCCESS( ntStatus))
2393 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2404 AFSProcessOpen( IN PIRP Irp,
2406 IN AFSVolumeCB *VolumeCB,
2407 IN AFSDirectoryCB *ParentDirCB,
2408 IN AFSDirectoryCB *DirectoryCB,
2412 UNREFERENCED_PARAMETER(VolumeCB);
2413 NTSTATUS ntStatus = STATUS_SUCCESS;
2414 PFILE_OBJECT pFileObject = NULL;
2415 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2416 PACCESS_MASK pDesiredAccess = NULL;
2417 USHORT usShareAccess;
2418 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE;
2419 ULONG ulOptions = 0;
2420 AFSFileOpenCB stOpenCB;
2421 AFSFileOpenResultCB stOpenResultCB;
2422 ULONG ulResultLen = 0;
2423 AFSObjectInfoCB *pParentObjectInfo = NULL;
2424 AFSObjectInfoCB *pObjectInfo = NULL;
2425 ULONG ulFileAccess = 0;
2426 AFSFileAccessReleaseCB stReleaseFileAccess;
2432 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2433 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2435 pFileObject = pIrpSp->FileObject;
2437 pParentObjectInfo = ParentDirCB->ObjectInformation;
2439 pObjectInfo = DirectoryCB->ObjectInformation;
2442 // Check if the entry is pending a deletion
2445 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2448 ntStatus = STATUS_DELETE_PENDING;
2450 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2451 AFS_TRACE_LEVEL_ERROR,
2452 "AFSProcessOpen (%p) Entry pending delete %wZ Status %08lX\n",
2454 &DirectoryCB->NameInformation.FileName,
2457 try_return( ntStatus);
2461 // Extract out the options
2464 ulOptions = pIrpSp->Parameters.Create.Options;
2467 // Check if we should go and retrieve updated information for the node
2470 ntStatus = AFSValidateEntry( DirectoryCB,
2475 if( !NT_SUCCESS( ntStatus))
2478 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2479 AFS_TRACE_LEVEL_ERROR,
2480 "AFSProcessOpen (%p) Failed to validate entry %wZ Status %08lX\n",
2482 &DirectoryCB->NameInformation.FileName,
2485 try_return( ntStatus);
2489 // If this is marked for delete on close then be sure we can delete the entry
2492 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2495 ntStatus = AFSNotifyDelete( DirectoryCB,
2499 if( !NT_SUCCESS( ntStatus))
2502 ntStatus = STATUS_CANNOT_DELETE;
2504 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2505 AFS_TRACE_LEVEL_ERROR,
2506 "AFSProcessOpen (%p) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2508 &DirectoryCB->NameInformation.FileName,
2511 try_return( ntStatus);
2516 // Be sure we have an Fcb for the current object
2519 ntStatus = AFSInitFcb( DirectoryCB);
2521 if( !NT_SUCCESS( ntStatus))
2524 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2525 AFS_TRACE_LEVEL_ERROR,
2526 "AFSProcessOpen (%p) Failed to init fcb on %wZ Status %08lX\n",
2528 &DirectoryCB->NameInformation.FileName,
2531 try_return( ntStatus);
2534 ntStatus = STATUS_SUCCESS;
2537 // AFSInitFcb returns the Fcb resource held
2543 // Increment the open count on this Fcb
2546 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2548 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2549 AFS_TRACE_LEVEL_VERBOSE,
2550 "AFSProcessOpen Increment2 count on Fcb %p Cnt %d\n",
2555 // Check access on the entry
2558 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2561 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2564 &pObjectInfo->Fcb->ShareAccess,
2567 if( !NT_SUCCESS( ntStatus))
2570 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2571 AFS_TRACE_LEVEL_ERROR,
2572 "AFSProcessOpen (%p) Failed to check share access on %wZ Status %08lX\n",
2574 &DirectoryCB->NameInformation.FileName,
2577 try_return( ntStatus);
2582 // Additional checks
2585 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2589 // If the caller is asking for write access then try to flush the image section
2592 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2593 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2598 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2599 AFS_TRACE_LEVEL_VERBOSE,
2600 "AFSProcessOpen Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2601 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2602 PsGetCurrentThread());
2604 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2607 bMmFlushed = MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2610 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2611 AFS_TRACE_LEVEL_VERBOSE,
2612 "AFSProcessOpen Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2613 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2614 PsGetCurrentThread());
2616 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
2621 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2622 STATUS_SHARING_VIOLATION;
2624 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2625 AFS_TRACE_LEVEL_ERROR,
2626 "AFSProcessOpen (%p) Failed to flush image section %wZ Status %08lX\n",
2628 &DirectoryCB->NameInformation.FileName,
2631 try_return( ntStatus);
2635 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2638 ntStatus = STATUS_NOT_A_DIRECTORY;
2640 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2641 AFS_TRACE_LEVEL_ERROR,
2642 "AFSProcessOpen (%p) Attempt to open file as directory %wZ Status %08lX\n",
2644 &DirectoryCB->NameInformation.FileName,
2647 try_return( ntStatus);
2650 pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2652 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2653 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2656 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2659 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2661 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2662 AFS_TRACE_LEVEL_ERROR,
2663 "AFSProcessOpen (%p) Attempt to open directory as file %wZ Status %08lX\n",
2665 &DirectoryCB->NameInformation.FileName,
2668 try_return( ntStatus);
2671 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2672 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2673 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2674 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2681 try_return( ntStatus = STATUS_UNSUCCESSFUL);
2685 // Check with the service that we can open the file
2688 stOpenCB.ParentId = pParentObjectInfo->FileId;
2690 stOpenCB.DesiredAccess = *pDesiredAccess;
2692 stOpenCB.ShareAccess = usShareAccess;
2694 stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2696 stOpenCB.Identifier = (ULONGLONG)pFileObject;
2698 stOpenResultCB.GrantedAccess = 0;
2700 ulResultLen = sizeof( AFSFileOpenResultCB);
2702 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2703 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2705 &DirectoryCB->NameInformation.FileName,
2706 &pObjectInfo->FileId,
2708 sizeof( AFSFileOpenCB),
2709 (void *)&stOpenResultCB,
2712 if( !NT_SUCCESS( ntStatus))
2715 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2716 AFS_TRACE_LEVEL_ERROR,
2717 "AFSProcessOpen (%p) Failed open in service %wZ Status %08lX\n",
2719 &DirectoryCB->NameInformation.FileName,
2722 try_return( ntStatus);
2726 // Save the granted access in case we need to release it below
2729 ulFileAccess = stOpenResultCB.FileAccess;
2732 // Check if there is a conflict
2735 if( !AFSCheckAccess( *pDesiredAccess,
2736 stOpenResultCB.GrantedAccess,
2737 BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2740 ntStatus = STATUS_ACCESS_DENIED;
2742 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2743 AFS_TRACE_LEVEL_ERROR,
2744 "AFSProcessOpen (%p) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2747 stOpenResultCB.GrantedAccess,
2748 &DirectoryCB->NameInformation.FileName,
2751 try_return( ntStatus);
2755 // Initialize the Ccb for the file.
2758 ntStatus = AFSInitCcb( Ccb,
2763 if( !NT_SUCCESS( ntStatus))
2766 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2767 AFS_TRACE_LEVEL_ERROR,
2768 "AFSProcessOpen (%p) Failed to initialize ccb %wZ Status %08lX\n",
2770 &DirectoryCB->NameInformation.FileName,
2773 try_return( ntStatus);
2776 bAllocatedCcb = TRUE;
2779 // Perform the access check on the target if this is a mount point or symlink
2782 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2785 IoUpdateShareAccess( pFileObject,
2786 &pObjectInfo->Fcb->ShareAccess);
2795 IoSetShareAccess( *pDesiredAccess,
2798 &pObjectInfo->Fcb->ShareAccess);
2801 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2803 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2804 AFS_TRACE_LEVEL_VERBOSE,
2805 "AFSProcessOpen Increment handle count on Fcb %p Cnt %d\n",
2810 // Increment the open reference and handle on the parent node
2813 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2815 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2816 AFS_TRACE_LEVEL_VERBOSE,
2817 "AFSProcessOpen Increment child open handle count on Parent object %p Cnt %d\n",
2818 pObjectInfo->ParentObjectInformation,
2821 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2823 AFSDbgLogMsg( AFS_SUBSYSTEM_OBJECT_REF_COUNTING,
2824 AFS_TRACE_LEVEL_VERBOSE,
2825 "AFSProcessOpen Increment child open ref count on Parent object %p Cnt %d\n",
2826 pObjectInfo->ParentObjectInformation,
2829 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2833 // Mark it for delete on close
2836 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2837 AFS_TRACE_LEVEL_VERBOSE,
2838 "AFSProcessOpen (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2841 &DirectoryCB->NameInformation.FileName);
2843 SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2847 // Indicate the object is held
2850 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2853 // Return the open result for this file
2856 Irp->IoStatus.Information = FILE_OPENED;
2858 *Fcb = pObjectInfo->Fcb;
2865 if( !NT_SUCCESS( ntStatus))
2868 // Decrement the open count on this Fcb
2871 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2873 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2874 AFS_TRACE_LEVEL_VERBOSE,
2875 "AFSProcessOpen Decrement2 count on Fcb %p Cnt %d\n",
2880 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2883 if( !NT_SUCCESS( ntStatus))
2886 if ( ulFileAccess > 0)
2889 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2891 stReleaseFileAccess.FileAccess = ulFileAccess;
2893 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2895 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2896 AFS_REQUEST_FLAG_SYNCHRONOUS,
2898 &DirectoryCB->NameInformation.FileName,
2899 &pObjectInfo->FileId,
2900 (void *)&stReleaseFileAccess,
2901 sizeof( AFSFileAccessReleaseCB),
2916 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2927 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
2929 IN AFSVolumeCB *VolumeCB,
2931 IN AFSDirectoryCB *ParentDirCB,
2932 IN AFSDirectoryCB *DirectoryCB,
2936 UNREFERENCED_PARAMETER(DeviceObject);
2937 NTSTATUS ntStatus = STATUS_SUCCESS;
2938 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2939 PFILE_OBJECT pFileObject = NULL;
2940 LARGE_INTEGER liZero = {0,0};
2941 BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
2942 ULONG ulAttributes = 0;
2943 ULONG ulCreateDisposition = 0;
2944 BOOLEAN bAllocatedCcb = FALSE;
2945 BOOLEAN bUserMapped = FALSE;
2946 PACCESS_MASK pDesiredAccess = NULL;
2947 USHORT usShareAccess;
2948 AFSObjectInfoCB *pParentObjectInfo = NULL;
2949 AFSObjectInfoCB *pObjectInfo = NULL;
2951 LARGE_INTEGER liSaveSize;
2952 LARGE_INTEGER liSaveVDL;
2953 LARGE_INTEGER liSaveAlloc;
2958 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2960 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2962 pFileObject = pIrpSp->FileObject;
2964 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
2966 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
2968 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
2971 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2972 AFS_TRACE_LEVEL_ERROR,
2973 "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
2975 &DirectoryCB->NameInformation.FileName);
2977 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
2980 pParentObjectInfo = ParentDirCB->ObjectInformation;
2982 pObjectInfo = DirectoryCB->ObjectInformation;
2985 // Check if we should go and retrieve updated information for the node
2988 ntStatus = AFSValidateEntry( DirectoryCB,
2993 if( !NT_SUCCESS( ntStatus))
2996 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2997 AFS_TRACE_LEVEL_ERROR,
2998 "AFSProcessOverwriteSupersede (%p) Failed to validate entry %wZ Status %08lX\n",
3000 &DirectoryCB->NameInformation.FileName,
3003 try_return( ntStatus);
3007 // Be sure we have an Fcb for the object block
3010 ntStatus = AFSInitFcb( DirectoryCB);
3012 *Fcb = pObjectInfo->Fcb;
3014 if( !NT_SUCCESS( ntStatus))
3017 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3018 AFS_TRACE_LEVEL_ERROR,
3019 "AFSProcessOverwriteSupersede (%p) Failed to initialize fcb %wZ Status %08lX\n",
3021 &DirectoryCB->NameInformation.FileName,
3024 try_return( ntStatus);
3027 ntStatus = STATUS_SUCCESS;
3030 // Increment the open count on this Fcb.
3033 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3035 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3036 AFS_TRACE_LEVEL_VERBOSE,
3037 "AFSProcessOverwriteSupersede Increment2 count on Fcb %p Cnt %d\n",
3044 // Check access on the entry
3047 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3050 ntStatus = IoCheckShareAccess( *pDesiredAccess,
3053 &pObjectInfo->Fcb->ShareAccess,
3056 if( !NT_SUCCESS( ntStatus))
3059 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3060 AFS_TRACE_LEVEL_ERROR,
3061 "AFSProcessOverwriteSupersede (%p) Access check failure %wZ Status %08lX\n",
3063 &DirectoryCB->NameInformation.FileName,
3066 try_return( ntStatus);
3070 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3071 AFS_TRACE_LEVEL_VERBOSE,
3072 "AFSProcessOverwriteSupercede Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
3073 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3074 PsGetCurrentThread());
3076 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3080 // Before we actually truncate, check to see if the purge
3081 // is going to fail.
3084 bUserMapped = !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3087 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3088 AFS_TRACE_LEVEL_VERBOSE,
3089 "AFSProcessOverwriteSupercede Releasing Fcb SectionObject lock %p EXCL %08lX\n",
3090 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3091 PsGetCurrentThread());
3093 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3098 ntStatus = STATUS_USER_MAPPED_FILE;
3100 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3101 AFS_TRACE_LEVEL_ERROR,
3102 "AFSProcessOverwriteSupersede (%p) File user mapped %wZ Status %08lX\n",
3104 &DirectoryCB->NameInformation.FileName,
3107 try_return( ntStatus);
3111 // Initialize the Ccb for the file.
3114 ntStatus = AFSInitCcb( Ccb,
3119 if( !NT_SUCCESS( ntStatus))
3122 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3123 AFS_TRACE_LEVEL_ERROR,
3124 "AFSProcessOverwriteSupersede (%p) Failed to initialize ccb %wZ Status %08lX\n",
3126 &DirectoryCB->NameInformation.FileName,
3129 try_return( ntStatus);
3132 bAllocatedCcb = TRUE;
3135 // Set the file length to zero
3138 AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3141 bReleasePaging = TRUE;
3143 liSaveSize = pObjectInfo->Fcb->Header.FileSize;
3144 liSaveAlloc = pObjectInfo->Fcb->Header.AllocationSize;
3145 liSaveVDL = pObjectInfo->Fcb->Header.ValidDataLength;
3147 pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3148 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3149 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3151 pObjectInfo->EndOfFile.QuadPart = 0;
3152 pObjectInfo->AllocationSize.QuadPart = 0;