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;
154 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
155 pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
156 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
157 ulOptions = pIrpSp->Parameters.Create.Options;
158 bNoIntermediateBuffering = BooleanFlagOn( ulOptions, FILE_NO_INTERMEDIATE_BUFFERING);
159 bOpenTargetDirectory = BooleanFlagOn( pIrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
160 pFileObject = pIrpSp->FileObject;
161 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
163 uniFileName.Length = uniFileName.MaximumLength = 0;
164 uniFileName.Buffer = NULL;
166 uniRootFileName.Length = uniRootFileName.MaximumLength = 0;
167 uniRootFileName.Buffer = NULL;
169 uniParsedFileName.Length = uniParsedFileName.MaximumLength = 0;
170 uniParsedFileName.Buffer = NULL;
172 uniSubstitutedPathName.Buffer = NULL;
173 uniSubstitutedPathName.Length = 0;
175 uniRelativeName.Buffer = NULL;
176 uniRelativeName.Length = 0;
178 if( AFSGlobalRoot == NULL)
180 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
183 RtlZeroMemory( &stAuthGroup,
186 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
187 (ULONGLONG)PsGetCurrentThreadId(),
190 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
193 ntStatus = AFSEnumerateGlobalRoot( &stAuthGroup);
195 if( !NT_SUCCESS( ntStatus))
198 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
199 AFS_TRACE_LEVEL_ERROR,
200 "AFSCommonCreate Failed to enumerate global root Status %08lX\n",
203 try_return( ntStatus);
208 // If we are in shutdown mode then fail the request
211 if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
214 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
215 AFS_TRACE_LEVEL_WARNING,
216 "AFSCommonCreate (%08lX) Open request after shutdown\n",
219 try_return( ntStatus = STATUS_TOO_LATE);
223 // Go and parse the name for processing.
224 // If ulParseFlags is returned with AFS_PARSE_FLAG_FREE_FILE_BUFFER set,
225 // then we are responsible for releasing the uniRootFileName.Buffer.
228 ntStatus = AFSParseName( Irp,
238 if( !NT_SUCCESS( ntStatus))
241 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
242 uniFileName.Length > 0 ? AFS_TRACE_LEVEL_ERROR : AFS_TRACE_LEVEL_VERBOSE,
243 "AFSCommonCreate (%08lX) Failed to parse name \"%wZ\" Status %08lX\n",
248 try_return( ntStatus);
252 // Check for STATUS_REPARSE
255 if( ntStatus == STATUS_REPARSE)
259 // Update the information and return
262 Irp->IoStatus.Information = IO_REPARSE;
264 try_return( ntStatus);
268 // If the returned volume cb is NULL then we are dealing with the \\Server\GlobalRoot
272 if( pVolumeCB == NULL)
276 // Remove any leading or trailing slashes
279 if( uniFileName.Length >= sizeof( WCHAR) &&
280 uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
283 uniFileName.Length -= sizeof( WCHAR);
286 if( uniFileName.Length >= sizeof( WCHAR) &&
287 uniFileName.Buffer[ 0] == L'\\')
290 uniFileName.Buffer = &uniFileName.Buffer[ 1];
292 uniFileName.Length -= sizeof( WCHAR);
296 // If there is a remaining portion returned for this request then
297 // check if it is for the PIOCtl interface
300 if( uniFileName.Length > 0)
304 // We don't accept any other opens off of the AFS Root
307 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
310 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
313 if( RtlCompareUnicodeString( &AFSPIOCtlName,
318 ntStatus = AFSOpenIOCtlFcb( Irp,
320 AFSGlobalRoot->DirectoryCB,
324 if( !NT_SUCCESS( ntStatus))
327 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
328 AFS_TRACE_LEVEL_ERROR,
329 "AFSCommonCreate Failed to open root IOCtl Fcb Status %08lX\n",
333 else if( pParentDirectoryCB != NULL &&
334 pParentDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
337 ntStatus = AFSOpenSpecialShareFcb( Irp,
343 if( !NT_SUCCESS( ntStatus))
346 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
347 AFS_TRACE_LEVEL_ERROR,
348 "AFSCommonCreate Failed to open special share Fcb Status %08lX\n",
353 try_return( ntStatus);
356 ntStatus = AFSOpenAFSRoot( Irp,
360 if( !NT_SUCCESS( ntStatus))
363 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
364 AFS_TRACE_LEVEL_ERROR,
365 "AFSCommonCreate Failed to open root Status %08lX\n",
368 lCount = InterlockedDecrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
370 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
371 AFS_TRACE_LEVEL_VERBOSE,
372 "AFSCommonCreate Decrement1 count on &wZ DE %p Ccb %p Cnt %d\n",
373 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
374 AFSGlobalRoot->DirectoryCB,
379 try_return( ntStatus);
383 // We have a reference on the root volume
386 bReleaseVolume = TRUE;
389 // Attempt to locate the node in the name tree if this is not a target
390 // open and the target is not the root
393 uniComponentName.Length = 0;
394 uniComponentName.Buffer = NULL;
396 if( uniFileName.Length > sizeof( WCHAR) ||
397 uniFileName.Buffer[ 0] != L'\\')
400 if( !AFSValidNameFormat( &uniFileName))
403 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
405 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
406 AFS_TRACE_LEVEL_VERBOSE,
407 "AFSCommonCreate (%08lX) Invalid name %wZ Status %08lX\n",
412 try_return( ntStatus);
416 // Opening a reparse point directly?
419 ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
421 if( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
423 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
424 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
425 AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
428 uniSubstitutedPathName = uniRootFileName;
430 ntStatus = AFSLocateNameEntry( &stAuthGroup,
435 ulNameProcessingFlags,
441 if( !NT_SUCCESS( ntStatus) &&
442 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
445 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
447 uniSubstitutedPathName.Buffer = NULL;
451 // The routine above released the root while walking the
455 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
456 AFS_TRACE_LEVEL_VERBOSE,
457 "AFSCommonCreate (%08lX) Failed to locate name entry for %wZ Status %08lX\n",
463 // We released any root volume locks in the above on failure
466 bReleaseVolume = FALSE;
468 try_return( ntStatus);
472 // Check for STATUS_REPARSE
475 if( ntStatus == STATUS_REPARSE)
478 uniSubstitutedPathName.Buffer = NULL;
481 // Update the information and return
484 Irp->IoStatus.Information = IO_REPARSE;
487 // We released the volume lock above
490 bReleaseVolume = FALSE;
492 try_return( ntStatus);
496 // If we re-allocated the name, then update our substitute name
499 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
502 uniSubstitutedPathName = uniRootFileName;
507 uniSubstitutedPathName.Buffer = NULL;
511 // Check for a symlink access
514 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
515 pParentDirectoryCB != NULL)
518 UNICODE_STRING uniFinalComponent;
520 uniFinalComponent.Length = 0;
521 uniFinalComponent.MaximumLength = 0;
522 uniFinalComponent.Buffer = NULL;
524 AFSRetrieveFinalComponent( &uniFileName,
527 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
530 if( !NT_SUCCESS( ntStatus) &&
531 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
534 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
535 AFS_TRACE_LEVEL_VERBOSE,
536 "AFSCommonCreate (%08lX) Failing access to symlink %wZ Status %08lX\n",
541 try_return( ntStatus);
547 // If we have no parent then this is a root open, be sure there is a directory entry
551 else if( pParentDirectoryCB == NULL &&
552 pDirectoryCB == NULL)
555 pDirectoryCB = pVolumeCB->DirectoryCB;
558 if( bOpenTargetDirectory)
562 // If we have a directory cb for the entry then dereference it and reference the parent
565 if( pDirectoryCB != NULL)
569 // Perform in this order to prevent thrashing
572 lCount = InterlockedIncrement( &pParentDirectoryCB->OpenReferenceCount);
574 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
575 AFS_TRACE_LEVEL_VERBOSE,
576 "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
577 &pParentDirectoryCB->NameInformation.FileName,
583 // Do NOT decrement the reference count on the pDirectoryCB yet.
584 // The BackupEntry below might drop the count to zero leaving
585 // the entry subject to being deleted and we need some of the
586 // contents during later processing
589 AFSBackupEntry( pNameArray);
593 // OK, open the target directory
596 if( uniComponentName.Length == 0)
598 AFSRetrieveFinalComponent( &uniFileName,
602 ntStatus = AFSOpenTargetDirectory( Irp,
609 if( pDirectoryCB != NULL)
612 // It is now safe to drop the Reference Count
614 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
616 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
617 AFS_TRACE_LEVEL_VERBOSE,
618 "AFSCommonCreate Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
619 &pDirectoryCB->NameInformation.FileName,
625 if( !NT_SUCCESS( ntStatus))
628 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
629 AFS_TRACE_LEVEL_ERROR,
630 "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
631 &pParentDirectoryCB->NameInformation.FileName,
635 // Decrement the reference on the parent
638 lCount = InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
640 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
641 AFS_TRACE_LEVEL_VERBOSE,
642 "AFSCommonCreate Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
643 &pParentDirectoryCB->NameInformation.FileName,
649 try_return( ntStatus);
652 if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
655 if( pDirectoryCB == NULL ||
656 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
658 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
659 AFS_TRACE_LEVEL_VERBOSE,
660 "AFSCommonCreate (%08lX) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
664 pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0);
668 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
669 AFS_TRACE_LEVEL_VERBOSE,
670 "AFSCommonCreate (%08lX) Opening as reparse point %wZ Type %08lX\n",
673 pDirectoryCB->ObjectInformation->FileType);
675 bOpenedReparsePoint = TRUE;
680 // Based on the options passed in, process the file accordingly.
683 if( ulCreateDisposition == FILE_CREATE ||
684 ( ( ulCreateDisposition == FILE_OPEN_IF ||
685 ulCreateDisposition == FILE_OVERWRITE_IF) &&
686 pDirectoryCB == NULL))
689 if( uniComponentName.Length == 0 ||
690 pDirectoryCB != NULL)
694 // We traversed the entire path so we found each entry,
695 // fail with collision
698 if( pDirectoryCB != NULL)
701 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
702 AFS_TRACE_LEVEL_VERBOSE,
703 "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
704 &pDirectoryCB->NameInformation.FileName,
707 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
709 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
710 AFS_TRACE_LEVEL_VERBOSE,
711 "AFSCommonCreate Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
712 &pDirectoryCB->NameInformation.FileName,
720 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
721 AFS_TRACE_LEVEL_VERBOSE,
722 "AFSCommonCreate Object name collision on create Status %08lX\n",
725 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
727 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
728 AFS_TRACE_LEVEL_VERBOSE,
729 "AFSCommonCreate Decrement5 count on %wZ DE %p Ccb %p Cnt %d\n",
730 &pParentDirectoryCB->NameInformation.FileName,
733 pParentDirectoryCB->OpenReferenceCount);
736 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
740 // OK, go and create the node
743 ntStatus = AFSProcessCreate( Irp,
753 if( !NT_SUCCESS( ntStatus))
756 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
757 AFS_TRACE_LEVEL_ERROR,
758 "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
760 &pParentDirectoryCB->NameInformation.FileName,
765 // Dereference the parent entry
768 lCount = InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
770 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
771 AFS_TRACE_LEVEL_VERBOSE,
772 "AFSCreate Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
773 &pParentDirectoryCB->NameInformation.FileName,
778 try_return( ntStatus);
782 // We should not have an extra component except for PIOCtl opens
785 if( uniComponentName.Length > 0)
789 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
792 if( RtlCompareUnicodeString( &AFSPIOCtlName,
797 ntStatus = AFSOpenIOCtlFcb( Irp,
803 if( !NT_SUCCESS( ntStatus))
806 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
807 AFS_TRACE_LEVEL_ERROR,
808 "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
816 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
817 AFS_TRACE_LEVEL_VERBOSE,
818 "AFSCommonCreate (%08lX) File %wZ name not found\n",
822 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
825 if( !NT_SUCCESS( ntStatus))
829 // Dereference the parent entry
832 if( pDirectoryCB != NULL)
835 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
837 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
838 AFS_TRACE_LEVEL_VERBOSE,
839 "AFSCommonCreate Decrement7a count on %wZ DE %p Ccb %p Cnt %d\n",
840 &pDirectoryCB->NameInformation.FileName,
848 lCount = InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
850 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
851 AFS_TRACE_LEVEL_VERBOSE,
852 "AFSCommonCreate Decrement7b count on %wZ DE %p Ccb %p Cnt %d\n",
853 &pParentDirectoryCB->NameInformation.FileName,
860 try_return( ntStatus);
864 // For root opens the parent will be NULL
867 if( pParentDirectoryCB == NULL)
871 // Check for the delete on close flag for the root
874 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
877 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
878 AFS_TRACE_LEVEL_ERROR,
879 "AFSCommonCreate (%08lX) Attempt to open root as delete on close\n",
882 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
884 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
885 AFS_TRACE_LEVEL_VERBOSE,
886 "AFSCommonCreate Decrement8 count on %wZ DE %p Ccb %p Cnt %d\n",
887 &pDirectoryCB->NameInformation.FileName,
892 try_return( ntStatus = STATUS_CANNOT_DELETE);
896 // If this is the target directory, then bail
899 if( bOpenTargetDirectory)
902 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
903 AFS_TRACE_LEVEL_ERROR,
904 "AFSCommonCreate (%08lX) Attempt to open root as target directory\n",
907 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
909 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
910 AFS_TRACE_LEVEL_VERBOSE,
911 "AFSCommonCreate Decrement9 count on %wZ DE %p Ccb %p Cnt %d\n",
912 &pDirectoryCB->NameInformation.FileName,
917 try_return( ntStatus = STATUS_INVALID_PARAMETER);
921 // Go and open the root of the volume
924 ntStatus = AFSOpenRoot( Irp,
930 if( !NT_SUCCESS( ntStatus))
933 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
934 AFS_TRACE_LEVEL_ERROR,
935 "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
936 pVolumeCB->ObjectInformation.FileId.Cell,
937 pVolumeCB->ObjectInformation.FileId.Volume,
940 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
942 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
943 AFS_TRACE_LEVEL_VERBOSE,
944 "AFSCommonCreate Decrement10 count on %wZ DE %p Ccb %p Cnt %d\n",
945 &pDirectoryCB->NameInformation.FileName,
951 try_return( ntStatus);
955 // At this point if we have no pDirectoryCB it was not found.
958 if( pDirectoryCB == NULL)
961 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
962 AFS_TRACE_LEVEL_ERROR,
963 "AFSCommonCreate Failing access to %wZ\n",
966 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
969 if( ulCreateDisposition == FILE_OVERWRITE ||
970 ulCreateDisposition == FILE_SUPERSEDE ||
971 ulCreateDisposition == FILE_OVERWRITE_IF)
975 // Go process a file for overwrite or supersede.
978 ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
987 if( !NT_SUCCESS( ntStatus))
990 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
991 AFS_TRACE_LEVEL_ERROR,
992 "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
993 &pDirectoryCB->NameInformation.FileName,
996 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
998 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
999 AFS_TRACE_LEVEL_VERBOSE,
1000 "AFSCommonCreate Decrement11 count on %wZ DE %p Ccb %p Cnt %d\n",
1001 &pDirectoryCB->NameInformation.FileName,
1007 try_return( ntStatus);
1011 // Trying to open the file
1014 ntStatus = AFSProcessOpen( Irp,
1022 if( !NT_SUCCESS( ntStatus))
1025 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1026 AFS_TRACE_LEVEL_ERROR,
1027 "AFSCommonCreate Failed open on %wZ Status %08lX\n",
1028 &pDirectoryCB->NameInformation.FileName,
1031 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
1033 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1034 AFS_TRACE_LEVEL_VERBOSE,
1035 "AFSCommonCreate Decrement12 count on %wZ DE %p Ccb %p Cnt %d\n",
1036 &pDirectoryCB->NameInformation.FileName,
1044 if( NT_SUCCESS( ntStatus) &&
1045 ntStatus != STATUS_REPARSE)
1051 RtlCopyMemory( &pCcb->AuthGroup,
1056 // If we have a substitute name, then use it
1059 if( uniSubstitutedPathName.Buffer != NULL)
1062 pCcb->FullFileName = uniSubstitutedPathName;
1064 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1066 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1071 pCcb->FullFileName = uniRootFileName;
1073 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1076 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1078 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1082 if( bOpenedReparsePoint)
1084 SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1087 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1088 AFS_TRACE_LEVEL_VERBOSE,
1089 "AFSCommonCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1090 &pCcb->DirectoryCB->NameInformation.FileName,
1093 pCcb->DirectoryCB->OpenReferenceCount);
1095 ASSERT( pCcb->DirectoryCB->OpenReferenceCount > 0);
1097 pCcb->CurrentDirIndex = 0;
1099 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1102 SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1106 // Save off the name array for this instance
1109 pCcb->NameArray = pNameArray;
1115 // If we make it here then init the FO for the request.
1118 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1119 AFS_TRACE_LEVEL_VERBOSE_2,
1120 "AFSCommonCreate (%08lX) FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1126 pFileObject->FsContext = (void *)pFcb;
1128 pFileObject->FsContext2 = (void *)pCcb;
1133 ASSERT( pFcb->OpenHandleCount > 0);
1135 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1138 // For files perform additional processing
1141 if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
1143 pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1147 // If the user did not request nobuffering then mark the FO as cacheable
1150 if( bNoIntermediateBuffering)
1153 pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1158 pFileObject->Flags |= FO_CACHE_SUPPORTED;
1162 // If the file was opened for execution then we need to set the bit in the FO
1165 if( BooleanFlagOn( *pDesiredAccess,
1169 SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1173 // Update the last access time
1176 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1187 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1188 AFS_TRACE_LEVEL_ERROR,
1189 "AFSCommonCreate (%08lX) Returning with NULL Fcb FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1198 if( NT_SUCCESS( ntStatus) &&
1199 ntStatus == STATUS_REPARSE)
1202 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1203 AFS_TRACE_LEVEL_ERROR,
1204 "AFSCommonCreate (%08lX) STATUS_REPARSE FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1212 // Free up the sub name if we have one
1215 if( uniSubstitutedPathName.Buffer != NULL)
1218 AFSExFreePool( uniSubstitutedPathName.Buffer);
1220 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1225 // Free up the name array ...
1228 if( pNameArray != NULL)
1231 AFSFreeNameArray( pNameArray);
1234 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1237 AFSExFreePool( uniRootFileName.Buffer);
1243 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1245 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1246 AFS_TRACE_LEVEL_VERBOSE,
1247 "AFSCommonCreate Decrement count on Volume %08lX Cnt %d\n",
1253 // Setup the Irp for completion, the Information has been set previously
1256 Irp->IoStatus.Status = ntStatus;
1263 AFSOpenRedirector( IN PIRP Irp,
1268 NTSTATUS ntStatus = STATUS_SUCCESS;
1275 // Initialize the Ccb for the file.
1278 ntStatus = AFSInitCcb( Ccb);
1280 if( !NT_SUCCESS( ntStatus))
1283 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1284 AFS_TRACE_LEVEL_ERROR,
1285 "AFSOpenRedirector (%08lX) Failed to allocate Ccb\n",
1288 try_return( ntStatus);
1295 (*Ccb)->DirectoryCB = AFSRedirectorRoot->DirectoryCB;
1298 // Increment the open count on this Fcb
1301 lCount = InterlockedIncrement( &AFSRedirectorRoot->RootFcb->OpenReferenceCount);
1303 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1304 AFS_TRACE_LEVEL_VERBOSE,
1305 "AFSOpenRedirector Increment count on Fcb %08lX Cnt %d\n",
1306 AFSRedirectorRoot->RootFcb,
1309 lCount = InterlockedIncrement( &AFSRedirectorRoot->RootFcb->OpenHandleCount);
1311 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1312 AFS_TRACE_LEVEL_VERBOSE,
1313 "AFSOpenRedirector Increment handle count on Fcb %08lX Cnt %d\n",
1314 AFSRedirectorRoot->RootFcb,
1317 *Fcb = AFSRedirectorRoot->RootFcb;
1319 lCount = InterlockedIncrement( &(*Ccb)->DirectoryCB->OpenReferenceCount);
1322 // Return the open result for this file
1325 Irp->IoStatus.Information = FILE_OPENED;
1336 AFSOpenAFSRoot( IN PIRP Irp,
1341 NTSTATUS ntStatus = STATUS_SUCCESS;
1348 // Initialize the Ccb for the file.
1351 ntStatus = AFSInitCcb( Ccb);
1353 if( !NT_SUCCESS( ntStatus))
1356 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1357 AFS_TRACE_LEVEL_ERROR,
1358 "AFSOpenAFSRoot (%08lX) Failed to allocate Ccb\n",
1361 try_return( ntStatus);
1368 (*Ccb)->DirectoryCB = AFSGlobalRoot->DirectoryCB;
1371 // Increment the open count on this Fcb
1374 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1376 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1377 AFS_TRACE_LEVEL_VERBOSE,
1378 "AFSOpenAFSRoot Increment count on Fcb %08lX Cnt %d\n",
1379 AFSGlobalRoot->RootFcb,
1382 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1384 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1385 AFS_TRACE_LEVEL_VERBOSE,
1386 "AFSOpenAFSRoot Increment handle count on Fcb %08lX Cnt %d\n",
1387 AFSGlobalRoot->RootFcb,
1390 *Fcb = AFSGlobalRoot->RootFcb;
1393 // Return the open result for this file
1396 Irp->IoStatus.Information = FILE_OPENED;
1407 AFSOpenRoot( IN PIRP Irp,
1408 IN AFSVolumeCB *VolumeCB,
1410 OUT AFSFcb **RootFcb,
1414 NTSTATUS ntStatus = STATUS_SUCCESS;
1415 PFILE_OBJECT pFileObject = NULL;
1416 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1417 PACCESS_MASK pDesiredAccess = NULL;
1418 USHORT usShareAccess;
1420 BOOLEAN bAllocatedCcb = FALSE;
1421 BOOLEAN bReleaseFcb = FALSE;
1422 AFSFileOpenCB stOpenCB;
1423 AFSFileOpenResultCB stOpenResultCB;
1424 ULONG ulResultLen = 0;
1430 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1431 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1432 ulOptions = pIrpSp->Parameters.Create.Options;
1434 pFileObject = pIrpSp->FileObject;
1436 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1439 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1441 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1442 AFS_TRACE_LEVEL_ERROR,
1443 "AFSOpenRoot (%08lX) Attempt to open root as file Status %08lX\n",
1447 try_return( ntStatus);
1451 // Check if we should go and retrieve updated information for the node
1454 ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1459 if( !NT_SUCCESS( ntStatus))
1462 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1463 AFS_TRACE_LEVEL_ERROR,
1464 "AFSOpenRoot (%08lX) Failed to validate root entry Status %08lX\n",
1468 try_return( ntStatus);
1472 // Check with the service that we can open the file
1475 RtlZeroMemory( &stOpenCB,
1476 sizeof( AFSFileOpenCB));
1478 stOpenCB.DesiredAccess = *pDesiredAccess;
1480 stOpenCB.ShareAccess = usShareAccess;
1482 stOpenResultCB.GrantedAccess = 0;
1484 ulResultLen = sizeof( AFSFileOpenResultCB);
1486 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1487 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1490 &VolumeCB->ObjectInformation.FileId,
1492 sizeof( AFSFileOpenCB),
1493 (void *)&stOpenResultCB,
1496 if( !NT_SUCCESS( ntStatus))
1499 UNICODE_STRING uniGUID;
1502 uniGUID.MaximumLength = 0;
1503 uniGUID.Buffer = NULL;
1505 if( AuthGroup != NULL)
1507 RtlStringFromGUID( *AuthGroup,
1511 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1512 AFS_TRACE_LEVEL_ERROR,
1513 "AFSOpenRoot (%08lX) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1515 VolumeCB->ObjectInformation.FileId.Cell,
1516 VolumeCB->ObjectInformation.FileId.Volume,
1520 if( AuthGroup != NULL)
1522 RtlFreeUnicodeString( &uniGUID);
1525 try_return( ntStatus);
1529 // If the entry is not initialized then do it now
1532 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1535 AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1538 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1541 ntStatus = AFSEnumerateDirectory( AuthGroup,
1542 &VolumeCB->ObjectInformation,
1545 if( !NT_SUCCESS( ntStatus))
1548 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1550 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1551 AFS_TRACE_LEVEL_ERROR,
1552 "AFSOpenRoot (%08lX) Failed to enumerate directory Status %08lX\n",
1556 try_return( ntStatus);
1559 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1562 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1566 // If the root fcb has been initialized then check access otherwise
1567 // init the volume fcb
1570 if( VolumeCB->RootFcb == NULL)
1573 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1576 if( !NT_SUCCESS( ntStatus))
1579 try_return( ntStatus);
1585 AFSAcquireExcl( VolumeCB->RootFcb->Header.Resource,
1592 // If there are current opens on the Fcb, check the access.
1595 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1598 ntStatus = IoCheckShareAccess( *pDesiredAccess,
1601 &VolumeCB->RootFcb->ShareAccess,
1604 if( !NT_SUCCESS( ntStatus))
1607 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1608 AFS_TRACE_LEVEL_ERROR,
1609 "AFSOpenRoot (%08lX) Access check failure Status %08lX\n",
1613 try_return( ntStatus);
1618 // Initialize the Ccb for the file.
1621 ntStatus = AFSInitCcb( Ccb);
1623 if( !NT_SUCCESS( ntStatus))
1626 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1627 AFS_TRACE_LEVEL_ERROR,
1628 "AFSOpenRoot (%08lX) Failed to allocate Ccb Status %08lX\n",
1632 try_return( ntStatus);
1635 bAllocatedCcb = TRUE;
1641 (*Ccb)->DirectoryCB = VolumeCB->DirectoryCB;
1643 (*Ccb)->GrantedAccess = *pDesiredAccess;
1646 // OK, update the share access on the fileobject
1649 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1652 IoUpdateShareAccess( pFileObject,
1653 &VolumeCB->RootFcb->ShareAccess);
1662 IoSetShareAccess( *pDesiredAccess,
1665 &VolumeCB->RootFcb->ShareAccess);
1669 // Increment the open count on this Fcb
1672 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1674 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1675 AFS_TRACE_LEVEL_VERBOSE,
1676 "AFSOpenRoot Increment count on Fcb %08lX Cnt %d\n",
1680 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1682 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1683 AFS_TRACE_LEVEL_VERBOSE,
1684 "AFSOpenRoot Increment handle count on Fcb %08lX Cnt %d\n",
1689 // Indicate the object is held
1692 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1695 // Return the open result for this file
1698 Irp->IoStatus.Information = FILE_OPENED;
1700 *RootFcb = VolumeCB->RootFcb;
1707 AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1710 if( !NT_SUCCESS( ntStatus))
1722 Irp->IoStatus.Information = 0;
1730 AFSProcessCreate( IN PIRP Irp,
1732 IN AFSVolumeCB *VolumeCB,
1733 IN AFSDirectoryCB *ParentDirCB,
1734 IN PUNICODE_STRING FileName,
1735 IN PUNICODE_STRING ComponentName,
1736 IN PUNICODE_STRING FullFileName,
1741 NTSTATUS ntStatus = STATUS_SUCCESS;
1742 PFILE_OBJECT pFileObject = NULL;
1743 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1744 ULONG ulOptions = 0;
1745 ULONG ulShareMode = 0;
1747 ULONG ulAttributes = 0;
1748 LARGE_INTEGER liAllocationSize = {0,0};
1749 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1750 BOOLEAN bAllocatedFcb = FALSE;
1751 PACCESS_MASK pDesiredAccess = NULL;
1752 USHORT usShareAccess;
1753 AFSDirectoryCB *pDirEntry = NULL;
1754 AFSObjectInfoCB *pParentObjectInfo = NULL;
1755 AFSObjectInfoCB *pObjectInfo = NULL;
1761 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1762 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1764 pFileObject = pIrpSp->FileObject;
1767 // Extract out the options
1770 ulOptions = pIrpSp->Parameters.Create.Options;
1773 // We pass all attributes they want to apply to the file to the create
1776 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1779 // If this is a directory create then set the attribute correctly
1782 if( ulOptions & FILE_DIRECTORY_FILE)
1785 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1788 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1789 AFS_TRACE_LEVEL_VERBOSE,
1790 "AFSProcessCreate (%08lX) Creating file %wZ Attributes %08lX\n",
1795 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1798 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1799 AFS_TRACE_LEVEL_ERROR,
1800 "AFSProcessCreate Request failed due to read only volume %wZ\n",
1803 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
1806 pParentObjectInfo = ParentDirCB->ObjectInformation;
1809 // Allocate and insert the direntry into the parent node
1812 ntStatus = AFSCreateDirEntry( AuthGroup,
1820 if( !NT_SUCCESS( ntStatus))
1823 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1824 AFS_TRACE_LEVEL_ERROR,
1825 "AFSProcessCreate (%08lX) Failed to create directory entry %wZ Status %08lX\n",
1830 try_return( ntStatus);
1833 bFileCreated = TRUE;
1835 pObjectInfo = pDirEntry->ObjectInformation;
1837 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1838 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1841 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1842 AFS_TRACE_LEVEL_VERBOSE,
1843 "AFSProcessCreate (%08lX) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1845 &pDirEntry->NameInformation.FileName,
1846 pObjectInfo->FileId.Cell,
1847 pObjectInfo->FileId.Volume,
1848 pObjectInfo->FileId.Vnode,
1849 pObjectInfo->FileId.Unique);
1851 ntStatus = AFSEvaluateNode( AuthGroup,
1854 if( !NT_SUCCESS( ntStatus))
1857 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1858 AFS_TRACE_LEVEL_ERROR,
1859 "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1861 &pDirEntry->NameInformation.FileName,
1862 pObjectInfo->FileId.Cell,
1863 pObjectInfo->FileId.Volume,
1864 pObjectInfo->FileId.Vnode,
1865 pObjectInfo->FileId.Unique,
1868 try_return( ntStatus);
1871 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1875 // We may have raced and the Fcb is already created
1878 if( pObjectInfo->Fcb != NULL)
1881 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1882 AFS_TRACE_LEVEL_VERBOSE,
1883 "AFSProcessCreate (%08lX) Not allocating Fcb for file %wZ\n",
1887 *Fcb = pObjectInfo->Fcb;
1889 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
1896 // Allocate and initialize the Fcb for the file.
1899 ntStatus = AFSInitFcb( pDirEntry);
1901 *Fcb = pObjectInfo->Fcb;
1903 if( !NT_SUCCESS( ntStatus) &&
1904 ntStatus != STATUS_REPARSE)
1907 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1908 AFS_TRACE_LEVEL_ERROR,
1909 "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
1914 try_return( ntStatus);
1917 if ( ntStatus != STATUS_REPARSE)
1920 bAllocatedFcb = TRUE;
1923 ntStatus = STATUS_SUCCESS;
1929 // Initialize the Ccb for the file.
1932 ntStatus = AFSInitCcb( Ccb);
1934 if( !NT_SUCCESS( ntStatus))
1937 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1938 AFS_TRACE_LEVEL_ERROR,
1939 "AFSProcessCreate (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
1944 try_return( ntStatus);
1947 bAllocatedCcb = TRUE;
1950 // Initialize the Ccb
1953 (*Ccb)->DirectoryCB = pDirEntry;
1955 (*Ccb)->GrantedAccess = *pDesiredAccess;
1958 // If this is a file, update the headers filesizes.
1961 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1965 // Update the sizes with the information passed in
1968 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
1969 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1970 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1973 // Notify the system of the addition
1976 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1978 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1979 (ULONG)FILE_ACTION_ADDED);
1981 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
1983 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1987 // This is a new directory node so indicate it has been enumerated
1990 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1993 // And the parent directory entry
1996 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1999 // Notify the system of the addition
2002 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2004 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2005 (ULONG)FILE_ACTION_ADDED);
2007 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2008 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2009 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2010 (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
2014 // And the parent directory entry
2017 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2020 // Notify the system of the addition
2023 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2025 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2026 (ULONG)FILE_ACTION_ADDED);
2030 // Save off the access for the open
2033 IoSetShareAccess( *pDesiredAccess,
2036 &(*Fcb)->ShareAccess);
2039 // Increment the open count on this Fcb
2042 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
2044 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2045 AFS_TRACE_LEVEL_VERBOSE,
2046 "AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n",
2050 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2052 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2053 AFS_TRACE_LEVEL_VERBOSE,
2054 "AFSProcessCreate Increment handle count on Fcb %08lX Cnt %d\n",
2059 // Increment the open reference and handle on the parent node
2062 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2064 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2065 AFS_TRACE_LEVEL_VERBOSE,
2066 "AFSProcessCreate Increment child open handle count on Parent object %08lX Cnt %d\n",
2067 pObjectInfo->ParentObjectInformation,
2070 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2072 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2073 AFS_TRACE_LEVEL_VERBOSE,
2074 "AFSProcessCreate Increment child open ref count on Parent object %08lX Cnt %d\n",
2075 pObjectInfo->ParentObjectInformation,
2078 if( ulOptions & FILE_DELETE_ON_CLOSE)
2082 // Mark it for delete on close
2085 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2086 AFS_TRACE_LEVEL_VERBOSE,
2087 "AFSProcessCreate (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2092 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2096 // Indicate the object is locked in the service
2099 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2102 // Return the open result for this file
2105 Irp->IoStatus.Information = FILE_CREATED;
2110 // If we created the Fcb we need to release the resources
2116 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2119 if( !NT_SUCCESS( ntStatus))
2125 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2126 AFS_TRACE_LEVEL_VERBOSE,
2127 "AFSProcessCreate Create failed, removing DE %p from aprent object %p Status %08lX\n",
2133 // Remove the dir entry from the parent
2136 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2139 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2141 AFSNotifyDelete( pDirEntry,
2146 // Decrement the reference added during initialization of the DE
2149 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
2151 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2152 AFS_TRACE_LEVEL_VERBOSE,
2153 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2154 &pDirEntry->NameInformation.FileName,
2159 // Pull the directory entry from the parent
2162 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2164 FALSE); // Leave it in the enum list so the worker cleans it up
2167 // Tag the parent as needing verification
2170 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2172 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2174 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2187 AFSRemoveFcb( pObjectInfo->Fcb);
2189 pObjectInfo->Fcb = NULL;
2202 AFSOpenTargetDirectory( IN PIRP Irp,
2203 IN AFSVolumeCB *VolumeCB,
2204 IN AFSDirectoryCB *ParentDirectoryCB,
2205 IN AFSDirectoryCB *TargetDirectoryCB,
2206 IN UNICODE_STRING *TargetName,
2211 NTSTATUS ntStatus = STATUS_SUCCESS;
2212 PFILE_OBJECT pFileObject = NULL;
2213 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2214 PACCESS_MASK pDesiredAccess = NULL;
2215 USHORT usShareAccess;
2216 BOOLEAN bAllocatedCcb = FALSE;
2217 BOOLEAN bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2218 AFSObjectInfoCB *pParentObject = NULL, *pTargetObject = NULL;
2219 UNICODE_STRING uniTargetName;
2225 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2226 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2228 pFileObject = pIrpSp->FileObject;
2230 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2231 AFS_TRACE_LEVEL_VERBOSE,
2232 "AFSOpenTargetDirectory (%08lX) Processing file %wZ\n",
2236 pParentObject = ParentDirectoryCB->ObjectInformation;
2238 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2241 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2245 // Make sure we have an Fcb for the access
2248 if( pParentObject->Fcb != NULL)
2251 *Fcb = pParentObject->Fcb;
2253 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
2260 // Allocate and initialize the Fcb for the file.
2263 ntStatus = AFSInitFcb( ParentDirectoryCB);
2265 *Fcb = pParentObject->Fcb;
2267 if( !NT_SUCCESS( ntStatus) &&
2268 ntStatus != STATUS_REPARSE)
2271 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2272 AFS_TRACE_LEVEL_ERROR,
2273 "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
2275 &ParentDirectoryCB->NameInformation.FileName,
2278 try_return( ntStatus);
2281 if ( ntStatus == STATUS_REPARSE)
2284 bAllocatedFcb = TRUE;
2287 ntStatus = STATUS_SUCCESS;
2293 // If there are current opens on the Fcb, check the access.
2296 if( pParentObject->Fcb->OpenHandleCount > 0)
2299 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2302 &pParentObject->Fcb->ShareAccess,
2305 if( !NT_SUCCESS( ntStatus))
2308 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2309 AFS_TRACE_LEVEL_ERROR,
2310 "AFSOpenTargetDirectory (%08lX) Access check failure %wZ Status %08lX\n",
2312 &ParentDirectoryCB->NameInformation.FileName,
2315 try_return( ntStatus);
2320 // Initialize the Ccb for the file.
2323 ntStatus = AFSInitCcb( Ccb);
2325 if( !NT_SUCCESS( ntStatus))
2328 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2329 AFS_TRACE_LEVEL_ERROR,
2330 "AFSOpenTargetDirectory (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2332 &ParentDirectoryCB->NameInformation.FileName,
2335 try_return( ntStatus);
2338 bAllocatedCcb = TRUE;
2341 // Initialize the Ccb
2344 (*Ccb)->DirectoryCB = ParentDirectoryCB;
2346 (*Ccb)->GrantedAccess = *pDesiredAccess;
2348 if( TargetDirectoryCB != NULL &&
2349 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2355 Irp->IoStatus.Information = FILE_EXISTS;
2357 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2362 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2364 uniTargetName = *TargetName;
2368 // Update the filename in the fileobject for rename processing
2371 RtlCopyMemory( pFileObject->FileName.Buffer,
2372 uniTargetName.Buffer,
2373 uniTargetName.Length);
2375 pFileObject->FileName.Length = uniTargetName.Length;
2378 // OK, update the share access on the fileobject
2381 if( pParentObject->Fcb->OpenHandleCount > 0)
2384 IoUpdateShareAccess( pFileObject,
2385 &pParentObject->Fcb->ShareAccess);
2394 IoSetShareAccess( *pDesiredAccess,
2397 &pParentObject->Fcb->ShareAccess);
2401 // Increment the open count on this Fcb
2404 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2406 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2407 AFS_TRACE_LEVEL_VERBOSE,
2408 "AFSOpenTargetDirectory Increment count on Fcb %08lX Cnt %d\n",
2412 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2414 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2415 AFS_TRACE_LEVEL_VERBOSE,
2416 "AFSOpenTargetDirectory Increment handle count on Fcb %08lX Cnt %d\n",
2421 // Increment the open reference and handle on the parent node
2424 if( pParentObject->ParentObjectInformation != NULL)
2427 lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2429 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2430 AFS_TRACE_LEVEL_VERBOSE,
2431 "AFSOpenTargetDirectory Increment child open handle count on Parent object %08lX Cnt %d\n",
2432 pParentObject->ParentObjectInformation,
2435 lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2437 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2438 AFS_TRACE_LEVEL_VERBOSE,
2439 "AFSOpenTargetDirectory Increment child open ref count on Parent object %08lX Cnt %d\n",
2440 pParentObject->ParentObjectInformation,
2449 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2452 if( !NT_SUCCESS( ntStatus))
2467 AFSRemoveFcb( pParentObject->Fcb);
2469 pParentObject->Fcb = NULL;
2480 AFSProcessOpen( IN PIRP Irp,
2482 IN AFSVolumeCB *VolumeCB,
2483 IN AFSDirectoryCB *ParentDirCB,
2484 IN AFSDirectoryCB *DirectoryCB,
2489 NTSTATUS ntStatus = STATUS_SUCCESS;
2490 PFILE_OBJECT pFileObject = NULL;
2491 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2492 PACCESS_MASK pDesiredAccess = NULL;
2493 USHORT usShareAccess;
2494 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2495 ULONG ulAdditionalFlags = 0, ulOptions = 0;
2496 AFSFileOpenCB stOpenCB;
2497 AFSFileOpenResultCB stOpenResultCB;
2498 ULONG ulResultLen = 0;
2499 AFSObjectInfoCB *pParentObjectInfo = NULL;
2500 AFSObjectInfoCB *pObjectInfo = NULL;
2501 ULONG ulFileAccess = 0;
2502 AFSFileAccessReleaseCB stReleaseFileAccess;
2508 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2509 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2511 pFileObject = pIrpSp->FileObject;
2513 pParentObjectInfo = ParentDirCB->ObjectInformation;
2515 pObjectInfo = DirectoryCB->ObjectInformation;
2518 // Check if the entry is pending a deletion
2521 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2524 ntStatus = STATUS_DELETE_PENDING;
2526 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2527 AFS_TRACE_LEVEL_ERROR,
2528 "AFSProcessOpen (%08lX) Entry pending delete %wZ Status %08lX\n",
2530 &DirectoryCB->NameInformation.FileName,
2533 try_return( ntStatus);
2537 // Extract out the options
2540 ulOptions = pIrpSp->Parameters.Create.Options;
2543 // Check if we should go and retrieve updated information for the node
2546 ntStatus = AFSValidateEntry( DirectoryCB,
2551 if( !NT_SUCCESS( ntStatus))
2554 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2555 AFS_TRACE_LEVEL_ERROR,
2556 "AFSProcessOpen (%08lX) Failed to validate entry %wZ Status %08lX\n",
2558 &DirectoryCB->NameInformation.FileName,
2561 try_return( ntStatus);
2565 // If this is marked for delete on close then be sure we can delete the entry
2568 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2571 ntStatus = AFSNotifyDelete( DirectoryCB,
2575 if( !NT_SUCCESS( ntStatus))
2578 ntStatus = STATUS_CANNOT_DELETE;
2580 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2581 AFS_TRACE_LEVEL_ERROR,
2582 "AFSProcessOpen (%08lX) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2584 &DirectoryCB->NameInformation.FileName,
2587 try_return( ntStatus);
2592 // Be sure we have an Fcb for the current object
2595 if( pObjectInfo->Fcb == NULL)
2598 ntStatus = AFSInitFcb( DirectoryCB);
2600 if( !NT_SUCCESS( ntStatus) &&
2601 ntStatus != STATUS_REPARSE)
2604 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2605 AFS_TRACE_LEVEL_ERROR,
2606 "AFSProcessOpen (%08lX) Failed to init fcb on %wZ Status %08lX\n",
2608 &DirectoryCB->NameInformation.FileName,
2611 try_return( ntStatus);
2614 if ( ntStatus != STATUS_REPARSE)
2617 bAllocatedFcb = TRUE;
2620 ntStatus = STATUS_SUCCESS;
2625 AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
2632 // Reference the Fcb so it won't go away while we call into the service for processing
2635 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2637 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2638 AFS_TRACE_LEVEL_VERBOSE,
2639 "AFSProcessOpen Increment count on Fcb %08lX Cnt %d\n",
2644 // Check access on the entry
2647 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2650 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2653 &pObjectInfo->Fcb->ShareAccess,
2656 if( !NT_SUCCESS( ntStatus))
2659 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2660 AFS_TRACE_LEVEL_ERROR,
2661 "AFSProcessOpen (%08lX) Failed to check share access on %wZ Status %08lX\n",
2663 &DirectoryCB->NameInformation.FileName,
2666 try_return( ntStatus);
2671 // Additional checks
2674 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2678 // If the caller is asking for write access then try to flush the image section
2681 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2682 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2685 if( !MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2689 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2690 STATUS_SHARING_VIOLATION;
2692 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2693 AFS_TRACE_LEVEL_ERROR,
2694 "AFSProcessOpen (%08lX) Failed to flush image section %wZ Status %08lX\n",
2696 &DirectoryCB->NameInformation.FileName,
2699 try_return( ntStatus);
2703 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2706 ntStatus = STATUS_NOT_A_DIRECTORY;
2708 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2709 AFS_TRACE_LEVEL_ERROR,
2710 "AFSProcessOpen (%08lX) Attempt to open file as directory %wZ Status %08lX\n",
2712 &DirectoryCB->NameInformation.FileName,
2715 try_return( ntStatus);
2718 pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2720 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2721 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2724 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2727 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2729 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2730 AFS_TRACE_LEVEL_ERROR,
2731 "AFSProcessOpen (%08lX) Attempt to open directory as file %wZ Status %08lX\n",
2733 &DirectoryCB->NameInformation.FileName,
2736 try_return( ntStatus);
2739 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2740 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2741 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2742 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2749 try_return( ntStatus = STATUS_UNSUCCESSFUL);
2753 // Check with the service that we can open the file
2756 stOpenCB.ParentId = pParentObjectInfo->FileId;
2758 stOpenCB.DesiredAccess = *pDesiredAccess;
2760 stOpenCB.ShareAccess = usShareAccess;
2762 stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2764 stOpenCB.Identifier = (ULONGLONG)pFileObject;
2766 stOpenResultCB.GrantedAccess = 0;
2768 ulResultLen = sizeof( AFSFileOpenResultCB);
2770 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2771 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2773 &DirectoryCB->NameInformation.FileName,
2774 &pObjectInfo->FileId,
2776 sizeof( AFSFileOpenCB),
2777 (void *)&stOpenResultCB,
2780 if( !NT_SUCCESS( ntStatus))
2783 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2784 AFS_TRACE_LEVEL_ERROR,
2785 "AFSProcessOpen (%08lX) Failed open in service %wZ Status %08lX\n",
2787 &DirectoryCB->NameInformation.FileName,
2790 try_return( ntStatus);
2794 // Save the granted access in case we need to release it below
2797 ulFileAccess = stOpenResultCB.FileAccess;
2800 // Check if there is a conflict
2803 if( !AFSCheckAccess( *pDesiredAccess,
2804 stOpenResultCB.GrantedAccess,
2805 BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2808 ntStatus = STATUS_ACCESS_DENIED;
2810 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2811 AFS_TRACE_LEVEL_ERROR,
2812 "AFSProcessOpen (%08lX) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2815 stOpenResultCB.GrantedAccess,
2816 &DirectoryCB->NameInformation.FileName,
2819 try_return( ntStatus);
2823 // Initialize the Ccb for the file.
2826 ntStatus = AFSInitCcb( Ccb);
2828 if( !NT_SUCCESS( ntStatus))
2831 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2832 AFS_TRACE_LEVEL_ERROR,
2833 "AFSProcessOpen (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2835 &DirectoryCB->NameInformation.FileName,
2838 try_return( ntStatus);
2841 bAllocatedCcb = TRUE;
2843 (*Ccb)->DirectoryCB = DirectoryCB;
2845 (*Ccb)->FileAccess = ulFileAccess;
2847 (*Ccb)->GrantedAccess = *pDesiredAccess;
2850 // Perform the access check on the target if this is a mount point or symlink
2853 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2856 IoUpdateShareAccess( pFileObject,
2857 &pObjectInfo->Fcb->ShareAccess);
2866 IoSetShareAccess( *pDesiredAccess,
2869 &pObjectInfo->Fcb->ShareAccess);
2873 // Increment the open count on this Fcb
2876 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2878 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2879 AFS_TRACE_LEVEL_VERBOSE,
2880 "AFSProcessOpen Increment2 count on Fcb %08lX Cnt %d\n",
2884 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2886 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2887 AFS_TRACE_LEVEL_VERBOSE,
2888 "AFSProcessOpen Increment handle count on Fcb %08lX Cnt %d\n",
2893 // Increment the open reference and handle on the parent node
2896 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2898 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2899 AFS_TRACE_LEVEL_VERBOSE,
2900 "AFSProcessOpen Increment child open handle count on Parent object %08lX Cnt %d\n",
2901 pObjectInfo->ParentObjectInformation,
2904 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2906 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2907 AFS_TRACE_LEVEL_VERBOSE,
2908 "AFSProcessOpen Increment child open ref count on Parent object %08lX Cnt %d\n",
2909 pObjectInfo->ParentObjectInformation,
2912 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2916 // Mark it for delete on close
2919 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2920 AFS_TRACE_LEVEL_VERBOSE,
2921 "AFSProcessOpen (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2924 &DirectoryCB->NameInformation.FileName);
2926 SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2930 // Indicate the object is held
2933 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2936 // Return the open result for this file
2939 Irp->IoStatus.Information = FILE_OPENED;
2941 *Fcb = pObjectInfo->Fcb;
2949 // Remove the reference we added initially
2952 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2954 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2955 AFS_TRACE_LEVEL_VERBOSE,
2956 "AFSProcessOpen Decrement count on Fcb %08lX Cnt %d\n",
2960 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2963 if( !NT_SUCCESS( ntStatus))
2966 if ( ulFileAccess > 0)
2969 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2971 stReleaseFileAccess.FileAccess = ulFileAccess;
2973 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2975 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2976 AFS_REQUEST_FLAG_SYNCHRONOUS,
2978 &DirectoryCB->NameInformation.FileName,
2979 &pObjectInfo->FileId,
2980 (void *)&stReleaseFileAccess,
2981 sizeof( AFSFileAccessReleaseCB),
2998 AFSRemoveFcb( pObjectInfo->Fcb);
3000 pObjectInfo->Fcb = NULL;
3011 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
3013 IN AFSVolumeCB *VolumeCB,
3015 IN AFSDirectoryCB *ParentDirCB,
3016 IN AFSDirectoryCB *DirectoryCB,
3021 NTSTATUS ntStatus = STATUS_SUCCESS;
3022 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3023 PFILE_OBJECT pFileObject = NULL;
3024 LARGE_INTEGER liZero = {0,0};
3025 BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
3026 ULONG ulAttributes = 0;
3027 LARGE_INTEGER liTime;
3028 ULONG ulCreateDisposition = 0;
3029 BOOLEAN bAllocatedCcb = FALSE, bAllocatedFcb = FALSE;
3030 PACCESS_MASK pDesiredAccess = NULL;
3031 USHORT usShareAccess;
3032 AFSObjectInfoCB *pParentObjectInfo = NULL;
3033 AFSObjectInfoCB *pObjectInfo = NULL;
3039 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3040 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
3042 pFileObject = pIrpSp->FileObject;
3044 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
3046 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
3048 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
3051 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3052 AFS_TRACE_LEVEL_ERROR,
3053 "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3055 &DirectoryCB->NameInformation.FileName);
3057 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3060 pParentObjectInfo = ParentDirCB->ObjectInformation;
3062 pObjectInfo = DirectoryCB->ObjectInformation;
3065 // Check if we should go and retrieve updated information for the node
3068 ntStatus = AFSValidateEntry( DirectoryCB,
3073 if( !NT_SUCCESS( ntStatus))
3076 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3077 AFS_TRACE_LEVEL_ERROR,
3078 "AFSProcessOverwriteSupersede (%08lX) Failed to validate entry %wZ Status %08lX\n",
3080 &DirectoryCB->NameInformation.FileName,
3083 try_return( ntStatus);
3087 // Be sure we have an Fcb for the object block
3090 if( pObjectInfo->Fcb == NULL)
3093 ntStatus = AFSInitFcb( DirectoryCB);
3095 *Fcb = pObjectInfo->Fcb;
3097 if( !NT_SUCCESS( ntStatus) &&
3098 ntStatus != STATUS_REPARSE)
3101 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3102 AFS_TRACE_LEVEL_ERROR,
3103 "AFSProcessOverwriteSupersede (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
3105 &DirectoryCB->NameInformation.FileName,
3108 try_return( ntStatus);
3111 if ( ntStatus != STATUS_REPARSE)
3114 bAllocatedFcb = TRUE;
3117 ntStatus = STATUS_SUCCESS;
3122 AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
3129 // Reference the Fcb so it won't go away while processing the request
3132 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3134 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3135 AFS_TRACE_LEVEL_VERBOSE,
3136 "AFSProcessOverwriteSupersede Increment count on Fcb %08lX Cnt %d\n",
3141 // Check access on the entry
3144 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3147 ntStatus = IoCheckShareAccess( *pDesiredAccess,
3150 &pObjectInfo->Fcb->ShareAccess,
3153 if( !NT_SUCCESS( ntStatus))
3156 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3157 AFS_TRACE_LEVEL_ERROR,
3158 "AFSProcessOverwriteSupersede (%08lX) Access check failure %wZ Status %08lX\n",
3160 &DirectoryCB->NameInformation.FileName,
3163 try_return( ntStatus);
3168 // Before we actually truncate, check to see if the purge
3169 // is going to fail.
3172 if( !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,