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;
152 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
153 pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
154 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
155 ulOptions = pIrpSp->Parameters.Create.Options;
156 bNoIntermediateBuffering = BooleanFlagOn( ulOptions, FILE_NO_INTERMEDIATE_BUFFERING);
157 bOpenTargetDirectory = BooleanFlagOn( pIrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
158 pFileObject = pIrpSp->FileObject;
159 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
161 uniFileName.Length = uniFileName.MaximumLength = 0;
162 uniFileName.Buffer = NULL;
164 uniRootFileName.Length = uniRootFileName.MaximumLength = 0;
165 uniRootFileName.Buffer = NULL;
167 uniParsedFileName.Length = uniParsedFileName.MaximumLength = 0;
168 uniParsedFileName.Buffer = NULL;
170 uniSubstitutedPathName.Buffer = NULL;
171 uniSubstitutedPathName.Length = 0;
173 uniRelativeName.Buffer = NULL;
174 uniRelativeName.Length = 0;
176 if( AFSGlobalRoot == NULL)
178 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
181 RtlZeroMemory( &stAuthGroup,
184 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
185 (ULONGLONG)PsGetCurrentThreadId(),
188 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
191 ntStatus = AFSEnumerateGlobalRoot( &stAuthGroup);
193 if( !NT_SUCCESS( ntStatus))
196 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
197 AFS_TRACE_LEVEL_ERROR,
198 "AFSCommonCreate Failed to enumerate global root Status %08lX\n",
201 try_return( ntStatus);
206 // If we are in shutdown mode then fail the request
209 if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
212 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
213 AFS_TRACE_LEVEL_WARNING,
214 "AFSCommonCreate (%08lX) Open request after shutdown\n",
217 try_return( ntStatus = STATUS_TOO_LATE);
221 // Go and parse the name for processing.
222 // If ulParseFlags is returned with AFS_PARSE_FLAG_FREE_FILE_BUFFER set,
223 // then we are responsible for releasing the uniRootFileName.Buffer.
226 ntStatus = AFSParseName( Irp,
236 if( !NT_SUCCESS( ntStatus))
239 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
240 uniFileName.Length > 0 ? AFS_TRACE_LEVEL_ERROR : AFS_TRACE_LEVEL_VERBOSE,
241 "AFSCommonCreate (%08lX) Failed to parse name \"%wZ\" Status %08lX\n",
246 try_return( ntStatus);
250 // Check for STATUS_REPARSE
253 if( ntStatus == STATUS_REPARSE)
257 // Update the information and return
260 Irp->IoStatus.Information = IO_REPARSE;
262 try_return( ntStatus);
266 // If the returned volume cb is NULL then we are dealing with the \\Server\GlobalRoot
270 if( pVolumeCB == NULL)
274 // Remove any leading or trailing slashes
277 if( uniFileName.Length >= sizeof( WCHAR) &&
278 uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
281 uniFileName.Length -= sizeof( WCHAR);
284 if( uniFileName.Length >= sizeof( WCHAR) &&
285 uniFileName.Buffer[ 0] == L'\\')
288 uniFileName.Buffer = &uniFileName.Buffer[ 1];
290 uniFileName.Length -= sizeof( WCHAR);
294 // If there is a remaining portion returned for this request then
295 // check if it is for the PIOCtl interface
298 if( uniFileName.Length > 0)
302 // We don't accept any other opens off of the AFS Root
305 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
308 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
311 if( RtlCompareUnicodeString( &AFSPIOCtlName,
316 ntStatus = AFSOpenIOCtlFcb( Irp,
318 AFSGlobalRoot->DirectoryCB,
322 if( !NT_SUCCESS( ntStatus))
325 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
326 AFS_TRACE_LEVEL_ERROR,
327 "AFSCommonCreate Failed to open root IOCtl Fcb Status %08lX\n",
331 else if( pParentDirectoryCB != NULL &&
332 pParentDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
335 ntStatus = AFSOpenSpecialShareFcb( Irp,
341 if( !NT_SUCCESS( ntStatus))
344 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
345 AFS_TRACE_LEVEL_ERROR,
346 "AFSCommonCreate Failed to open special share Fcb Status %08lX\n",
351 try_return( ntStatus);
354 ntStatus = AFSOpenAFSRoot( Irp,
358 if( !NT_SUCCESS( ntStatus))
361 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
362 AFS_TRACE_LEVEL_ERROR,
363 "AFSCommonCreate Failed to open root Status %08lX\n",
366 InterlockedDecrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
368 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
369 AFS_TRACE_LEVEL_VERBOSE,
370 "AFSCreate Decrement1 count on &wZ DE %p Ccb %p Cnt %d\n",
371 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
372 AFSGlobalRoot->DirectoryCB,
374 AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
377 try_return( ntStatus);
381 // We have our root node shared
384 bReleaseVolume = TRUE;
387 // Attempt to locate the node in the name tree if this is not a target
388 // open and the target is not the root
391 uniComponentName.Length = 0;
392 uniComponentName.Buffer = NULL;
394 if( uniFileName.Length > sizeof( WCHAR) ||
395 uniFileName.Buffer[ 0] != L'\\')
398 if( !AFSValidNameFormat( &uniFileName))
401 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
403 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
404 AFS_TRACE_LEVEL_VERBOSE,
405 "AFSCommonCreate (%08lX) Invalid name %wZ Status %08lX\n",
410 try_return( ntStatus);
414 // Opening a reparse point directly?
417 ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
419 if( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
421 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
422 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
423 AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
426 uniSubstitutedPathName = uniRootFileName;
428 ntStatus = AFSLocateNameEntry( &stAuthGroup,
433 ulNameProcessingFlags,
439 if( !NT_SUCCESS( ntStatus) &&
440 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
443 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
445 uniSubstitutedPathName.Buffer = NULL;
449 // The routine above released the root while walking the
453 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
454 AFS_TRACE_LEVEL_VERBOSE,
455 "AFSCommonCreate (%08lX) Failed to locate name entry for %wZ Status %08lX\n",
461 // We released any root volume locks in the above on failure
464 bReleaseVolume = FALSE;
466 try_return( ntStatus);
470 // Check for STATUS_REPARSE
473 if( ntStatus == STATUS_REPARSE)
476 uniSubstitutedPathName.Buffer = NULL;
479 // Update the information and return
482 Irp->IoStatus.Information = IO_REPARSE;
485 // We released the volume lock above
488 bReleaseVolume = FALSE;
490 try_return( ntStatus);
494 // If we re-allocated the name, then update our substitute name
497 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
500 uniSubstitutedPathName = uniRootFileName;
505 uniSubstitutedPathName.Buffer = NULL;
509 // Check for a symlink access
512 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
513 pParentDirectoryCB != NULL)
516 UNICODE_STRING uniFinalComponent;
518 uniFinalComponent.Length = 0;
519 uniFinalComponent.MaximumLength = 0;
520 uniFinalComponent.Buffer = NULL;
522 AFSRetrieveFinalComponent( &uniFileName,
525 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
528 if( !NT_SUCCESS( ntStatus) &&
529 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
532 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
533 AFS_TRACE_LEVEL_VERBOSE,
534 "AFSCommonCreate (%08lX) Failing access to symlink %wZ Status %08lX\n",
539 try_return( ntStatus);
545 // If we have no parent then this is a root open, be sure there is a directory entry
549 else if( pParentDirectoryCB == NULL &&
550 pDirectoryCB == NULL)
553 pDirectoryCB = pVolumeCB->DirectoryCB;
556 if( bOpenTargetDirectory)
560 // If we have a directory cb for the entry then dereference it and reference the parent
563 if( pDirectoryCB != NULL)
567 // Perform in this order to prevent thrashing
570 InterlockedIncrement( &pParentDirectoryCB->OpenReferenceCount);
572 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
573 AFS_TRACE_LEVEL_VERBOSE,
574 "AFSCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
575 &pParentDirectoryCB->NameInformation.FileName,
578 pParentDirectoryCB->OpenReferenceCount);
581 // Do NOT decrement the reference count on the pDirectoryCB yet.
582 // The BackupEntry below might drop the count to zero leaving
583 // the entry subject to being deleted and we need some of the
584 // contents during later processing
587 AFSBackupEntry( pNameArray);
591 // OK, open the target directory
594 if( uniComponentName.Length == 0)
596 AFSRetrieveFinalComponent( &uniFileName,
600 ntStatus = AFSOpenTargetDirectory( Irp,
607 if( pDirectoryCB != NULL)
610 // It is now safe to drop the Reference Count
612 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
614 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
615 AFS_TRACE_LEVEL_VERBOSE,
616 "AFSCreate Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
617 &pDirectoryCB->NameInformation.FileName,
620 pDirectoryCB->OpenReferenceCount);
623 if( !NT_SUCCESS( ntStatus))
626 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
627 AFS_TRACE_LEVEL_ERROR,
628 "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
629 &pParentDirectoryCB->NameInformation.FileName,
633 // Decrement the reference on the parent
636 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
638 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
639 AFS_TRACE_LEVEL_VERBOSE,
640 "AFSCreate Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
641 &pParentDirectoryCB->NameInformation.FileName,
644 pParentDirectoryCB->OpenReferenceCount);
647 try_return( ntStatus);
650 if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT) &&
651 pDirectoryCB != NULL &&
652 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
655 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
656 AFS_TRACE_LEVEL_VERBOSE,
657 "AFSCommonCreate (%08lX) Reparse open request but attribute not set for %wZ Type %08lX\n",
660 pDirectoryCB->ObjectInformation->FileType);
664 // Based on the options passed in, process the file accordingly.
667 if( ulCreateDisposition == FILE_CREATE ||
668 ( ( ulCreateDisposition == FILE_OPEN_IF ||
669 ulCreateDisposition == FILE_OVERWRITE_IF) &&
670 pDirectoryCB == NULL))
673 if( uniComponentName.Length == 0 ||
674 pDirectoryCB != NULL)
678 // We traversed the entire path so we found each entry,
679 // fail with collision
682 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
683 AFS_TRACE_LEVEL_VERBOSE,
684 "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
685 &pDirectoryCB->NameInformation.FileName,
688 if( pDirectoryCB != NULL)
691 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
693 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
694 AFS_TRACE_LEVEL_VERBOSE,
695 "AFSCreate Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
696 &pDirectoryCB->NameInformation.FileName,
699 pDirectoryCB->OpenReferenceCount);
704 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
706 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
707 AFS_TRACE_LEVEL_VERBOSE,
708 "AFSCreate Decrement5 count on %wZ DE %p Ccb %p Cnt %d\n",
709 &pParentDirectoryCB->NameInformation.FileName,
712 pParentDirectoryCB->OpenReferenceCount);
715 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
719 // OK, go and create the node
722 ntStatus = AFSProcessCreate( Irp,
732 if( !NT_SUCCESS( ntStatus))
735 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
736 AFS_TRACE_LEVEL_ERROR,
737 "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
739 &pParentDirectoryCB->NameInformation.FileName,
744 // Dereference the parent entry
747 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
749 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
750 AFS_TRACE_LEVEL_VERBOSE,
751 "AFSCreate Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
752 &pParentDirectoryCB->NameInformation.FileName,
755 pParentDirectoryCB->OpenReferenceCount);
757 try_return( ntStatus);
761 // We should not have an extra component except for PIOCtl opens
764 if( uniComponentName.Length > 0)
768 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
771 if( RtlCompareUnicodeString( &AFSPIOCtlName,
776 ntStatus = AFSOpenIOCtlFcb( Irp,
782 if( !NT_SUCCESS( ntStatus))
785 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
786 AFS_TRACE_LEVEL_ERROR,
787 "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
795 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
796 AFS_TRACE_LEVEL_VERBOSE,
797 "AFSCommonCreate (%08lX) File %wZ name not found\n",
801 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
804 if( !NT_SUCCESS( ntStatus))
808 // Dereference the parent entry
811 if( pDirectoryCB != NULL)
814 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
816 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
817 AFS_TRACE_LEVEL_VERBOSE,
818 "AFSCreate Decrement7a count on %wZ DE %p Ccb %p Cnt %d\n",
819 &pDirectoryCB->NameInformation.FileName,
822 pDirectoryCB->OpenReferenceCount);
827 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
829 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
830 AFS_TRACE_LEVEL_VERBOSE,
831 "AFSCreate Decrement7b count on %wZ DE %p Ccb %p Cnt %d\n",
832 &pParentDirectoryCB->NameInformation.FileName,
835 pParentDirectoryCB->OpenReferenceCount);
839 try_return( ntStatus);
843 // For root opens the parent will be NULL
846 if( pParentDirectoryCB == NULL)
850 // Check for the delete on close flag for the root
853 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
856 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
857 AFS_TRACE_LEVEL_ERROR,
858 "AFSCommonCreate (%08lX) Attempt to open root as delete on close\n",
861 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
863 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
864 AFS_TRACE_LEVEL_VERBOSE,
865 "AFSCreate Decrement8 count on %wZ DE %p Ccb %p Cnt %d\n",
866 &pDirectoryCB->NameInformation.FileName,
869 pDirectoryCB->OpenReferenceCount);
871 try_return( ntStatus = STATUS_CANNOT_DELETE);
875 // If this is the target directory, then bail
878 if( bOpenTargetDirectory)
881 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
882 AFS_TRACE_LEVEL_ERROR,
883 "AFSCommonCreate (%08lX) Attempt to open root as target directory\n",
886 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
888 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
889 AFS_TRACE_LEVEL_VERBOSE,
890 "AFSCreate Decrement9 count on %wZ DE %p Ccb %p Cnt %d\n",
891 &pDirectoryCB->NameInformation.FileName,
894 pDirectoryCB->OpenReferenceCount);
896 try_return( ntStatus = STATUS_INVALID_PARAMETER);
900 // Go and open the root of the volume
903 ntStatus = AFSOpenRoot( Irp,
909 if( !NT_SUCCESS( ntStatus))
912 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
913 AFS_TRACE_LEVEL_ERROR,
914 "AFSCommonCreate Failed to open root (2) Status %08lX\n",
917 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
919 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
920 AFS_TRACE_LEVEL_VERBOSE,
921 "AFSCreate Decrement10 count on %wZ DE %p Ccb %p Cnt %d\n",
922 &pDirectoryCB->NameInformation.FileName,
925 pDirectoryCB->OpenReferenceCount);
928 try_return( ntStatus);
932 // At this point if we have no pDirectoryCB it was not found.
935 if( pDirectoryCB == NULL)
938 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
939 AFS_TRACE_LEVEL_ERROR,
940 "AFSCommonCreate Failing access to %wZ\n",
943 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
946 if( ulCreateDisposition == FILE_OVERWRITE ||
947 ulCreateDisposition == FILE_SUPERSEDE ||
948 ulCreateDisposition == FILE_OVERWRITE_IF)
952 // Go process a file for overwrite or supersede.
955 ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
964 if( !NT_SUCCESS( ntStatus))
967 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
968 AFS_TRACE_LEVEL_ERROR,
969 "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
970 &pDirectoryCB->NameInformation.FileName,
973 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
975 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
976 AFS_TRACE_LEVEL_VERBOSE,
977 "AFSCreate Decrement11 count on %wZ DE %p Ccb %p Cnt %d\n",
978 &pDirectoryCB->NameInformation.FileName,
981 pDirectoryCB->OpenReferenceCount);
984 try_return( ntStatus);
988 // Trying to open the file
991 ntStatus = AFSProcessOpen( Irp,
999 if( !NT_SUCCESS( ntStatus))
1002 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1003 AFS_TRACE_LEVEL_ERROR,
1004 "AFSCommonCreate Failed open on %wZ Status %08lX\n",
1005 &pDirectoryCB->NameInformation.FileName,
1008 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
1010 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1011 AFS_TRACE_LEVEL_VERBOSE,
1012 "AFSCreate Decrement12 count on %wZ DE %p Ccb %p Cnt %d\n",
1013 &pDirectoryCB->NameInformation.FileName,
1016 pDirectoryCB->OpenReferenceCount);
1021 if( NT_SUCCESS( ntStatus) &&
1022 ntStatus != STATUS_REPARSE)
1029 // If we have a substitute name, then use it
1032 if( uniSubstitutedPathName.Buffer != NULL)
1035 pCcb->FullFileName = uniSubstitutedPathName;
1037 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1039 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1044 pCcb->FullFileName = uniRootFileName;
1046 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1049 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1051 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1055 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1056 AFS_TRACE_LEVEL_VERBOSE,
1057 "AFSCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1058 &pCcb->DirectoryCB->NameInformation.FileName,
1061 pCcb->DirectoryCB->OpenReferenceCount);
1063 ASSERT( pCcb->DirectoryCB->OpenReferenceCount > 0);
1065 pCcb->CurrentDirIndex = 0;
1067 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1070 SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1074 // Save off the name array for this instance
1077 pCcb->NameArray = pNameArray;
1083 // If we make it here then init the FO for the request.
1086 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1087 AFS_TRACE_LEVEL_VERBOSE_2,
1088 "AFSCommonCreate (%08lX) FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1094 pFileObject->FsContext = (void *)pFcb;
1096 pFileObject->FsContext2 = (void *)pCcb;
1101 ASSERT( pFcb->OpenHandleCount > 0);
1103 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1105 RtlCopyMemory( &pFcb->AuthGroup,
1110 // For files perform additional processing
1113 if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
1115 pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1119 // If the user did not request nobuffering then mark the FO as cacheable
1122 if( bNoIntermediateBuffering)
1125 pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1130 pFileObject->Flags |= FO_CACHE_SUPPORTED;
1134 // If the file was opened for execution then we need to set the bit in the FO
1137 if( BooleanFlagOn( *pDesiredAccess,
1141 SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1145 // Update the last access time
1148 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1153 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1154 AFS_TRACE_LEVEL_ERROR,
1155 "AFSCommonCreate (%08lX) Returning with NULL Fcb FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1164 if( NT_SUCCESS( ntStatus) &&
1165 ntStatus == STATUS_REPARSE)
1168 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1169 AFS_TRACE_LEVEL_ERROR,
1170 "AFSCommonCreate (%08lX) STATUS_REPARSE FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1178 // Free up the sub name if we have one
1181 if( uniSubstitutedPathName.Buffer != NULL)
1184 AFSExFreePool( uniSubstitutedPathName.Buffer);
1186 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1191 // Free up the name array ...
1194 if( pNameArray != NULL)
1197 AFSFreeNameArray( pNameArray);
1200 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1203 AFSExFreePool( uniRootFileName.Buffer);
1209 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1211 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1212 AFS_TRACE_LEVEL_VERBOSE,
1213 "AFSCommonCreate Decrement count on Volume %08lX Cnt %d\n",
1215 pVolumeCB->VolumeReferenceCount);
1217 AFSReleaseResource( pVolumeCB->VolumeLock);
1221 // Setup the Irp for completion, the Information has been set previously
1224 Irp->IoStatus.Status = ntStatus;
1231 AFSOpenRedirector( IN PIRP Irp,
1236 NTSTATUS ntStatus = STATUS_SUCCESS;
1242 // Initialize the Ccb for the file.
1245 ntStatus = AFSInitCcb( Ccb);
1247 if( !NT_SUCCESS( ntStatus))
1250 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1251 AFS_TRACE_LEVEL_ERROR,
1252 "AFSOpenRedirector (%08lX) Failed to allocate Ccb\n",
1255 try_return( ntStatus);
1262 (*Ccb)->DirectoryCB = AFSRedirectorRoot->DirectoryCB;
1265 // Increment the open count on this Fcb
1268 InterlockedIncrement( &AFSRedirectorRoot->RootFcb->OpenReferenceCount);
1270 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1271 AFS_TRACE_LEVEL_VERBOSE,
1272 "AFSOpenRedirector Increment count on Fcb %08lX Cnt %d\n",
1273 AFSRedirectorRoot->RootFcb,
1274 AFSRedirectorRoot->RootFcb->OpenReferenceCount);
1276 InterlockedIncrement( &AFSRedirectorRoot->RootFcb->OpenHandleCount);
1278 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1279 AFS_TRACE_LEVEL_VERBOSE,
1280 "AFSOpenRedirector Increment handle count on Fcb %08lX Cnt %d\n",
1281 AFSRedirectorRoot->RootFcb,
1282 AFSRedirectorRoot->RootFcb->OpenHandleCount);
1284 *Fcb = AFSRedirectorRoot->RootFcb;
1286 InterlockedIncrement( &(*Ccb)->DirectoryCB->OpenReferenceCount);
1289 // Return the open result for this file
1292 Irp->IoStatus.Information = FILE_OPENED;
1303 AFSOpenAFSRoot( IN PIRP Irp,
1308 NTSTATUS ntStatus = STATUS_SUCCESS;
1314 // Initialize the Ccb for the file.
1317 ntStatus = AFSInitCcb( Ccb);
1319 if( !NT_SUCCESS( ntStatus))
1322 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1323 AFS_TRACE_LEVEL_ERROR,
1324 "AFSOpenAFSRoot (%08lX) Failed to allocate Ccb\n",
1327 try_return( ntStatus);
1334 (*Ccb)->DirectoryCB = AFSGlobalRoot->DirectoryCB;
1337 // Increment the open count on this Fcb
1340 InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1342 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1343 AFS_TRACE_LEVEL_VERBOSE,
1344 "AFSOpenAFSRoot Increment count on Fcb %08lX Cnt %d\n",
1345 AFSGlobalRoot->RootFcb,
1346 AFSGlobalRoot->RootFcb->OpenReferenceCount);
1348 InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1350 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1351 AFS_TRACE_LEVEL_VERBOSE,
1352 "AFSOpenAFSRoot Increment handle count on Fcb %08lX Cnt %d\n",
1353 AFSGlobalRoot->RootFcb,
1354 AFSGlobalRoot->RootFcb->OpenHandleCount);
1356 *Fcb = AFSGlobalRoot->RootFcb;
1359 // Return the open result for this file
1362 Irp->IoStatus.Information = FILE_OPENED;
1373 AFSOpenRoot( IN PIRP Irp,
1374 IN AFSVolumeCB *VolumeCB,
1376 OUT AFSFcb **RootFcb,
1380 NTSTATUS ntStatus = STATUS_SUCCESS;
1381 PFILE_OBJECT pFileObject = NULL;
1382 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1383 PACCESS_MASK pDesiredAccess = NULL;
1384 USHORT usShareAccess;
1385 BOOLEAN bAllocatedCcb = FALSE;
1386 BOOLEAN bReleaseFcb = FALSE;
1387 AFSFileOpenCB stOpenCB;
1388 AFSFileOpenResultCB stOpenResultCB;
1389 ULONG ulResultLen = 0;
1394 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1395 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1397 pFileObject = pIrpSp->FileObject;
1400 // Check if we should go and retrieve updated information for the node
1403 ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1408 if( !NT_SUCCESS( ntStatus))
1411 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1412 AFS_TRACE_LEVEL_ERROR,
1413 "AFSOpenRoot (%08lX) Failed to validate root entry Status %08lX\n",
1417 try_return( ntStatus);
1421 // Check with the service that we can open the file
1424 RtlZeroMemory( &stOpenCB,
1425 sizeof( AFSFileOpenCB));
1427 stOpenCB.DesiredAccess = *pDesiredAccess;
1429 stOpenCB.ShareAccess = usShareAccess;
1431 stOpenResultCB.GrantedAccess = 0;
1433 ulResultLen = sizeof( AFSFileOpenResultCB);
1435 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1436 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1439 &VolumeCB->ObjectInformation.FileId,
1441 sizeof( AFSFileOpenCB),
1442 (void *)&stOpenResultCB,
1445 if( !NT_SUCCESS( ntStatus))
1448 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1449 AFS_TRACE_LEVEL_ERROR,
1450 "AFSOpenRoot (%08lX) Failed to open file in service Status %08lX\n",
1454 try_return( ntStatus);
1458 // If the entry is not initialized then do it now
1461 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1464 AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1467 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1470 ntStatus = AFSEnumerateDirectory( AuthGroup,
1471 &VolumeCB->ObjectInformation,
1474 if( !NT_SUCCESS( ntStatus))
1477 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1479 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1480 AFS_TRACE_LEVEL_ERROR,
1481 "AFSOpenRoot (%08lX) Failed to enumerate directory Status %08lX\n",
1485 try_return( ntStatus);
1488 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1491 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1495 // If the root fcb has been initialized then check access otherwise
1496 // init the volume fcb
1499 if( VolumeCB->RootFcb == NULL)
1502 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1505 if( !NT_SUCCESS( ntStatus))
1508 try_return( ntStatus);
1514 AFSAcquireExcl( VolumeCB->RootFcb->Header.Resource,
1521 // If there are current opens on the Fcb, check the access.
1524 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1527 ntStatus = IoCheckShareAccess( *pDesiredAccess,
1530 &VolumeCB->RootFcb->ShareAccess,
1533 if( !NT_SUCCESS( ntStatus))
1536 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1537 AFS_TRACE_LEVEL_ERROR,
1538 "AFSOpenRoot (%08lX) Access check failure Status %08lX\n",
1542 try_return( ntStatus);
1547 // Initialize the Ccb for the file.
1550 ntStatus = AFSInitCcb( Ccb);
1552 if( !NT_SUCCESS( ntStatus))
1555 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1556 AFS_TRACE_LEVEL_ERROR,
1557 "AFSOpenRoot (%08lX) Failed to allocate Ccb Status %08lX\n",
1561 try_return( ntStatus);
1564 bAllocatedCcb = TRUE;
1570 (*Ccb)->DirectoryCB = VolumeCB->DirectoryCB;
1573 // OK, update the share access on the fileobject
1576 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1579 IoUpdateShareAccess( pFileObject,
1580 &VolumeCB->RootFcb->ShareAccess);
1589 IoSetShareAccess( *pDesiredAccess,
1592 &VolumeCB->RootFcb->ShareAccess);
1596 // Increment the open count on this Fcb
1599 InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1601 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1602 AFS_TRACE_LEVEL_VERBOSE,
1603 "AFSOpenRoot Increment count on Fcb %08lX Cnt %d\n",
1605 VolumeCB->RootFcb->OpenReferenceCount);
1607 InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1609 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1610 AFS_TRACE_LEVEL_VERBOSE,
1611 "AFSOpenRoot Increment handle count on Fcb %08lX Cnt %d\n",
1613 VolumeCB->RootFcb->OpenHandleCount);
1616 // Indicate the object is held
1619 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1622 // Return the open result for this file
1625 Irp->IoStatus.Information = FILE_OPENED;
1627 *RootFcb = VolumeCB->RootFcb;
1634 AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1637 if( !NT_SUCCESS( ntStatus))
1643 AFSRemoveCcb( *Ccb);
1648 Irp->IoStatus.Information = 0;
1656 AFSProcessCreate( IN PIRP Irp,
1658 IN AFSVolumeCB *VolumeCB,
1659 IN AFSDirectoryCB *ParentDirCB,
1660 IN PUNICODE_STRING FileName,
1661 IN PUNICODE_STRING ComponentName,
1662 IN PUNICODE_STRING FullFileName,
1667 NTSTATUS ntStatus = STATUS_SUCCESS;
1668 PFILE_OBJECT pFileObject = NULL;
1669 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1670 ULONG ulOptions = 0;
1671 ULONG ulShareMode = 0;
1673 ULONG ulAttributes = 0;
1674 LARGE_INTEGER liAllocationSize = {0,0};
1675 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1676 BOOLEAN bAllocatedFcb = FALSE;
1677 PACCESS_MASK pDesiredAccess = NULL;
1678 USHORT usShareAccess;
1679 AFSDirectoryCB *pDirEntry = NULL;
1680 AFSObjectInfoCB *pParentObjectInfo = NULL;
1681 AFSObjectInfoCB *pObjectInfo = NULL;
1686 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1687 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1689 pFileObject = pIrpSp->FileObject;
1692 // Extract out the options
1695 ulOptions = pIrpSp->Parameters.Create.Options;
1698 // We pass all attributes they want to apply to the file to the create
1701 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1704 // If this is a directory create then set the attribute correctly
1707 if( ulOptions & FILE_DIRECTORY_FILE)
1710 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1713 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1714 AFS_TRACE_LEVEL_VERBOSE,
1715 "AFSProcessCreate (%08lX) Creating file %wZ Attributes %08lX\n",
1720 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1723 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1724 AFS_TRACE_LEVEL_ERROR,
1725 "AFSProcessCreate Request failed due to read only volume %wZ\n",
1728 try_return( ntStatus = STATUS_ACCESS_DENIED);
1731 pParentObjectInfo = ParentDirCB->ObjectInformation;
1734 // Allocate and insert the direntry into the parent node
1737 ntStatus = AFSCreateDirEntry( AuthGroup,
1745 if( !NT_SUCCESS( ntStatus))
1748 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1749 AFS_TRACE_LEVEL_ERROR,
1750 "AFSProcessCreate (%08lX) Failed to create directory entry %wZ Status %08lX\n",
1755 try_return( ntStatus);
1758 bFileCreated = TRUE;
1760 pObjectInfo = pDirEntry->ObjectInformation;
1762 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1763 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1766 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1767 AFS_TRACE_LEVEL_VERBOSE,
1768 "AFSProcessCreate (%08lX) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1770 &pDirEntry->NameInformation.FileName,
1771 pObjectInfo->FileId.Cell,
1772 pObjectInfo->FileId.Volume,
1773 pObjectInfo->FileId.Vnode,
1774 pObjectInfo->FileId.Unique);
1776 ntStatus = AFSEvaluateNode( AuthGroup,
1779 if( !NT_SUCCESS( ntStatus))
1782 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1783 AFS_TRACE_LEVEL_ERROR,
1784 "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1786 &pDirEntry->NameInformation.FileName,
1787 pObjectInfo->FileId.Cell,
1788 pObjectInfo->FileId.Volume,
1789 pObjectInfo->FileId.Vnode,
1790 pObjectInfo->FileId.Unique,
1793 try_return( ntStatus);
1796 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1800 // We may have raced and the Fcb is already created
1803 if( pObjectInfo->Fcb != NULL)
1806 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1807 AFS_TRACE_LEVEL_VERBOSE,
1808 "AFSProcessCreate (%08lX) Not allocating Fcb for file %wZ\n",
1812 *Fcb = pObjectInfo->Fcb;
1814 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
1821 // Allocate and initialize the Fcb for the file.
1824 ntStatus = AFSInitFcb( pDirEntry,
1827 if( !NT_SUCCESS( ntStatus))
1830 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1831 AFS_TRACE_LEVEL_ERROR,
1832 "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
1837 try_return( ntStatus);
1840 bAllocatedFcb = TRUE;
1846 // Initialize the Ccb for the file.
1849 ntStatus = AFSInitCcb( Ccb);
1851 if( !NT_SUCCESS( ntStatus))
1854 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1855 AFS_TRACE_LEVEL_ERROR,
1856 "AFSProcessCreate (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
1861 try_return( ntStatus);
1864 bAllocatedCcb = TRUE;
1867 // Initialize the Ccb
1870 (*Ccb)->DirectoryCB = pDirEntry;
1873 // If this is a file, update the headers filesizes.
1876 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1880 // Update the sizes with the information passed in
1883 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
1884 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1885 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1888 // Notify the system of the addition
1891 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1893 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1894 (ULONG)FILE_ACTION_ADDED);
1896 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
1898 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1902 // This is a new directory node so indicate it has been enumerated
1905 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1908 // And the parent directory entry
1911 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1914 // Notify the system of the addition
1917 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1919 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1920 (ULONG)FILE_ACTION_ADDED);
1922 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
1923 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
1924 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB)
1928 // And the parent directory entry
1931 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1934 // Notify the system of the addition
1937 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1939 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1940 (ULONG)FILE_ACTION_ADDED);
1944 // Save off the access for the open
1947 IoSetShareAccess( *pDesiredAccess,
1950 &(*Fcb)->ShareAccess);
1953 // Increment the open count on this Fcb
1956 InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1958 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1959 AFS_TRACE_LEVEL_VERBOSE,
1960 "AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n",
1962 (*Fcb)->OpenReferenceCount);
1964 InterlockedIncrement( &(*Fcb)->OpenHandleCount);
1966 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1967 AFS_TRACE_LEVEL_VERBOSE,
1968 "AFSProcessCreate Increment handle count on Fcb %08lX Cnt %d\n",
1970 (*Fcb)->OpenHandleCount);
1973 // Increment the open reference and handle on the parent node
1976 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
1978 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1979 AFS_TRACE_LEVEL_VERBOSE,
1980 "AFSProcessCreate Increment child open handle count on Parent object %08lX Cnt %d\n",
1981 pObjectInfo->ParentObjectInformation,
1982 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
1984 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
1986 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1987 AFS_TRACE_LEVEL_VERBOSE,
1988 "AFSProcessCreate Increment child open ref count on Parent object %08lX Cnt %d\n",
1989 pObjectInfo->ParentObjectInformation,
1990 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
1992 if( ulOptions & FILE_DELETE_ON_CLOSE)
1996 // Mark it for delete on close
1999 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2000 AFS_TRACE_LEVEL_VERBOSE,
2001 "AFSProcessCreate (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2006 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2010 // Indicate the object is locked in the service
2013 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2016 // Return the open result for this file
2019 Irp->IoStatus.Information = FILE_CREATED;
2024 // If we created the Fcb we need to release the resources
2030 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2033 if( !NT_SUCCESS( ntStatus))
2039 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2040 AFS_TRACE_LEVEL_VERBOSE,
2041 "AFSProcessCreate Create failed, removing DE %p from aprent object %p Status %08lX\n",
2047 // Remove the dir entry from the parent
2050 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2053 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2056 // Decrement the reference added during initialization of the DE
2059 InterlockedDecrement( &pDirEntry->OpenReferenceCount);
2061 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2062 AFS_TRACE_LEVEL_VERBOSE,
2063 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2064 &pDirEntry->NameInformation.FileName,
2066 pDirEntry->OpenReferenceCount);
2069 // Pull the directory entry from the parent
2072 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2074 FALSE); // Leave it in the enum list so the worker cleans it up
2076 AFSNotifyDelete( pDirEntry,
2080 // Tag the parent as needing verification
2083 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2085 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2091 AFSRemoveCcb( *Ccb);
2097 AFSRemoveFcb( pObjectInfo->Fcb);
2099 pObjectInfo->Fcb = NULL;
2112 AFSOpenTargetDirectory( IN PIRP Irp,
2113 IN AFSVolumeCB *VolumeCB,
2114 IN AFSDirectoryCB *ParentDirectoryCB,
2115 IN AFSDirectoryCB *TargetDirectoryCB,
2116 IN UNICODE_STRING *TargetName,
2121 NTSTATUS ntStatus = STATUS_SUCCESS;
2122 PFILE_OBJECT pFileObject = NULL;
2123 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2124 PACCESS_MASK pDesiredAccess = NULL;
2125 USHORT usShareAccess;
2126 BOOLEAN bAllocatedCcb = FALSE;
2127 BOOLEAN bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2128 AFSObjectInfoCB *pParentObject = NULL, *pTargetObject = NULL;
2129 UNICODE_STRING uniTargetName;
2134 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2135 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2137 pFileObject = pIrpSp->FileObject;
2139 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2140 AFS_TRACE_LEVEL_VERBOSE,
2141 "AFSOpenTargetDirectory (%08lX) Processing file %wZ\n",
2145 pParentObject = ParentDirectoryCB->ObjectInformation;
2147 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2150 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2154 // Make sure we have an Fcb for the access
2157 if( pParentObject->Fcb != NULL)
2160 *Fcb = pParentObject->Fcb;
2162 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
2169 // Allocate and initialize the Fcb for the file.
2172 ntStatus = AFSInitFcb( ParentDirectoryCB,
2175 if( !NT_SUCCESS( ntStatus))
2178 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2179 AFS_TRACE_LEVEL_ERROR,
2180 "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
2182 &ParentDirectoryCB->NameInformation.FileName,
2185 try_return( ntStatus);
2188 bAllocatedFcb = TRUE;
2194 // If there are current opens on the Fcb, check the access.
2197 if( pParentObject->Fcb->OpenHandleCount > 0)
2200 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2203 &pParentObject->Fcb->ShareAccess,
2206 if( !NT_SUCCESS( ntStatus))
2209 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2210 AFS_TRACE_LEVEL_ERROR,
2211 "AFSOpenTargetDirectory (%08lX) Access check failure %wZ Status %08lX\n",
2213 &ParentDirectoryCB->NameInformation.FileName,
2216 try_return( ntStatus);
2221 // Initialize the Ccb for the file.
2224 ntStatus = AFSInitCcb( Ccb);
2226 if( !NT_SUCCESS( ntStatus))
2229 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2230 AFS_TRACE_LEVEL_ERROR,
2231 "AFSOpenTargetDirectory (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2233 &ParentDirectoryCB->NameInformation.FileName,
2236 try_return( ntStatus);
2239 bAllocatedCcb = TRUE;
2242 // Initialize the Ccb
2245 (*Ccb)->DirectoryCB = ParentDirectoryCB;
2247 if( TargetDirectoryCB != NULL &&
2248 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2254 Irp->IoStatus.Information = FILE_EXISTS;
2256 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2261 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2263 uniTargetName = *TargetName;
2267 // Update the filename in the fileobject for rename processing
2270 RtlCopyMemory( pFileObject->FileName.Buffer,
2271 uniTargetName.Buffer,
2272 uniTargetName.Length);
2274 pFileObject->FileName.Length = uniTargetName.Length;
2277 // OK, update the share access on the fileobject
2280 if( pParentObject->Fcb->OpenHandleCount > 0)
2283 IoUpdateShareAccess( pFileObject,
2284 &pParentObject->Fcb->ShareAccess);
2293 IoSetShareAccess( *pDesiredAccess,
2296 &pParentObject->Fcb->ShareAccess);
2300 // Increment the open count on this Fcb
2303 InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2305 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2306 AFS_TRACE_LEVEL_VERBOSE,
2307 "AFSOpenTargetDirectory Increment count on Fcb %08lX Cnt %d\n",
2309 pParentObject->Fcb->OpenReferenceCount);
2311 InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2313 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2314 AFS_TRACE_LEVEL_VERBOSE,
2315 "AFSOpenTargetDirectory Increment handle count on Fcb %08lX Cnt %d\n",
2317 pParentObject->Fcb->OpenHandleCount);
2320 // Increment the open reference and handle on the parent node
2323 if( pParentObject->ParentObjectInformation != NULL)
2326 InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2328 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2329 AFS_TRACE_LEVEL_VERBOSE,
2330 "AFSOpenTargetDirectory Increment child open handle count on Parent object %08lX Cnt %d\n",
2331 pParentObject->ParentObjectInformation,
2332 pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2334 InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2336 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2337 AFS_TRACE_LEVEL_VERBOSE,
2338 "AFSOpenTargetDirectory Increment child open ref count on Parent object %08lX Cnt %d\n",
2339 pParentObject->ParentObjectInformation,
2340 pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2348 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2351 if( !NT_SUCCESS( ntStatus))
2357 AFSRemoveCcb( *Ccb);
2365 AFSRemoveFcb( pParentObject->Fcb);
2367 pParentObject->Fcb = NULL;
2378 AFSProcessOpen( IN PIRP Irp,
2380 IN AFSVolumeCB *VolumeCB,
2381 IN AFSDirectoryCB *ParentDirCB,
2382 IN AFSDirectoryCB *DirectoryCB,
2387 NTSTATUS ntStatus = STATUS_SUCCESS;
2388 PFILE_OBJECT pFileObject = NULL;
2389 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2390 PACCESS_MASK pDesiredAccess = NULL;
2391 USHORT usShareAccess;
2392 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2393 ULONG ulAdditionalFlags = 0, ulOptions = 0;
2394 AFSFileOpenCB stOpenCB;
2395 AFSFileOpenResultCB stOpenResultCB;
2396 ULONG ulResultLen = 0;
2397 AFSObjectInfoCB *pParentObjectInfo = NULL;
2398 AFSObjectInfoCB *pObjectInfo = NULL;
2403 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2404 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2406 pFileObject = pIrpSp->FileObject;
2408 pParentObjectInfo = ParentDirCB->ObjectInformation;
2410 pObjectInfo = DirectoryCB->ObjectInformation;
2413 // Check if the entry is pending a deletion
2416 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2419 ntStatus = STATUS_DELETE_PENDING;
2421 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2422 AFS_TRACE_LEVEL_ERROR,
2423 "AFSProcessOpen (%08lX) Entry pending delete %wZ Status %08lX\n",
2425 &DirectoryCB->NameInformation.FileName,
2428 try_return( ntStatus);
2432 // Extract out the options
2435 ulOptions = pIrpSp->Parameters.Create.Options;
2438 // Check if we should go and retrieve updated information for the node
2441 ntStatus = AFSValidateEntry( DirectoryCB,
2446 if( !NT_SUCCESS( ntStatus))
2449 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2450 AFS_TRACE_LEVEL_ERROR,
2451 "AFSProcessOpen (%08lX) Failed to validate entry %wZ Status %08lX\n",
2453 &DirectoryCB->NameInformation.FileName,
2456 try_return( ntStatus);
2460 // If this is marked for delete on close then be sure we can delete the entry
2463 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2466 ntStatus = AFSNotifyDelete( DirectoryCB,
2469 if( !NT_SUCCESS( ntStatus))
2472 ntStatus = STATUS_CANNOT_DELETE;
2474 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2475 AFS_TRACE_LEVEL_ERROR,
2476 "AFSProcessOpen (%08lX) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2478 &DirectoryCB->NameInformation.FileName,
2481 try_return( ntStatus);
2486 // Be sure we have an Fcb for the current object
2489 if( pObjectInfo->Fcb == NULL)
2492 ntStatus = AFSInitFcb( DirectoryCB,
2495 if( !NT_SUCCESS( ntStatus))
2498 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2499 AFS_TRACE_LEVEL_ERROR,
2500 "AFSProcessOpen (%08lX) Failed to init fcb on %wZ Status %08lX\n",
2502 &DirectoryCB->NameInformation.FileName,
2505 try_return( ntStatus);
2508 bAllocatedFcb = TRUE;
2513 AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
2520 // Reference the Fcb so it won't go away while we call into the service for processing
2523 InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2525 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2526 AFS_TRACE_LEVEL_VERBOSE,
2527 "AFSProcessOpen Increment count on Fcb %08lX Cnt %d\n",
2529 pObjectInfo->Fcb->OpenReferenceCount);
2532 // Check access on the entry
2535 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2538 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2541 &pObjectInfo->Fcb->ShareAccess,
2544 if( !NT_SUCCESS( ntStatus))
2547 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2548 AFS_TRACE_LEVEL_ERROR,
2549 "AFSProcessOpen (%08lX) Failed to check share access on %wZ Status %08lX\n",
2551 &DirectoryCB->NameInformation.FileName,
2554 try_return( ntStatus);
2559 // Additional checks
2562 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2566 // If the caller is asking for write access then try to flush the image section
2569 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2570 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2573 if( !MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2577 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2578 STATUS_SHARING_VIOLATION;
2580 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2581 AFS_TRACE_LEVEL_ERROR,
2582 "AFSProcessOpen (%08lX) Failed to flush image section %wZ Status %08lX\n",
2584 &DirectoryCB->NameInformation.FileName,
2587 try_return( ntStatus);
2591 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2594 ntStatus = STATUS_NOT_A_DIRECTORY;
2596 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2597 AFS_TRACE_LEVEL_ERROR,
2598 "AFSProcessOpen (%08lX) Attempt to open file as directory %wZ Status %08lX\n",
2600 &DirectoryCB->NameInformation.FileName,
2603 try_return( ntStatus);
2606 pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2608 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2609 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2612 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2615 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2617 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2618 AFS_TRACE_LEVEL_ERROR,
2619 "AFSProcessOpen (%08lX) Attempt to open directory as file %wZ Status %08lX\n",
2621 &DirectoryCB->NameInformation.FileName,
2624 try_return( ntStatus);
2627 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2628 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2629 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB)
2636 try_return( ntStatus = STATUS_UNSUCCESSFUL);
2640 // Check with the service that we can open the file
2643 stOpenCB.ParentId = pParentObjectInfo->FileId;
2645 stOpenCB.DesiredAccess = *pDesiredAccess;
2647 stOpenCB.ShareAccess = usShareAccess;
2649 stOpenResultCB.GrantedAccess = 0;
2651 ulResultLen = sizeof( AFSFileOpenResultCB);
2653 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2654 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2656 &DirectoryCB->NameInformation.FileName,
2657 &pObjectInfo->FileId,
2659 sizeof( AFSFileOpenCB),
2660 (void *)&stOpenResultCB,
2663 if( !NT_SUCCESS( ntStatus))
2666 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2667 AFS_TRACE_LEVEL_ERROR,
2668 "AFSProcessOpen (%08lX) Failed open in service %wZ Status %08lX\n",
2670 &DirectoryCB->NameInformation.FileName,
2673 try_return( ntStatus);
2677 // Check if there is a conflict
2680 if( !AFSCheckAccess( *pDesiredAccess,
2681 stOpenResultCB.GrantedAccess,
2682 BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2685 ntStatus = STATUS_ACCESS_DENIED;
2687 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2688 AFS_TRACE_LEVEL_ERROR,
2689 "AFSProcessOpen (%08lX) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2692 stOpenResultCB.GrantedAccess,
2693 &DirectoryCB->NameInformation.FileName,
2696 try_return( ntStatus);
2700 // Initialize the Ccb for the file.
2703 ntStatus = AFSInitCcb( Ccb);
2705 if( !NT_SUCCESS( ntStatus))
2708 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2709 AFS_TRACE_LEVEL_ERROR,
2710 "AFSProcessOpen (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2712 &DirectoryCB->NameInformation.FileName,
2715 try_return( ntStatus);
2718 bAllocatedCcb = TRUE;
2720 (*Ccb)->DirectoryCB = DirectoryCB;
2723 // Perform the access check on the target if this is a mount point or symlink
2726 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2729 IoUpdateShareAccess( pFileObject,
2730 &pObjectInfo->Fcb->ShareAccess);
2739 IoSetShareAccess( *pDesiredAccess,
2742 &pObjectInfo->Fcb->ShareAccess);
2746 // Increment the open count on this Fcb
2749 InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2751 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2752 AFS_TRACE_LEVEL_VERBOSE,
2753 "AFSProcessOpen Increment2 count on Fcb %08lX Cnt %d\n",
2755 pObjectInfo->Fcb->OpenReferenceCount);
2757 InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2759 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2760 AFS_TRACE_LEVEL_VERBOSE,
2761 "AFSProcessOpen Increment handle count on Fcb %08lX Cnt %d\n",
2763 pObjectInfo->Fcb->OpenHandleCount);
2766 // Increment the open reference and handle on the parent node
2769 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2771 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2772 AFS_TRACE_LEVEL_VERBOSE,
2773 "AFSProcessOpen Increment child open handle count on Parent object %08lX Cnt %d\n",
2774 pObjectInfo->ParentObjectInformation,
2775 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2777 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2779 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2780 AFS_TRACE_LEVEL_VERBOSE,
2781 "AFSProcessOpen Increment child open ref count on Parent object %08lX Cnt %d\n",
2782 pObjectInfo->ParentObjectInformation,
2783 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2785 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2789 // Mark it for delete on close
2792 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2793 AFS_TRACE_LEVEL_VERBOSE,
2794 "AFSProcessOpen (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2797 &DirectoryCB->NameInformation.FileName);
2799 SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2803 // Indicate the object is held
2806 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2809 // Return the open result for this file
2812 Irp->IoStatus.Information = FILE_OPENED;
2814 *Fcb = pObjectInfo->Fcb;
2822 // Remove the reference we added initially
2825 InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2827 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2828 AFS_TRACE_LEVEL_VERBOSE,
2829 "AFSProcessOpen Decrement count on Fcb %08lX Cnt %d\n",
2831 pObjectInfo->Fcb->OpenReferenceCount);
2833 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2836 if( !NT_SUCCESS( ntStatus))
2842 AFSRemoveCcb( *Ccb);
2850 AFSRemoveFcb( pObjectInfo->Fcb);
2852 pObjectInfo->Fcb = NULL;
2863 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
2865 IN AFSVolumeCB *VolumeCB,
2867 IN AFSDirectoryCB *ParentDirCB,
2868 IN AFSDirectoryCB *DirectoryCB,
2873 NTSTATUS ntStatus = STATUS_SUCCESS;
2874 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2875 PFILE_OBJECT pFileObject = NULL;
2876 LARGE_INTEGER liZero = {0,0};
2877 BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
2878 ULONG ulAttributes = 0;
2879 LARGE_INTEGER liTime;
2880 ULONG ulCreateDisposition = 0;
2881 BOOLEAN bAllocatedCcb = FALSE, bAllocatedFcb = FALSE;
2882 PACCESS_MASK pDesiredAccess = NULL;
2883 USHORT usShareAccess;
2884 AFSObjectInfoCB *pParentObjectInfo = NULL;
2885 AFSObjectInfoCB *pObjectInfo = NULL;
2890 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2891 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2893 pFileObject = pIrpSp->FileObject;
2895 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
2897 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
2899 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
2902 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2903 AFS_TRACE_LEVEL_ERROR,
2904 "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
2906 &DirectoryCB->NameInformation.FileName);
2908 try_return( ntStatus = STATUS_ACCESS_DENIED);
2911 pParentObjectInfo = ParentDirCB->ObjectInformation;
2913 pObjectInfo = DirectoryCB->ObjectInformation;
2916 // Check if we should go and retrieve updated information for the node
2919 ntStatus = AFSValidateEntry( DirectoryCB,
2924 if( !NT_SUCCESS( ntStatus))
2927 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2928 AFS_TRACE_LEVEL_ERROR,
2929 "AFSProcessOverwriteSupersede (%08lX) Failed to validate entry %wZ Status %08lX\n",
2931 &DirectoryCB->NameInformation.FileName,
2934 try_return( ntStatus);
2938 // Be sure we have an Fcb for the object block
2941 if( pObjectInfo->Fcb == NULL)
2944 ntStatus = AFSInitFcb( DirectoryCB,
2947 if( !NT_SUCCESS( ntStatus))
2950 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2951 AFS_TRACE_LEVEL_ERROR,
2952 "AFSProcessOverwriteSupersede (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
2954 &DirectoryCB->NameInformation.FileName,
2957 try_return( ntStatus);
2960 bAllocatedFcb = TRUE;
2965 AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
2972 // Reference the Fcb so it won't go away while processing the request
2975 InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2977 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2978 AFS_TRACE_LEVEL_VERBOSE,
2979 "AFSProcessOverwriteSupersede Increment count on Fcb %08lX Cnt %d\n",
2981 pObjectInfo->Fcb->OpenReferenceCount);
2984 // Check access on the entry
2987 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2990 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2993 &pObjectInfo->Fcb->ShareAccess,
2996 if( !NT_SUCCESS( ntStatus))
2999 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3000 AFS_TRACE_LEVEL_ERROR,
3001 "AFSProcessOverwriteSupersede (%08lX) Access check failure %wZ Status %08lX\n",
3003 &DirectoryCB->NameInformation.FileName,
3006 try_return( ntStatus);
3011 // Before we actually truncate, check to see if the purge
3012 // is going to fail.
3015 if( !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3019 ntStatus = STATUS_USER_MAPPED_FILE;
3021 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3022 AFS_TRACE_LEVEL_ERROR,
3023 "AFSProcessOverwriteSupersede (%08lX) File user mapped %wZ Status %08lX\n",
3025 &DirectoryCB->NameInformation.FileName,
3028 try_return( ntStatus);
3032 // Initialize the Ccb for the file.
3035 ntStatus = AFSInitCcb( Ccb);
3037 if( !NT_SUCCESS( ntStatus))
3040 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3041 AFS_TRACE_LEVEL_ERROR,
3042 "AFSProcessOverwriteSupersede (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
3044 &DirectoryCB->NameInformation.FileName,
3047 try_return( ntStatus);
3050 bAllocatedCcb = TRUE;
3053 // Initialize the Ccb
3056 (*Ccb)->DirectoryCB = DirectoryCB;
3059 // Need to purge any data currently in the cache
3062 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3067 pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3068 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3069 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3071 pObjectInfo->EndOfFile.QuadPart = 0;
3072 pObjectInfo->AllocationSize.QuadPart = 0;
3075 // Trim down the extents. We do this BEFORE telling the service
3076 // the file is truncated since there is a potential race between
3077 // a worker thread releasing extents and us trimming
3080 AFSTrimExtents( pObjectInfo->Fcb,
3081 &pObjectInfo->Fcb->Header.FileSize);
3083 KeQuerySystemTime( &pObjectInfo->ChangeTime);
3085 KeQuerySystemTime( &pObjectInfo->LastAccessTime);
3087 //KeQuerySystemTime( &pObjectInfo->CreationTime);
3089 KeQuerySystemTime( &pObjectInfo->LastWriteTime);
3091 ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
3095 if( !NT_SUCCESS( ntStatus))
3098 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3099 AFS_TRACE_LEVEL_ERROR,
3100 "AFSProcessOverwriteSupersede (%08lX) Failed to update file information %wZ Status %08lX\n",
3102 &DirectoryCB->NameInformation.FileName,
3105 try_return( ntStatus);
3108 AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3111 bReleasePaging = TRUE;
3113 pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
3115 pFileObject->FsContext = (void *)pObjectInfo->Fcb;
3117 pFileObject->FsContext2 = (void *)*Ccb;
3120 // Set the update flag accordingly
3123 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
3124 AFS_FCB_FLAG_UPDATE_CREATE_TIME |
3125 AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
3126 AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
3127 AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
3129 CcSetFileSizes( pFileObject,
3130 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3132 AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3134 bReleasePaging = FALSE;
3136 ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
3138 if( ulCreateDisposition == FILE_SUPERSEDE)
3141 pObjectInfo->FileAttributes = ulAttributes;
3147 pObjectInfo->FileAttributes |= ulAttributes;
3151 // Save off the access for the open
3154 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3157 IoUpdateShareAccess( pFileObject,
3158 &pObjectInfo->Fcb->ShareAccess);
3167 IoSetShareAccess( *pDesiredAccess,
3170 &pObjectInfo->Fcb->ShareAccess);
3174 // Return the correct action
3177 if( ulCreateDisposition == FILE_SUPERSEDE)
3180 Irp->IoStatus.Information = FILE_SUPERSEDED;