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,
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 (%08lX) 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 (%08lX) Invalid request to open before library is initialized\n",
92 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
95 ntStatus = AFSCommonCreate( AFSRDRDeviceObject,
102 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
107 "EXCEPTION - AFSCreate\n");
109 ntStatus = STATUS_ACCESS_DENIED;
113 // Complete the request
116 AFSCompleteRequest( Irp,
123 AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
127 NTSTATUS ntStatus = STATUS_SUCCESS;
128 UNICODE_STRING uniFileName;
129 ULONG ulCreateDisposition = 0;
131 BOOLEAN bNoIntermediateBuffering = FALSE;
132 FILE_OBJECT *pFileObject = NULL;
133 IO_STACK_LOCATION *pIrpSp;
136 AFSDeviceExt *pDeviceExt = NULL;
137 BOOLEAN bOpenTargetDirectory = FALSE, bReleaseVolume = FALSE;
138 PACCESS_MASK pDesiredAccess = NULL;
139 UNICODE_STRING uniComponentName, uniPathName, uniRootFileName, uniParsedFileName;
140 UNICODE_STRING uniSubstitutedPathName;
141 UNICODE_STRING uniRelativeName;
142 AFSNameArrayHdr *pNameArray = NULL;
143 AFSVolumeCB *pVolumeCB = NULL;
144 AFSDirectoryCB *pParentDirectoryCB = NULL, *pDirectoryCB = NULL;
145 ULONG ulParseFlags = 0;
147 ULONG ulNameProcessingFlags = 0;
148 BOOLEAN bOpenedReparsePoint = FALSE;
153 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
154 pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
155 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
156 ulOptions = pIrpSp->Parameters.Create.Options;
157 bNoIntermediateBuffering = BooleanFlagOn( ulOptions, FILE_NO_INTERMEDIATE_BUFFERING);
158 bOpenTargetDirectory = BooleanFlagOn( pIrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
159 pFileObject = pIrpSp->FileObject;
160 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
162 uniFileName.Length = uniFileName.MaximumLength = 0;
163 uniFileName.Buffer = NULL;
165 uniRootFileName.Length = uniRootFileName.MaximumLength = 0;
166 uniRootFileName.Buffer = NULL;
168 uniParsedFileName.Length = uniParsedFileName.MaximumLength = 0;
169 uniParsedFileName.Buffer = NULL;
171 uniSubstitutedPathName.Buffer = NULL;
172 uniSubstitutedPathName.Length = 0;
174 uniRelativeName.Buffer = NULL;
175 uniRelativeName.Length = 0;
177 if( AFSGlobalRoot == NULL)
179 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
182 RtlZeroMemory( &stAuthGroup,
185 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
186 (ULONGLONG)PsGetCurrentThreadId(),
189 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
192 ntStatus = AFSEnumerateGlobalRoot( &stAuthGroup);
194 if( !NT_SUCCESS( ntStatus))
197 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
198 AFS_TRACE_LEVEL_ERROR,
199 "AFSCommonCreate Failed to enumerate global root Status %08lX\n",
202 try_return( ntStatus);
207 // If we are in shutdown mode then fail the request
210 if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
213 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
214 AFS_TRACE_LEVEL_WARNING,
215 "AFSCommonCreate (%08lX) Open request after shutdown\n",
218 try_return( ntStatus = STATUS_TOO_LATE);
222 // Go and parse the name for processing.
223 // If ulParseFlags is returned with AFS_PARSE_FLAG_FREE_FILE_BUFFER set,
224 // then we are responsible for releasing the uniRootFileName.Buffer.
227 ntStatus = AFSParseName( Irp,
237 if( !NT_SUCCESS( ntStatus))
240 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
241 uniFileName.Length > 0 ? AFS_TRACE_LEVEL_ERROR : AFS_TRACE_LEVEL_VERBOSE,
242 "AFSCommonCreate (%08lX) Failed to parse name \"%wZ\" Status %08lX\n",
247 try_return( ntStatus);
251 // Check for STATUS_REPARSE
254 if( ntStatus == STATUS_REPARSE)
258 // Update the information and return
261 Irp->IoStatus.Information = IO_REPARSE;
263 try_return( ntStatus);
267 // If the returned volume cb is NULL then we are dealing with the \\Server\GlobalRoot
271 if( pVolumeCB == NULL)
275 // Remove any leading or trailing slashes
278 if( uniFileName.Length >= sizeof( WCHAR) &&
279 uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
282 uniFileName.Length -= sizeof( WCHAR);
285 if( uniFileName.Length >= sizeof( WCHAR) &&
286 uniFileName.Buffer[ 0] == L'\\')
289 uniFileName.Buffer = &uniFileName.Buffer[ 1];
291 uniFileName.Length -= sizeof( WCHAR);
295 // If there is a remaining portion returned for this request then
296 // check if it is for the PIOCtl interface
299 if( uniFileName.Length > 0)
303 // We don't accept any other opens off of the AFS Root
306 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
309 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
312 if( RtlCompareUnicodeString( &AFSPIOCtlName,
317 ntStatus = AFSOpenIOCtlFcb( Irp,
319 AFSGlobalRoot->DirectoryCB,
323 if( !NT_SUCCESS( ntStatus))
326 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
327 AFS_TRACE_LEVEL_ERROR,
328 "AFSCommonCreate Failed to open root IOCtl Fcb Status %08lX\n",
332 else if( pParentDirectoryCB != NULL &&
333 pParentDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
336 ntStatus = AFSOpenSpecialShareFcb( Irp,
342 if( !NT_SUCCESS( ntStatus))
345 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
346 AFS_TRACE_LEVEL_ERROR,
347 "AFSCommonCreate Failed to open special share Fcb Status %08lX\n",
352 try_return( ntStatus);
355 ntStatus = AFSOpenAFSRoot( Irp,
359 if( !NT_SUCCESS( ntStatus))
362 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
363 AFS_TRACE_LEVEL_ERROR,
364 "AFSCommonCreate Failed to open root Status %08lX\n",
367 InterlockedDecrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
369 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
370 AFS_TRACE_LEVEL_VERBOSE,
371 "AFSCreate Decrement1 count on &wZ DE %p Ccb %p Cnt %d\n",
372 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
373 AFSGlobalRoot->DirectoryCB,
375 AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
378 try_return( ntStatus);
382 // We have our root node shared
385 bReleaseVolume = TRUE;
388 // Attempt to locate the node in the name tree if this is not a target
389 // open and the target is not the root
392 uniComponentName.Length = 0;
393 uniComponentName.Buffer = NULL;
395 if( uniFileName.Length > sizeof( WCHAR) ||
396 uniFileName.Buffer[ 0] != L'\\')
399 if( !AFSValidNameFormat( &uniFileName))
402 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
404 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
405 AFS_TRACE_LEVEL_VERBOSE,
406 "AFSCommonCreate (%08lX) Invalid name %wZ Status %08lX\n",
411 try_return( ntStatus);
415 // Opening a reparse point directly?
418 ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
420 if( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
422 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
423 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
424 AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
427 uniSubstitutedPathName = uniRootFileName;
429 ntStatus = AFSLocateNameEntry( &stAuthGroup,
434 ulNameProcessingFlags,
440 if( !NT_SUCCESS( ntStatus) &&
441 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
444 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
446 uniSubstitutedPathName.Buffer = NULL;
450 // The routine above released the root while walking the
454 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
455 AFS_TRACE_LEVEL_VERBOSE,
456 "AFSCommonCreate (%08lX) Failed to locate name entry for %wZ Status %08lX\n",
462 // We released any root volume locks in the above on failure
465 bReleaseVolume = FALSE;
467 try_return( ntStatus);
471 // Check for STATUS_REPARSE
474 if( ntStatus == STATUS_REPARSE)
477 uniSubstitutedPathName.Buffer = NULL;
480 // Update the information and return
483 Irp->IoStatus.Information = IO_REPARSE;
486 // We released the volume lock above
489 bReleaseVolume = FALSE;
491 try_return( ntStatus);
495 // If we re-allocated the name, then update our substitute name
498 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
501 uniSubstitutedPathName = uniRootFileName;
506 uniSubstitutedPathName.Buffer = NULL;
510 // Check for a symlink access
513 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
514 pParentDirectoryCB != NULL)
517 UNICODE_STRING uniFinalComponent;
519 uniFinalComponent.Length = 0;
520 uniFinalComponent.MaximumLength = 0;
521 uniFinalComponent.Buffer = NULL;
523 AFSRetrieveFinalComponent( &uniFileName,
526 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
529 if( !NT_SUCCESS( ntStatus) &&
530 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
533 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
534 AFS_TRACE_LEVEL_VERBOSE,
535 "AFSCommonCreate (%08lX) Failing access to symlink %wZ Status %08lX\n",
540 try_return( ntStatus);
546 // If we have no parent then this is a root open, be sure there is a directory entry
550 else if( pParentDirectoryCB == NULL &&
551 pDirectoryCB == NULL)
554 pDirectoryCB = pVolumeCB->DirectoryCB;
557 if( bOpenTargetDirectory)
561 // If we have a directory cb for the entry then dereference it and reference the parent
564 if( pDirectoryCB != NULL)
568 // Perform in this order to prevent thrashing
571 InterlockedIncrement( &pParentDirectoryCB->OpenReferenceCount);
573 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
574 AFS_TRACE_LEVEL_VERBOSE,
575 "AFSCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
576 &pParentDirectoryCB->NameInformation.FileName,
579 pParentDirectoryCB->OpenReferenceCount);
582 // Do NOT decrement the reference count on the pDirectoryCB yet.
583 // The BackupEntry below might drop the count to zero leaving
584 // the entry subject to being deleted and we need some of the
585 // contents during later processing
588 AFSBackupEntry( pNameArray);
592 // OK, open the target directory
595 if( uniComponentName.Length == 0)
597 AFSRetrieveFinalComponent( &uniFileName,
601 ntStatus = AFSOpenTargetDirectory( Irp,
608 if( pDirectoryCB != NULL)
611 // It is now safe to drop the Reference Count
613 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
615 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
616 AFS_TRACE_LEVEL_VERBOSE,
617 "AFSCreate Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
618 &pDirectoryCB->NameInformation.FileName,
621 pDirectoryCB->OpenReferenceCount);
624 if( !NT_SUCCESS( ntStatus))
627 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
628 AFS_TRACE_LEVEL_ERROR,
629 "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
630 &pParentDirectoryCB->NameInformation.FileName,
634 // Decrement the reference on the parent
637 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
639 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
640 AFS_TRACE_LEVEL_VERBOSE,
641 "AFSCreate Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
642 &pParentDirectoryCB->NameInformation.FileName,
645 pParentDirectoryCB->OpenReferenceCount);
648 try_return( ntStatus);
651 if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT) &&
652 pDirectoryCB != NULL)
655 if( !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
657 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
658 AFS_TRACE_LEVEL_VERBOSE,
659 "AFSCommonCreate (%08lX) Reparse open request but attribute not set for %wZ Type %08lX\n",
662 pDirectoryCB->ObjectInformation->FileType);
666 bOpenedReparsePoint = TRUE;
671 // Based on the options passed in, process the file accordingly.
674 if( ulCreateDisposition == FILE_CREATE ||
675 ( ( ulCreateDisposition == FILE_OPEN_IF ||
676 ulCreateDisposition == FILE_OVERWRITE_IF) &&
677 pDirectoryCB == NULL))
680 if( uniComponentName.Length == 0 ||
681 pDirectoryCB != NULL)
685 // We traversed the entire path so we found each entry,
686 // fail with collision
689 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
690 AFS_TRACE_LEVEL_VERBOSE,
691 "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
692 &pDirectoryCB->NameInformation.FileName,
695 if( pDirectoryCB != NULL)
698 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
700 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
701 AFS_TRACE_LEVEL_VERBOSE,
702 "AFSCreate Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
703 &pDirectoryCB->NameInformation.FileName,
706 pDirectoryCB->OpenReferenceCount);
711 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
713 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
714 AFS_TRACE_LEVEL_VERBOSE,
715 "AFSCreate Decrement5 count on %wZ DE %p Ccb %p Cnt %d\n",
716 &pParentDirectoryCB->NameInformation.FileName,
719 pParentDirectoryCB->OpenReferenceCount);
722 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
726 // OK, go and create the node
729 ntStatus = AFSProcessCreate( Irp,
739 if( !NT_SUCCESS( ntStatus))
742 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
743 AFS_TRACE_LEVEL_ERROR,
744 "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
746 &pParentDirectoryCB->NameInformation.FileName,
751 // Dereference the parent entry
754 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
756 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
757 AFS_TRACE_LEVEL_VERBOSE,
758 "AFSCreate Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
759 &pParentDirectoryCB->NameInformation.FileName,
762 pParentDirectoryCB->OpenReferenceCount);
764 try_return( ntStatus);
768 // We should not have an extra component except for PIOCtl opens
771 if( uniComponentName.Length > 0)
775 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
778 if( RtlCompareUnicodeString( &AFSPIOCtlName,
783 ntStatus = AFSOpenIOCtlFcb( Irp,
789 if( !NT_SUCCESS( ntStatus))
792 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
793 AFS_TRACE_LEVEL_ERROR,
794 "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
802 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
803 AFS_TRACE_LEVEL_VERBOSE,
804 "AFSCommonCreate (%08lX) File %wZ name not found\n",
808 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
811 if( !NT_SUCCESS( ntStatus))
815 // Dereference the parent entry
818 if( pDirectoryCB != NULL)
821 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
823 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
824 AFS_TRACE_LEVEL_VERBOSE,
825 "AFSCreate Decrement7a count on %wZ DE %p Ccb %p Cnt %d\n",
826 &pDirectoryCB->NameInformation.FileName,
829 pDirectoryCB->OpenReferenceCount);
834 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
836 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
837 AFS_TRACE_LEVEL_VERBOSE,
838 "AFSCreate Decrement7b count on %wZ DE %p Ccb %p Cnt %d\n",
839 &pParentDirectoryCB->NameInformation.FileName,
842 pParentDirectoryCB->OpenReferenceCount);
846 try_return( ntStatus);
850 // For root opens the parent will be NULL
853 if( pParentDirectoryCB == NULL)
857 // Check for the delete on close flag for the root
860 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
863 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
864 AFS_TRACE_LEVEL_ERROR,
865 "AFSCommonCreate (%08lX) Attempt to open root as delete on close\n",
868 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
870 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
871 AFS_TRACE_LEVEL_VERBOSE,
872 "AFSCreate Decrement8 count on %wZ DE %p Ccb %p Cnt %d\n",
873 &pDirectoryCB->NameInformation.FileName,
876 pDirectoryCB->OpenReferenceCount);
878 try_return( ntStatus = STATUS_CANNOT_DELETE);
882 // If this is the target directory, then bail
885 if( bOpenTargetDirectory)
888 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
889 AFS_TRACE_LEVEL_ERROR,
890 "AFSCommonCreate (%08lX) Attempt to open root as target directory\n",
893 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
895 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
896 AFS_TRACE_LEVEL_VERBOSE,
897 "AFSCreate Decrement9 count on %wZ DE %p Ccb %p Cnt %d\n",
898 &pDirectoryCB->NameInformation.FileName,
901 pDirectoryCB->OpenReferenceCount);
903 try_return( ntStatus = STATUS_INVALID_PARAMETER);
907 // Go and open the root of the volume
910 ntStatus = AFSOpenRoot( Irp,
916 if( !NT_SUCCESS( ntStatus))
919 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
920 AFS_TRACE_LEVEL_ERROR,
921 "AFSCommonCreate Failed to open root (2) Status %08lX\n",
924 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
926 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
927 AFS_TRACE_LEVEL_VERBOSE,
928 "AFSCreate Decrement10 count on %wZ DE %p Ccb %p Cnt %d\n",
929 &pDirectoryCB->NameInformation.FileName,
932 pDirectoryCB->OpenReferenceCount);
935 try_return( ntStatus);
939 // At this point if we have no pDirectoryCB it was not found.
942 if( pDirectoryCB == NULL)
945 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
946 AFS_TRACE_LEVEL_ERROR,
947 "AFSCommonCreate Failing access to %wZ\n",
950 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
953 if( ulCreateDisposition == FILE_OVERWRITE ||
954 ulCreateDisposition == FILE_SUPERSEDE ||
955 ulCreateDisposition == FILE_OVERWRITE_IF)
959 // Go process a file for overwrite or supersede.
962 ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
971 if( !NT_SUCCESS( ntStatus))
974 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
975 AFS_TRACE_LEVEL_ERROR,
976 "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
977 &pDirectoryCB->NameInformation.FileName,
980 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
982 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
983 AFS_TRACE_LEVEL_VERBOSE,
984 "AFSCreate Decrement11 count on %wZ DE %p Ccb %p Cnt %d\n",
985 &pDirectoryCB->NameInformation.FileName,
988 pDirectoryCB->OpenReferenceCount);
991 try_return( ntStatus);
995 // Trying to open the file
998 ntStatus = AFSProcessOpen( Irp,
1006 if( !NT_SUCCESS( ntStatus))
1009 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1010 AFS_TRACE_LEVEL_ERROR,
1011 "AFSCommonCreate Failed open on %wZ Status %08lX\n",
1012 &pDirectoryCB->NameInformation.FileName,
1015 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
1017 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1018 AFS_TRACE_LEVEL_VERBOSE,
1019 "AFSCreate Decrement12 count on %wZ DE %p Ccb %p Cnt %d\n",
1020 &pDirectoryCB->NameInformation.FileName,
1023 pDirectoryCB->OpenReferenceCount);
1028 if( NT_SUCCESS( ntStatus) &&
1029 ntStatus != STATUS_REPARSE)
1036 // If we have a substitute name, then use it
1039 if( uniSubstitutedPathName.Buffer != NULL)
1042 pCcb->FullFileName = uniSubstitutedPathName;
1044 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1046 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1051 pCcb->FullFileName = uniRootFileName;
1053 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1056 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1058 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1062 if( bOpenedReparsePoint)
1064 SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1067 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1068 AFS_TRACE_LEVEL_VERBOSE,
1069 "AFSCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1070 &pCcb->DirectoryCB->NameInformation.FileName,
1073 pCcb->DirectoryCB->OpenReferenceCount);
1075 ASSERT( pCcb->DirectoryCB->OpenReferenceCount > 0);
1077 pCcb->CurrentDirIndex = 0;
1079 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1082 SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1086 // Save off the name array for this instance
1089 pCcb->NameArray = pNameArray;
1095 // If we make it here then init the FO for the request.
1098 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1099 AFS_TRACE_LEVEL_VERBOSE_2,
1100 "AFSCommonCreate (%08lX) FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1106 pFileObject->FsContext = (void *)pFcb;
1108 pFileObject->FsContext2 = (void *)pCcb;
1113 ASSERT( pFcb->OpenHandleCount > 0);
1115 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1117 RtlCopyMemory( &pFcb->AuthGroup,
1122 // For files perform additional processing
1125 if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
1127 pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1131 // If the user did not request nobuffering then mark the FO as cacheable
1134 if( bNoIntermediateBuffering)
1137 pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1142 pFileObject->Flags |= FO_CACHE_SUPPORTED;
1146 // If the file was opened for execution then we need to set the bit in the FO
1149 if( BooleanFlagOn( *pDesiredAccess,
1153 SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1157 // Update the last access time
1160 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1165 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1166 AFS_TRACE_LEVEL_ERROR,
1167 "AFSCommonCreate (%08lX) Returning with NULL Fcb FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1176 if( NT_SUCCESS( ntStatus) &&
1177 ntStatus == STATUS_REPARSE)
1180 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1181 AFS_TRACE_LEVEL_ERROR,
1182 "AFSCommonCreate (%08lX) STATUS_REPARSE FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1190 // Free up the sub name if we have one
1193 if( uniSubstitutedPathName.Buffer != NULL)
1196 AFSExFreePool( uniSubstitutedPathName.Buffer);
1198 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1203 // Free up the name array ...
1206 if( pNameArray != NULL)
1209 AFSFreeNameArray( pNameArray);
1212 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1215 AFSExFreePool( uniRootFileName.Buffer);
1221 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1223 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1224 AFS_TRACE_LEVEL_VERBOSE,
1225 "AFSCommonCreate Decrement count on Volume %08lX Cnt %d\n",
1227 pVolumeCB->VolumeReferenceCount);
1229 AFSReleaseResource( pVolumeCB->VolumeLock);
1233 // Setup the Irp for completion, the Information has been set previously
1236 Irp->IoStatus.Status = ntStatus;
1243 AFSOpenRedirector( IN PIRP Irp,
1248 NTSTATUS ntStatus = STATUS_SUCCESS;
1254 // Initialize the Ccb for the file.
1257 ntStatus = AFSInitCcb( Ccb);
1259 if( !NT_SUCCESS( ntStatus))
1262 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1263 AFS_TRACE_LEVEL_ERROR,
1264 "AFSOpenRedirector (%08lX) Failed to allocate Ccb\n",
1267 try_return( ntStatus);
1274 (*Ccb)->DirectoryCB = AFSRedirectorRoot->DirectoryCB;
1277 // Increment the open count on this Fcb
1280 InterlockedIncrement( &AFSRedirectorRoot->RootFcb->OpenReferenceCount);
1282 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1283 AFS_TRACE_LEVEL_VERBOSE,
1284 "AFSOpenRedirector Increment count on Fcb %08lX Cnt %d\n",
1285 AFSRedirectorRoot->RootFcb,
1286 AFSRedirectorRoot->RootFcb->OpenReferenceCount);
1288 InterlockedIncrement( &AFSRedirectorRoot->RootFcb->OpenHandleCount);
1290 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1291 AFS_TRACE_LEVEL_VERBOSE,
1292 "AFSOpenRedirector Increment handle count on Fcb %08lX Cnt %d\n",
1293 AFSRedirectorRoot->RootFcb,
1294 AFSRedirectorRoot->RootFcb->OpenHandleCount);
1296 *Fcb = AFSRedirectorRoot->RootFcb;
1298 InterlockedIncrement( &(*Ccb)->DirectoryCB->OpenReferenceCount);
1301 // Return the open result for this file
1304 Irp->IoStatus.Information = FILE_OPENED;
1315 AFSOpenAFSRoot( IN PIRP Irp,
1320 NTSTATUS ntStatus = STATUS_SUCCESS;
1326 // Initialize the Ccb for the file.
1329 ntStatus = AFSInitCcb( Ccb);
1331 if( !NT_SUCCESS( ntStatus))
1334 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1335 AFS_TRACE_LEVEL_ERROR,
1336 "AFSOpenAFSRoot (%08lX) Failed to allocate Ccb\n",
1339 try_return( ntStatus);
1346 (*Ccb)->DirectoryCB = AFSGlobalRoot->DirectoryCB;
1349 // Increment the open count on this Fcb
1352 InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1354 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1355 AFS_TRACE_LEVEL_VERBOSE,
1356 "AFSOpenAFSRoot Increment count on Fcb %08lX Cnt %d\n",
1357 AFSGlobalRoot->RootFcb,
1358 AFSGlobalRoot->RootFcb->OpenReferenceCount);
1360 InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1362 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1363 AFS_TRACE_LEVEL_VERBOSE,
1364 "AFSOpenAFSRoot Increment handle count on Fcb %08lX Cnt %d\n",
1365 AFSGlobalRoot->RootFcb,
1366 AFSGlobalRoot->RootFcb->OpenHandleCount);
1368 *Fcb = AFSGlobalRoot->RootFcb;
1371 // Return the open result for this file
1374 Irp->IoStatus.Information = FILE_OPENED;
1385 AFSOpenRoot( IN PIRP Irp,
1386 IN AFSVolumeCB *VolumeCB,
1388 OUT AFSFcb **RootFcb,
1392 NTSTATUS ntStatus = STATUS_SUCCESS;
1393 PFILE_OBJECT pFileObject = NULL;
1394 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1395 PACCESS_MASK pDesiredAccess = NULL;
1396 USHORT usShareAccess;
1397 BOOLEAN bAllocatedCcb = FALSE;
1398 BOOLEAN bReleaseFcb = FALSE;
1399 AFSFileOpenCB stOpenCB;
1400 AFSFileOpenResultCB stOpenResultCB;
1401 ULONG ulResultLen = 0;
1406 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1407 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1409 pFileObject = pIrpSp->FileObject;
1412 // Check if we should go and retrieve updated information for the node
1415 ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1420 if( !NT_SUCCESS( ntStatus))
1423 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1424 AFS_TRACE_LEVEL_ERROR,
1425 "AFSOpenRoot (%08lX) Failed to validate root entry Status %08lX\n",
1429 try_return( ntStatus);
1433 // Check with the service that we can open the file
1436 RtlZeroMemory( &stOpenCB,
1437 sizeof( AFSFileOpenCB));
1439 stOpenCB.DesiredAccess = *pDesiredAccess;
1441 stOpenCB.ShareAccess = usShareAccess;
1443 stOpenResultCB.GrantedAccess = 0;
1445 ulResultLen = sizeof( AFSFileOpenResultCB);
1447 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1448 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1451 &VolumeCB->ObjectInformation.FileId,
1453 sizeof( AFSFileOpenCB),
1454 (void *)&stOpenResultCB,
1457 if( !NT_SUCCESS( ntStatus))
1460 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1461 AFS_TRACE_LEVEL_ERROR,
1462 "AFSOpenRoot (%08lX) Failed to open file in service Status %08lX\n",
1466 try_return( ntStatus);
1470 // If the entry is not initialized then do it now
1473 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1476 AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1479 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1482 ntStatus = AFSEnumerateDirectory( AuthGroup,
1483 &VolumeCB->ObjectInformation,
1486 if( !NT_SUCCESS( ntStatus))
1489 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1491 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1492 AFS_TRACE_LEVEL_ERROR,
1493 "AFSOpenRoot (%08lX) Failed to enumerate directory Status %08lX\n",
1497 try_return( ntStatus);
1500 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1503 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1507 // If the root fcb has been initialized then check access otherwise
1508 // init the volume fcb
1511 if( VolumeCB->RootFcb == NULL)
1514 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1517 if( !NT_SUCCESS( ntStatus))
1520 try_return( ntStatus);
1526 AFSAcquireExcl( VolumeCB->RootFcb->Header.Resource,
1533 // If there are current opens on the Fcb, check the access.
1536 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1539 ntStatus = IoCheckShareAccess( *pDesiredAccess,
1542 &VolumeCB->RootFcb->ShareAccess,
1545 if( !NT_SUCCESS( ntStatus))
1548 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1549 AFS_TRACE_LEVEL_ERROR,
1550 "AFSOpenRoot (%08lX) Access check failure Status %08lX\n",
1554 try_return( ntStatus);
1559 // Initialize the Ccb for the file.
1562 ntStatus = AFSInitCcb( Ccb);
1564 if( !NT_SUCCESS( ntStatus))
1567 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1568 AFS_TRACE_LEVEL_ERROR,
1569 "AFSOpenRoot (%08lX) Failed to allocate Ccb Status %08lX\n",
1573 try_return( ntStatus);
1576 bAllocatedCcb = TRUE;
1582 (*Ccb)->DirectoryCB = VolumeCB->DirectoryCB;
1585 // OK, update the share access on the fileobject
1588 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1591 IoUpdateShareAccess( pFileObject,
1592 &VolumeCB->RootFcb->ShareAccess);
1601 IoSetShareAccess( *pDesiredAccess,
1604 &VolumeCB->RootFcb->ShareAccess);
1608 // Increment the open count on this Fcb
1611 InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1613 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1614 AFS_TRACE_LEVEL_VERBOSE,
1615 "AFSOpenRoot Increment count on Fcb %08lX Cnt %d\n",
1617 VolumeCB->RootFcb->OpenReferenceCount);
1619 InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1621 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1622 AFS_TRACE_LEVEL_VERBOSE,
1623 "AFSOpenRoot Increment handle count on Fcb %08lX Cnt %d\n",
1625 VolumeCB->RootFcb->OpenHandleCount);
1628 // Indicate the object is held
1631 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1634 // Return the open result for this file
1637 Irp->IoStatus.Information = FILE_OPENED;
1639 *RootFcb = VolumeCB->RootFcb;
1646 AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1649 if( !NT_SUCCESS( ntStatus))
1655 AFSRemoveCcb( *Ccb);
1660 Irp->IoStatus.Information = 0;
1668 AFSProcessCreate( IN PIRP Irp,
1670 IN AFSVolumeCB *VolumeCB,
1671 IN AFSDirectoryCB *ParentDirCB,
1672 IN PUNICODE_STRING FileName,
1673 IN PUNICODE_STRING ComponentName,
1674 IN PUNICODE_STRING FullFileName,
1679 NTSTATUS ntStatus = STATUS_SUCCESS;
1680 PFILE_OBJECT pFileObject = NULL;
1681 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1682 ULONG ulOptions = 0;
1683 ULONG ulShareMode = 0;
1685 ULONG ulAttributes = 0;
1686 LARGE_INTEGER liAllocationSize = {0,0};
1687 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1688 BOOLEAN bAllocatedFcb = FALSE;
1689 PACCESS_MASK pDesiredAccess = NULL;
1690 USHORT usShareAccess;
1691 AFSDirectoryCB *pDirEntry = NULL;
1692 AFSObjectInfoCB *pParentObjectInfo = NULL;
1693 AFSObjectInfoCB *pObjectInfo = NULL;
1698 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1699 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1701 pFileObject = pIrpSp->FileObject;
1704 // Extract out the options
1707 ulOptions = pIrpSp->Parameters.Create.Options;
1710 // We pass all attributes they want to apply to the file to the create
1713 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1716 // If this is a directory create then set the attribute correctly
1719 if( ulOptions & FILE_DIRECTORY_FILE)
1722 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1725 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1726 AFS_TRACE_LEVEL_VERBOSE,
1727 "AFSProcessCreate (%08lX) Creating file %wZ Attributes %08lX\n",
1732 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1735 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1736 AFS_TRACE_LEVEL_ERROR,
1737 "AFSProcessCreate Request failed due to read only volume %wZ\n",
1740 try_return( ntStatus = STATUS_ACCESS_DENIED);
1743 pParentObjectInfo = ParentDirCB->ObjectInformation;
1746 // Allocate and insert the direntry into the parent node
1749 ntStatus = AFSCreateDirEntry( AuthGroup,
1757 if( !NT_SUCCESS( ntStatus))
1760 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1761 AFS_TRACE_LEVEL_ERROR,
1762 "AFSProcessCreate (%08lX) Failed to create directory entry %wZ Status %08lX\n",
1767 try_return( ntStatus);
1770 bFileCreated = TRUE;
1772 pObjectInfo = pDirEntry->ObjectInformation;
1774 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1775 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1778 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1779 AFS_TRACE_LEVEL_VERBOSE,
1780 "AFSProcessCreate (%08lX) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1782 &pDirEntry->NameInformation.FileName,
1783 pObjectInfo->FileId.Cell,
1784 pObjectInfo->FileId.Volume,
1785 pObjectInfo->FileId.Vnode,
1786 pObjectInfo->FileId.Unique);
1788 ntStatus = AFSEvaluateNode( AuthGroup,
1791 if( !NT_SUCCESS( ntStatus))
1794 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1795 AFS_TRACE_LEVEL_ERROR,
1796 "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1798 &pDirEntry->NameInformation.FileName,
1799 pObjectInfo->FileId.Cell,
1800 pObjectInfo->FileId.Volume,
1801 pObjectInfo->FileId.Vnode,
1802 pObjectInfo->FileId.Unique,
1805 try_return( ntStatus);
1808 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1812 // We may have raced and the Fcb is already created
1815 if( pObjectInfo->Fcb != NULL)
1818 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1819 AFS_TRACE_LEVEL_VERBOSE,
1820 "AFSProcessCreate (%08lX) Not allocating Fcb for file %wZ\n",
1824 *Fcb = pObjectInfo->Fcb;
1826 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
1833 // Allocate and initialize the Fcb for the file.
1836 ntStatus = AFSInitFcb( pDirEntry,
1839 if( !NT_SUCCESS( ntStatus))
1842 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1843 AFS_TRACE_LEVEL_ERROR,
1844 "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
1849 try_return( ntStatus);
1852 bAllocatedFcb = TRUE;
1858 // Initialize the Ccb for the file.
1861 ntStatus = AFSInitCcb( Ccb);
1863 if( !NT_SUCCESS( ntStatus))
1866 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1867 AFS_TRACE_LEVEL_ERROR,
1868 "AFSProcessCreate (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
1873 try_return( ntStatus);
1876 bAllocatedCcb = TRUE;
1879 // Initialize the Ccb
1882 (*Ccb)->DirectoryCB = pDirEntry;
1885 // If this is a file, update the headers filesizes.
1888 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1892 // Update the sizes with the information passed in
1895 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
1896 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1897 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1900 // Notify the system of the addition
1903 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1905 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1906 (ULONG)FILE_ACTION_ADDED);
1908 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
1910 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1914 // This is a new directory node so indicate it has been enumerated
1917 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1920 // And the parent directory entry
1923 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1926 // Notify the system of the addition
1929 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1931 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1932 (ULONG)FILE_ACTION_ADDED);
1934 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
1935 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
1936 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB)
1940 // And the parent directory entry
1943 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1946 // Notify the system of the addition
1949 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1951 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1952 (ULONG)FILE_ACTION_ADDED);
1956 // Save off the access for the open
1959 IoSetShareAccess( *pDesiredAccess,
1962 &(*Fcb)->ShareAccess);
1965 // Increment the open count on this Fcb
1968 InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1970 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1971 AFS_TRACE_LEVEL_VERBOSE,
1972 "AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n",
1974 (*Fcb)->OpenReferenceCount);
1976 InterlockedIncrement( &(*Fcb)->OpenHandleCount);
1978 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1979 AFS_TRACE_LEVEL_VERBOSE,
1980 "AFSProcessCreate Increment handle count on Fcb %08lX Cnt %d\n",
1982 (*Fcb)->OpenHandleCount);
1985 // Increment the open reference and handle on the parent node
1988 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
1990 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1991 AFS_TRACE_LEVEL_VERBOSE,
1992 "AFSProcessCreate Increment child open handle count on Parent object %08lX Cnt %d\n",
1993 pObjectInfo->ParentObjectInformation,
1994 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
1996 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
1998 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1999 AFS_TRACE_LEVEL_VERBOSE,
2000 "AFSProcessCreate Increment child open ref count on Parent object %08lX Cnt %d\n",
2001 pObjectInfo->ParentObjectInformation,
2002 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2004 if( ulOptions & FILE_DELETE_ON_CLOSE)
2008 // Mark it for delete on close
2011 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2012 AFS_TRACE_LEVEL_VERBOSE,
2013 "AFSProcessCreate (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2018 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2022 // Indicate the object is locked in the service
2025 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2028 // Return the open result for this file
2031 Irp->IoStatus.Information = FILE_CREATED;
2036 // If we created the Fcb we need to release the resources
2042 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2045 if( !NT_SUCCESS( ntStatus))
2051 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2052 AFS_TRACE_LEVEL_VERBOSE,
2053 "AFSProcessCreate Create failed, removing DE %p from aprent object %p Status %08lX\n",
2059 // Remove the dir entry from the parent
2062 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2065 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2068 // Decrement the reference added during initialization of the DE
2071 InterlockedDecrement( &pDirEntry->OpenReferenceCount);
2073 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2074 AFS_TRACE_LEVEL_VERBOSE,
2075 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2076 &pDirEntry->NameInformation.FileName,
2078 pDirEntry->OpenReferenceCount);
2081 // Pull the directory entry from the parent
2084 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2086 FALSE); // Leave it in the enum list so the worker cleans it up
2088 AFSNotifyDelete( pDirEntry,
2092 // Tag the parent as needing verification
2095 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2097 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2103 AFSRemoveCcb( *Ccb);
2109 AFSRemoveFcb( pObjectInfo->Fcb);
2111 pObjectInfo->Fcb = NULL;
2124 AFSOpenTargetDirectory( IN PIRP Irp,
2125 IN AFSVolumeCB *VolumeCB,
2126 IN AFSDirectoryCB *ParentDirectoryCB,
2127 IN AFSDirectoryCB *TargetDirectoryCB,
2128 IN UNICODE_STRING *TargetName,
2133 NTSTATUS ntStatus = STATUS_SUCCESS;
2134 PFILE_OBJECT pFileObject = NULL;
2135 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2136 PACCESS_MASK pDesiredAccess = NULL;
2137 USHORT usShareAccess;
2138 BOOLEAN bAllocatedCcb = FALSE;
2139 BOOLEAN bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2140 AFSObjectInfoCB *pParentObject = NULL, *pTargetObject = NULL;
2141 UNICODE_STRING uniTargetName;
2146 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2147 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2149 pFileObject = pIrpSp->FileObject;
2151 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2152 AFS_TRACE_LEVEL_VERBOSE,
2153 "AFSOpenTargetDirectory (%08lX) Processing file %wZ\n",
2157 pParentObject = ParentDirectoryCB->ObjectInformation;
2159 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2162 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2166 // Make sure we have an Fcb for the access
2169 if( pParentObject->Fcb != NULL)
2172 *Fcb = pParentObject->Fcb;
2174 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
2181 // Allocate and initialize the Fcb for the file.
2184 ntStatus = AFSInitFcb( ParentDirectoryCB,
2187 if( !NT_SUCCESS( ntStatus))
2190 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2191 AFS_TRACE_LEVEL_ERROR,
2192 "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
2194 &ParentDirectoryCB->NameInformation.FileName,
2197 try_return( ntStatus);
2200 bAllocatedFcb = TRUE;
2206 // If there are current opens on the Fcb, check the access.
2209 if( pParentObject->Fcb->OpenHandleCount > 0)
2212 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2215 &pParentObject->Fcb->ShareAccess,
2218 if( !NT_SUCCESS( ntStatus))
2221 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2222 AFS_TRACE_LEVEL_ERROR,
2223 "AFSOpenTargetDirectory (%08lX) Access check failure %wZ Status %08lX\n",
2225 &ParentDirectoryCB->NameInformation.FileName,
2228 try_return( ntStatus);
2233 // Initialize the Ccb for the file.
2236 ntStatus = AFSInitCcb( Ccb);
2238 if( !NT_SUCCESS( ntStatus))
2241 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2242 AFS_TRACE_LEVEL_ERROR,
2243 "AFSOpenTargetDirectory (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2245 &ParentDirectoryCB->NameInformation.FileName,
2248 try_return( ntStatus);
2251 bAllocatedCcb = TRUE;
2254 // Initialize the Ccb
2257 (*Ccb)->DirectoryCB = ParentDirectoryCB;
2259 if( TargetDirectoryCB != NULL &&
2260 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2266 Irp->IoStatus.Information = FILE_EXISTS;
2268 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2273 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2275 uniTargetName = *TargetName;
2279 // Update the filename in the fileobject for rename processing
2282 RtlCopyMemory( pFileObject->FileName.Buffer,
2283 uniTargetName.Buffer,
2284 uniTargetName.Length);
2286 pFileObject->FileName.Length = uniTargetName.Length;
2289 // OK, update the share access on the fileobject
2292 if( pParentObject->Fcb->OpenHandleCount > 0)
2295 IoUpdateShareAccess( pFileObject,
2296 &pParentObject->Fcb->ShareAccess);
2305 IoSetShareAccess( *pDesiredAccess,
2308 &pParentObject->Fcb->ShareAccess);
2312 // Increment the open count on this Fcb
2315 InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2317 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2318 AFS_TRACE_LEVEL_VERBOSE,
2319 "AFSOpenTargetDirectory Increment count on Fcb %08lX Cnt %d\n",
2321 pParentObject->Fcb->OpenReferenceCount);
2323 InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2325 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2326 AFS_TRACE_LEVEL_VERBOSE,
2327 "AFSOpenTargetDirectory Increment handle count on Fcb %08lX Cnt %d\n",
2329 pParentObject->Fcb->OpenHandleCount);
2332 // Increment the open reference and handle on the parent node
2335 if( pParentObject->ParentObjectInformation != NULL)
2338 InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2340 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2341 AFS_TRACE_LEVEL_VERBOSE,
2342 "AFSOpenTargetDirectory Increment child open handle count on Parent object %08lX Cnt %d\n",
2343 pParentObject->ParentObjectInformation,
2344 pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2346 InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2348 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2349 AFS_TRACE_LEVEL_VERBOSE,
2350 "AFSOpenTargetDirectory Increment child open ref count on Parent object %08lX Cnt %d\n",
2351 pParentObject->ParentObjectInformation,
2352 pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2360 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2363 if( !NT_SUCCESS( ntStatus))
2369 AFSRemoveCcb( *Ccb);
2377 AFSRemoveFcb( pParentObject->Fcb);
2379 pParentObject->Fcb = NULL;
2390 AFSProcessOpen( IN PIRP Irp,
2392 IN AFSVolumeCB *VolumeCB,
2393 IN AFSDirectoryCB *ParentDirCB,
2394 IN AFSDirectoryCB *DirectoryCB,
2399 NTSTATUS ntStatus = STATUS_SUCCESS;
2400 PFILE_OBJECT pFileObject = NULL;
2401 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2402 PACCESS_MASK pDesiredAccess = NULL;
2403 USHORT usShareAccess;
2404 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2405 ULONG ulAdditionalFlags = 0, ulOptions = 0;
2406 AFSFileOpenCB stOpenCB;
2407 AFSFileOpenResultCB stOpenResultCB;
2408 ULONG ulResultLen = 0;
2409 AFSObjectInfoCB *pParentObjectInfo = NULL;
2410 AFSObjectInfoCB *pObjectInfo = NULL;
2415 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2416 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2418 pFileObject = pIrpSp->FileObject;
2420 pParentObjectInfo = ParentDirCB->ObjectInformation;
2422 pObjectInfo = DirectoryCB->ObjectInformation;
2425 // Check if the entry is pending a deletion
2428 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2431 ntStatus = STATUS_DELETE_PENDING;
2433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2434 AFS_TRACE_LEVEL_ERROR,
2435 "AFSProcessOpen (%08lX) Entry pending delete %wZ Status %08lX\n",
2437 &DirectoryCB->NameInformation.FileName,
2440 try_return( ntStatus);
2444 // Extract out the options
2447 ulOptions = pIrpSp->Parameters.Create.Options;
2450 // Check if we should go and retrieve updated information for the node
2453 ntStatus = AFSValidateEntry( DirectoryCB,
2458 if( !NT_SUCCESS( ntStatus))
2461 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2462 AFS_TRACE_LEVEL_ERROR,
2463 "AFSProcessOpen (%08lX) Failed to validate entry %wZ Status %08lX\n",
2465 &DirectoryCB->NameInformation.FileName,
2468 try_return( ntStatus);
2472 // If this is marked for delete on close then be sure we can delete the entry
2475 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2478 ntStatus = AFSNotifyDelete( DirectoryCB,
2481 if( !NT_SUCCESS( ntStatus))
2484 ntStatus = STATUS_CANNOT_DELETE;
2486 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2487 AFS_TRACE_LEVEL_ERROR,
2488 "AFSProcessOpen (%08lX) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2490 &DirectoryCB->NameInformation.FileName,
2493 try_return( ntStatus);
2498 // Be sure we have an Fcb for the current object
2501 if( pObjectInfo->Fcb == NULL)
2504 ntStatus = AFSInitFcb( DirectoryCB,
2507 if( !NT_SUCCESS( ntStatus))
2510 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2511 AFS_TRACE_LEVEL_ERROR,
2512 "AFSProcessOpen (%08lX) Failed to init fcb on %wZ Status %08lX\n",
2514 &DirectoryCB->NameInformation.FileName,
2517 try_return( ntStatus);
2520 bAllocatedFcb = TRUE;
2525 AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
2532 // Reference the Fcb so it won't go away while we call into the service for processing
2535 InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2537 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2538 AFS_TRACE_LEVEL_VERBOSE,
2539 "AFSProcessOpen Increment count on Fcb %08lX Cnt %d\n",
2541 pObjectInfo->Fcb->OpenReferenceCount);
2544 // Check access on the entry
2547 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2550 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2553 &pObjectInfo->Fcb->ShareAccess,
2556 if( !NT_SUCCESS( ntStatus))
2559 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2560 AFS_TRACE_LEVEL_ERROR,
2561 "AFSProcessOpen (%08lX) Failed to check share access on %wZ Status %08lX\n",
2563 &DirectoryCB->NameInformation.FileName,
2566 try_return( ntStatus);
2571 // Additional checks
2574 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2578 // If the caller is asking for write access then try to flush the image section
2581 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2582 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2585 if( !MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2589 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2590 STATUS_SHARING_VIOLATION;
2592 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2593 AFS_TRACE_LEVEL_ERROR,
2594 "AFSProcessOpen (%08lX) Failed to flush image section %wZ Status %08lX\n",
2596 &DirectoryCB->NameInformation.FileName,
2599 try_return( ntStatus);
2603 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2606 ntStatus = STATUS_NOT_A_DIRECTORY;
2608 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2609 AFS_TRACE_LEVEL_ERROR,
2610 "AFSProcessOpen (%08lX) Attempt to open file as directory %wZ Status %08lX\n",
2612 &DirectoryCB->NameInformation.FileName,
2615 try_return( ntStatus);
2618 pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2620 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2621 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2624 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2627 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2629 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2630 AFS_TRACE_LEVEL_ERROR,
2631 "AFSProcessOpen (%08lX) Attempt to open directory as file %wZ Status %08lX\n",
2633 &DirectoryCB->NameInformation.FileName,
2636 try_return( ntStatus);
2639 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2640 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2641 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB)
2648 try_return( ntStatus = STATUS_UNSUCCESSFUL);
2652 // Check with the service that we can open the file
2655 stOpenCB.ParentId = pParentObjectInfo->FileId;
2657 stOpenCB.DesiredAccess = *pDesiredAccess;
2659 stOpenCB.ShareAccess = usShareAccess;
2661 stOpenResultCB.GrantedAccess = 0;
2663 ulResultLen = sizeof( AFSFileOpenResultCB);
2665 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2666 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2668 &DirectoryCB->NameInformation.FileName,
2669 &pObjectInfo->FileId,
2671 sizeof( AFSFileOpenCB),
2672 (void *)&stOpenResultCB,
2675 if( !NT_SUCCESS( ntStatus))
2678 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2679 AFS_TRACE_LEVEL_ERROR,
2680 "AFSProcessOpen (%08lX) Failed open in service %wZ Status %08lX\n",
2682 &DirectoryCB->NameInformation.FileName,
2685 try_return( ntStatus);
2689 // Check if there is a conflict
2692 if( !AFSCheckAccess( *pDesiredAccess,
2693 stOpenResultCB.GrantedAccess,
2694 BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2697 ntStatus = STATUS_ACCESS_DENIED;
2699 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2700 AFS_TRACE_LEVEL_ERROR,
2701 "AFSProcessOpen (%08lX) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2704 stOpenResultCB.GrantedAccess,
2705 &DirectoryCB->NameInformation.FileName,
2708 try_return( ntStatus);
2712 // Initialize the Ccb for the file.
2715 ntStatus = AFSInitCcb( Ccb);
2717 if( !NT_SUCCESS( ntStatus))
2720 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2721 AFS_TRACE_LEVEL_ERROR,
2722 "AFSProcessOpen (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2724 &DirectoryCB->NameInformation.FileName,
2727 try_return( ntStatus);
2730 bAllocatedCcb = TRUE;
2732 (*Ccb)->DirectoryCB = DirectoryCB;
2735 // Perform the access check on the target if this is a mount point or symlink
2738 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2741 IoUpdateShareAccess( pFileObject,
2742 &pObjectInfo->Fcb->ShareAccess);
2751 IoSetShareAccess( *pDesiredAccess,
2754 &pObjectInfo->Fcb->ShareAccess);
2758 // Increment the open count on this Fcb
2761 InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2763 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2764 AFS_TRACE_LEVEL_VERBOSE,
2765 "AFSProcessOpen Increment2 count on Fcb %08lX Cnt %d\n",
2767 pObjectInfo->Fcb->OpenReferenceCount);
2769 InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2771 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2772 AFS_TRACE_LEVEL_VERBOSE,
2773 "AFSProcessOpen Increment handle count on Fcb %08lX Cnt %d\n",
2775 pObjectInfo->Fcb->OpenHandleCount);
2778 // Increment the open reference and handle on the parent node
2781 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2783 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2784 AFS_TRACE_LEVEL_VERBOSE,
2785 "AFSProcessOpen Increment child open handle count on Parent object %08lX Cnt %d\n",
2786 pObjectInfo->ParentObjectInformation,
2787 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2789 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2791 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2792 AFS_TRACE_LEVEL_VERBOSE,
2793 "AFSProcessOpen Increment child open ref count on Parent object %08lX Cnt %d\n",
2794 pObjectInfo->ParentObjectInformation,
2795 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2797 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2801 // Mark it for delete on close
2804 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2805 AFS_TRACE_LEVEL_VERBOSE,
2806 "AFSProcessOpen (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2809 &DirectoryCB->NameInformation.FileName);
2811 SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2815 // Indicate the object is held
2818 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2821 // Return the open result for this file
2824 Irp->IoStatus.Information = FILE_OPENED;
2826 *Fcb = pObjectInfo->Fcb;
2834 // Remove the reference we added initially
2837 InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2839 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2840 AFS_TRACE_LEVEL_VERBOSE,
2841 "AFSProcessOpen Decrement count on Fcb %08lX Cnt %d\n",
2843 pObjectInfo->Fcb->OpenReferenceCount);
2845 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2848 if( !NT_SUCCESS( ntStatus))
2854 AFSRemoveCcb( *Ccb);
2862 AFSRemoveFcb( pObjectInfo->Fcb);
2864 pObjectInfo->Fcb = NULL;
2875 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
2877 IN AFSVolumeCB *VolumeCB,
2879 IN AFSDirectoryCB *ParentDirCB,
2880 IN AFSDirectoryCB *DirectoryCB,
2885 NTSTATUS ntStatus = STATUS_SUCCESS;
2886 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2887 PFILE_OBJECT pFileObject = NULL;
2888 LARGE_INTEGER liZero = {0,0};
2889 BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
2890 ULONG ulAttributes = 0;
2891 LARGE_INTEGER liTime;
2892 ULONG ulCreateDisposition = 0;
2893 BOOLEAN bAllocatedCcb = FALSE, bAllocatedFcb = FALSE;
2894 PACCESS_MASK pDesiredAccess = NULL;
2895 USHORT usShareAccess;
2896 AFSObjectInfoCB *pParentObjectInfo = NULL;
2897 AFSObjectInfoCB *pObjectInfo = NULL;
2902 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2903 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2905 pFileObject = pIrpSp->FileObject;
2907 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
2909 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
2911 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
2914 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2915 AFS_TRACE_LEVEL_ERROR,
2916 "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
2918 &DirectoryCB->NameInformation.FileName);
2920 try_return( ntStatus = STATUS_ACCESS_DENIED);
2923 pParentObjectInfo = ParentDirCB->ObjectInformation;
2925 pObjectInfo = DirectoryCB->ObjectInformation;
2928 // Check if we should go and retrieve updated information for the node
2931 ntStatus = AFSValidateEntry( DirectoryCB,
2936 if( !NT_SUCCESS( ntStatus))
2939 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2940 AFS_TRACE_LEVEL_ERROR,
2941 "AFSProcessOverwriteSupersede (%08lX) Failed to validate entry %wZ Status %08lX\n",
2943 &DirectoryCB->NameInformation.FileName,
2946 try_return( ntStatus);
2950 // Be sure we have an Fcb for the object block
2953 if( pObjectInfo->Fcb == NULL)
2956 ntStatus = AFSInitFcb( DirectoryCB,
2959 if( !NT_SUCCESS( ntStatus))
2962 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2963 AFS_TRACE_LEVEL_ERROR,
2964 "AFSProcessOverwriteSupersede (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
2966 &DirectoryCB->NameInformation.FileName,
2969 try_return( ntStatus);
2972 bAllocatedFcb = TRUE;
2977 AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
2984 // Reference the Fcb so it won't go away while processing the request
2987 InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2989 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2990 AFS_TRACE_LEVEL_VERBOSE,
2991 "AFSProcessOverwriteSupersede Increment count on Fcb %08lX Cnt %d\n",
2993 pObjectInfo->Fcb->OpenReferenceCount);
2996 // Check access on the entry
2999 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3002 ntStatus = IoCheckShareAccess( *pDesiredAccess,
3005 &pObjectInfo->Fcb->ShareAccess,
3008 if( !NT_SUCCESS( ntStatus))
3011 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3012 AFS_TRACE_LEVEL_ERROR,
3013 "AFSProcessOverwriteSupersede (%08lX) Access check failure %wZ Status %08lX\n",
3015 &DirectoryCB->NameInformation.FileName,
3018 try_return( ntStatus);
3023 // Before we actually truncate, check to see if the purge
3024 // is going to fail.
3027 if( !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3031 ntStatus = STATUS_USER_MAPPED_FILE;
3033 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3034 AFS_TRACE_LEVEL_ERROR,
3035 "AFSProcessOverwriteSupersede (%08lX) File user mapped %wZ Status %08lX\n",
3037 &DirectoryCB->NameInformation.FileName,
3040 try_return( ntStatus);
3044 // Initialize the Ccb for the file.
3047 ntStatus = AFSInitCcb( Ccb);
3049 if( !NT_SUCCESS( ntStatus))
3052 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3053 AFS_TRACE_LEVEL_ERROR,
3054 "AFSProcessOverwriteSupersede (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
3056 &DirectoryCB->NameInformation.FileName,
3059 try_return( ntStatus);
3062 bAllocatedCcb = TRUE;
3065 // Initialize the Ccb
3068 (*Ccb)->DirectoryCB = DirectoryCB;
3071 // Need to purge any data currently in the cache
3074 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3079 pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3080 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3081 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3083 pObjectInfo->EndOfFile.QuadPart = 0;
3084 pObjectInfo->AllocationSize.QuadPart = 0;
3087 // Trim down the extents. We do this BEFORE telling the service
3088 // the file is truncated since there is a potential race between
3089 // a worker thread releasing extents and us trimming
3092 AFSTrimExtents( pObjectInfo->Fcb,
3093 &pObjectInfo->Fcb->Header.FileSize);
3095 KeQuerySystemTime( &pObjectInfo->ChangeTime);
3097 KeQuerySystemTime( &pObjectInfo->LastAccessTime);
3099 //KeQuerySystemTime( &pObjectInfo->CreationTime);
3101 KeQuerySystemTime( &pObjectInfo->LastWriteTime);
3103 ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
3107 if( !NT_SUCCESS( ntStatus))
3110 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3111 AFS_TRACE_LEVEL_ERROR,
3112 "AFSProcessOverwriteSupersede (%08lX) Failed to update file information %wZ Status %08lX\n",
3114 &DirectoryCB->NameInformation.FileName,
3117 try_return( ntStatus);
3120 AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3123 bReleasePaging = TRUE;
3125 pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
3127 pFileObject->FsContext = (void *)pObjectInfo->Fcb;
3129 pFileObject->FsContext2 = (void *)*Ccb;
3132 // Set the update flag accordingly
3135 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
3136 AFS_FCB_FLAG_UPDATE_CREATE_TIME |
3137 AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
3138 AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
3139 AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
3141 CcSetFileSizes( pFileObject,
3142 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3144 AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3146 bReleasePaging = FALSE;
3148 ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
3150 if( ulCreateDisposition == FILE_SUPERSEDE)
3153 pObjectInfo->FileAttributes = ulAttributes;
3159 pObjectInfo->FileAttributes |= ulAttributes;
3163 // Save off the access for the open
3166 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3169 IoUpdateShareAccess( pFileObject,
3170 &pObjectInfo->Fcb->ShareAccess);