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( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
107 "EXCEPTION - AFSCreate\n");
109 ntStatus = STATUS_ACCESS_DENIED;
111 AFSDumpTraceFilesFnc();
115 // Complete the request
118 AFSCompleteRequest( Irp,
125 AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
129 NTSTATUS ntStatus = STATUS_SUCCESS;
130 UNICODE_STRING uniFileName;
131 ULONG ulCreateDisposition = 0;
133 BOOLEAN bNoIntermediateBuffering = FALSE;
134 FILE_OBJECT *pFileObject = NULL;
135 IO_STACK_LOCATION *pIrpSp;
138 AFSDeviceExt *pDeviceExt = NULL;
139 BOOLEAN bOpenTargetDirectory = FALSE, bReleaseVolume = FALSE;
140 PACCESS_MASK pDesiredAccess = NULL;
141 UNICODE_STRING uniComponentName, uniPathName, uniRootFileName, uniParsedFileName;
142 UNICODE_STRING uniSubstitutedPathName;
143 UNICODE_STRING uniRelativeName;
144 AFSNameArrayHdr *pNameArray = NULL;
145 AFSVolumeCB *pVolumeCB = NULL;
146 AFSDirectoryCB *pParentDirectoryCB = NULL, *pDirectoryCB = NULL;
147 ULONG ulParseFlags = 0;
149 ULONG ulNameProcessingFlags = 0;
150 BOOLEAN bOpenedReparsePoint = FALSE;
156 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
157 pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
158 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
159 ulOptions = pIrpSp->Parameters.Create.Options;
160 bNoIntermediateBuffering = BooleanFlagOn( ulOptions, FILE_NO_INTERMEDIATE_BUFFERING);
161 bOpenTargetDirectory = BooleanFlagOn( pIrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
162 pFileObject = pIrpSp->FileObject;
163 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
165 uniFileName.Length = uniFileName.MaximumLength = 0;
166 uniFileName.Buffer = NULL;
168 uniRootFileName.Length = uniRootFileName.MaximumLength = 0;
169 uniRootFileName.Buffer = NULL;
171 uniParsedFileName.Length = uniParsedFileName.MaximumLength = 0;
172 uniParsedFileName.Buffer = NULL;
174 uniSubstitutedPathName.Buffer = NULL;
175 uniSubstitutedPathName.Length = 0;
177 uniRelativeName.Buffer = NULL;
178 uniRelativeName.Length = 0;
180 if( AFSGlobalRoot == NULL)
182 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
185 RtlZeroMemory( &stAuthGroup,
188 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
189 (ULONGLONG)PsGetCurrentThreadId(),
193 // If we are in shutdown mode then fail the request
196 if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
199 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
200 AFS_TRACE_LEVEL_WARNING,
201 "AFSCommonCreate (%08lX) Open request after shutdown\n",
204 try_return( ntStatus = STATUS_TOO_LATE);
207 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
210 ntStatus = AFSEnumerateGlobalRoot( &stAuthGroup);
212 if( !NT_SUCCESS( ntStatus))
215 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
216 AFS_TRACE_LEVEL_ERROR,
217 "AFSCommonCreate Failed to enumerate global root Status %08lX\n",
220 try_return( ntStatus);
225 // Go and parse the name for processing.
226 // If ulParseFlags is returned with AFS_PARSE_FLAG_FREE_FILE_BUFFER set,
227 // then we are responsible for releasing the uniRootFileName.Buffer.
230 ntStatus = AFSParseName( Irp,
240 if( !NT_SUCCESS( ntStatus))
243 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
244 uniFileName.Length > 0 ? AFS_TRACE_LEVEL_ERROR : AFS_TRACE_LEVEL_VERBOSE,
245 "AFSCommonCreate (%08lX) Failed to parse name \"%wZ\" Status %08lX\n",
250 try_return( ntStatus);
254 // Check for STATUS_REPARSE
257 if( ntStatus == STATUS_REPARSE)
261 // Update the information and return
264 Irp->IoStatus.Information = IO_REPARSE;
266 try_return( ntStatus);
270 // If the returned volume cb is NULL then we are dealing with the \\Server\GlobalRoot
274 if( pVolumeCB == NULL)
278 // Remove any leading or trailing slashes
281 if( uniFileName.Length >= sizeof( WCHAR) &&
282 uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
285 uniFileName.Length -= sizeof( WCHAR);
288 if( uniFileName.Length >= sizeof( WCHAR) &&
289 uniFileName.Buffer[ 0] == L'\\')
292 uniFileName.Buffer = &uniFileName.Buffer[ 1];
294 uniFileName.Length -= sizeof( WCHAR);
298 // If there is a remaining portion returned for this request then
299 // check if it is for the PIOCtl interface
302 if( uniFileName.Length > 0)
306 // We don't accept any other opens off of the AFS Root
309 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
312 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
315 if( RtlCompareUnicodeString( &AFSPIOCtlName,
320 ntStatus = AFSOpenIOCtlFcb( Irp,
322 AFSGlobalRoot->DirectoryCB,
326 if( !NT_SUCCESS( ntStatus))
329 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
330 AFS_TRACE_LEVEL_ERROR,
331 "AFSCommonCreate Failed to open root IOCtl Fcb Status %08lX\n",
335 else if( pParentDirectoryCB != NULL &&
336 pParentDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
339 ntStatus = AFSOpenSpecialShareFcb( Irp,
345 if( !NT_SUCCESS( ntStatus))
348 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
349 AFS_TRACE_LEVEL_ERROR,
350 "AFSCommonCreate Failed to open special share Fcb Status %08lX\n",
355 try_return( ntStatus);
358 ntStatus = AFSOpenAFSRoot( Irp,
362 if( !NT_SUCCESS( ntStatus))
365 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
366 AFS_TRACE_LEVEL_ERROR,
367 "AFSCommonCreate Failed to open root Status %08lX\n",
370 lCount = InterlockedDecrement( &AFSGlobalRoot->DirectoryCB->DirOpenReferenceCount);
372 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
373 AFS_TRACE_LEVEL_VERBOSE,
374 "AFSCommonCreate Decrement1 count on &wZ DE %p Ccb %p Cnt %d\n",
375 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
376 AFSGlobalRoot->DirectoryCB,
380 ASSERT( lCount >= 0);
383 try_return( ntStatus);
387 // We have a reference on the root volume
390 bReleaseVolume = TRUE;
393 // Attempt to locate the node in the name tree if this is not a target
394 // open and the target is not the root
397 uniComponentName.Length = 0;
398 uniComponentName.Buffer = NULL;
400 if( uniFileName.Length > sizeof( WCHAR) ||
401 uniFileName.Buffer[ 0] != L'\\')
404 if( !AFSValidNameFormat( &uniFileName))
407 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
409 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
410 AFS_TRACE_LEVEL_VERBOSE,
411 "AFSCommonCreate (%08lX) Invalid name %wZ Status %08lX\n",
416 try_return( ntStatus);
420 // Opening a reparse point directly?
423 ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
425 if( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
427 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
428 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
429 AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
432 uniSubstitutedPathName = uniRootFileName;
434 ntStatus = AFSLocateNameEntry( &stAuthGroup,
439 ulNameProcessingFlags,
445 if( !NT_SUCCESS( ntStatus) &&
446 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
449 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
451 uniSubstitutedPathName.Buffer = NULL;
455 // The routine above released the root while walking the
459 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
460 AFS_TRACE_LEVEL_VERBOSE,
461 "AFSCommonCreate (%08lX) Failed to locate name entry for %wZ Status %08lX\n",
467 // We released any root volume locks in the above on failure
470 bReleaseVolume = FALSE;
472 try_return( ntStatus);
476 // Check for STATUS_REPARSE
479 if( ntStatus == STATUS_REPARSE)
482 uniSubstitutedPathName.Buffer = NULL;
485 // Update the information and return
488 Irp->IoStatus.Information = IO_REPARSE;
491 // We released the volume lock above
494 bReleaseVolume = FALSE;
496 try_return( ntStatus);
500 // If we re-allocated the name, then update our substitute name
503 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
506 uniSubstitutedPathName = uniRootFileName;
511 uniSubstitutedPathName.Buffer = NULL;
515 // Check for a symlink access
518 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
519 pParentDirectoryCB != NULL)
522 UNICODE_STRING uniFinalComponent;
524 uniFinalComponent.Length = 0;
525 uniFinalComponent.MaximumLength = 0;
526 uniFinalComponent.Buffer = NULL;
528 AFSRetrieveFinalComponent( &uniFileName,
531 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
534 if( !NT_SUCCESS( ntStatus) &&
535 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
538 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
539 AFS_TRACE_LEVEL_VERBOSE,
540 "AFSCommonCreate (%08lX) Failing access to symlink %wZ Status %08lX\n",
545 try_return( ntStatus);
551 // If we have no parent then this is a root open, be sure there is a directory entry
555 else if( pParentDirectoryCB == NULL &&
556 pDirectoryCB == NULL)
559 pDirectoryCB = pVolumeCB->DirectoryCB;
562 if( bOpenTargetDirectory)
566 // If we have a directory cb for the entry then dereference it and reference the parent
569 if( pDirectoryCB != NULL)
573 // Perform in this order to prevent thrashing
576 lCount = InterlockedIncrement( &pParentDirectoryCB->DirOpenReferenceCount);
578 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
579 AFS_TRACE_LEVEL_VERBOSE,
580 "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
581 &pParentDirectoryCB->NameInformation.FileName,
587 // Do NOT decrement the reference count on the pDirectoryCB yet.
588 // The BackupEntry below might drop the count to zero leaving
589 // the entry subject to being deleted and we need some of the
590 // contents during later processing
593 AFSBackupEntry( pNameArray);
597 // OK, open the target directory
600 if( uniComponentName.Length == 0)
602 AFSRetrieveFinalComponent( &uniFileName,
606 ntStatus = AFSOpenTargetDirectory( Irp,
613 if( pDirectoryCB != NULL)
616 // It is now safe to drop the Reference Count
618 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
620 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
621 AFS_TRACE_LEVEL_VERBOSE,
622 "AFSCommonCreate Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
623 &pDirectoryCB->NameInformation.FileName,
628 ASSERT( lCount >= 0);
631 if( !NT_SUCCESS( ntStatus))
634 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
635 AFS_TRACE_LEVEL_ERROR,
636 "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
637 &pParentDirectoryCB->NameInformation.FileName,
641 // Decrement the reference on the parent
644 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
646 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
647 AFS_TRACE_LEVEL_VERBOSE,
648 "AFSCommonCreate Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
649 &pParentDirectoryCB->NameInformation.FileName,
654 ASSERT( lCount >= 0);
657 try_return( ntStatus);
660 if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
663 if( pDirectoryCB == NULL ||
664 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
666 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
667 AFS_TRACE_LEVEL_VERBOSE,
668 "AFSCommonCreate (%08lX) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
672 pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0);
676 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
677 AFS_TRACE_LEVEL_VERBOSE,
678 "AFSCommonCreate (%08lX) Opening as reparse point %wZ Type %08lX\n",
681 pDirectoryCB->ObjectInformation->FileType);
683 bOpenedReparsePoint = TRUE;
688 // Based on the options passed in, process the file accordingly.
691 if( ulCreateDisposition == FILE_CREATE ||
692 ( ( ulCreateDisposition == FILE_OPEN_IF ||
693 ulCreateDisposition == FILE_OVERWRITE_IF) &&
694 pDirectoryCB == NULL))
697 if( uniComponentName.Length == 0 ||
698 pDirectoryCB != NULL)
702 // We traversed the entire path so we found each entry,
703 // fail with collision
706 if( pDirectoryCB != NULL)
709 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
710 AFS_TRACE_LEVEL_VERBOSE,
711 "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
712 &pDirectoryCB->NameInformation.FileName,
715 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
717 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
718 AFS_TRACE_LEVEL_VERBOSE,
719 "AFSCommonCreate Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
720 &pDirectoryCB->NameInformation.FileName,
725 ASSERT( lCount >= 0);
730 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
731 AFS_TRACE_LEVEL_VERBOSE,
732 "AFSCommonCreate Object name collision on create Status %08lX\n",
735 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
737 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
738 AFS_TRACE_LEVEL_VERBOSE,
739 "AFSCommonCreate Decrement5 count on %wZ DE %p Ccb %p Cnt %d\n",
740 &pParentDirectoryCB->NameInformation.FileName,
745 ASSERT( lCount >= 0);
748 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
752 // OK, go and create the node
755 ntStatus = AFSProcessCreate( Irp,
765 if( !NT_SUCCESS( ntStatus))
768 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
769 AFS_TRACE_LEVEL_ERROR,
770 "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
772 &pParentDirectoryCB->NameInformation.FileName,
777 // Dereference the parent entry
780 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
782 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
783 AFS_TRACE_LEVEL_VERBOSE,
784 "AFSCreate Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
785 &pParentDirectoryCB->NameInformation.FileName,
790 ASSERT( lCount >= 0);
792 try_return( ntStatus);
796 // We should not have an extra component except for PIOCtl opens
799 if( uniComponentName.Length > 0)
803 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
806 if( RtlCompareUnicodeString( &AFSPIOCtlName,
811 ntStatus = AFSOpenIOCtlFcb( Irp,
817 if( !NT_SUCCESS( ntStatus))
820 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
821 AFS_TRACE_LEVEL_ERROR,
822 "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
830 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
831 AFS_TRACE_LEVEL_VERBOSE,
832 "AFSCommonCreate (%08lX) File %wZ name not found\n",
836 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
839 if( !NT_SUCCESS( ntStatus))
843 // Dereference the parent entry
846 if( pDirectoryCB != NULL)
849 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
851 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
852 AFS_TRACE_LEVEL_VERBOSE,
853 "AFSCommonCreate Decrement7a count on %wZ DE %p Ccb %p Cnt %d\n",
854 &pDirectoryCB->NameInformation.FileName,
859 ASSERT( lCount >= 0);
864 lCount = InterlockedDecrement( &pParentDirectoryCB->DirOpenReferenceCount);
866 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
867 AFS_TRACE_LEVEL_VERBOSE,
868 "AFSCommonCreate Decrement7b count on %wZ DE %p Ccb %p Cnt %d\n",
869 &pParentDirectoryCB->NameInformation.FileName,
874 ASSERT( lCount >= 0);
878 try_return( ntStatus);
882 // For root opens the parent will be NULL
885 if( pParentDirectoryCB == NULL)
889 // Check for the delete on close flag for the root
892 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
895 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
896 AFS_TRACE_LEVEL_ERROR,
897 "AFSCommonCreate (%08lX) Attempt to open root as delete on close\n",
900 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
902 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
903 AFS_TRACE_LEVEL_VERBOSE,
904 "AFSCommonCreate Decrement8 count on %wZ DE %p Ccb %p Cnt %d\n",
905 &pDirectoryCB->NameInformation.FileName,
910 ASSERT( lCount >= 0);
912 try_return( ntStatus = STATUS_CANNOT_DELETE);
916 // If this is the target directory, then bail
919 if( bOpenTargetDirectory)
922 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
923 AFS_TRACE_LEVEL_ERROR,
924 "AFSCommonCreate (%08lX) Attempt to open root as target directory\n",
927 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
929 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
930 AFS_TRACE_LEVEL_VERBOSE,
931 "AFSCommonCreate Decrement9 count on %wZ DE %p Ccb %p Cnt %d\n",
932 &pDirectoryCB->NameInformation.FileName,
937 ASSERT( lCount >= 0);
939 try_return( ntStatus = STATUS_INVALID_PARAMETER);
943 // Go and open the root of the volume
946 ntStatus = AFSOpenRoot( Irp,
952 if( !NT_SUCCESS( ntStatus))
955 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
956 AFS_TRACE_LEVEL_ERROR,
957 "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
958 pVolumeCB->ObjectInformation.FileId.Cell,
959 pVolumeCB->ObjectInformation.FileId.Volume,
962 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
964 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
965 AFS_TRACE_LEVEL_VERBOSE,
966 "AFSCommonCreate Decrement10 count on %wZ DE %p Ccb %p Cnt %d\n",
967 &pDirectoryCB->NameInformation.FileName,
972 ASSERT( lCount >= 0);
975 try_return( ntStatus);
979 // At this point if we have no pDirectoryCB it was not found.
982 if( pDirectoryCB == NULL)
985 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
986 AFS_TRACE_LEVEL_ERROR,
987 "AFSCommonCreate Failing access to %wZ\n",
990 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
993 if( ulCreateDisposition == FILE_OVERWRITE ||
994 ulCreateDisposition == FILE_SUPERSEDE ||
995 ulCreateDisposition == FILE_OVERWRITE_IF)
999 // Go process a file for overwrite or supersede.
1002 ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
1011 if( !NT_SUCCESS( ntStatus))
1014 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1015 AFS_TRACE_LEVEL_ERROR,
1016 "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
1017 &pDirectoryCB->NameInformation.FileName,
1020 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
1022 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1023 AFS_TRACE_LEVEL_VERBOSE,
1024 "AFSCommonCreate Decrement11 count on %wZ DE %p Ccb %p Cnt %d\n",
1025 &pDirectoryCB->NameInformation.FileName,
1030 ASSERT( lCount >= 0);
1033 try_return( ntStatus);
1037 // Trying to open the file
1040 ntStatus = AFSProcessOpen( Irp,
1048 if( !NT_SUCCESS( ntStatus))
1051 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1052 AFS_TRACE_LEVEL_ERROR,
1053 "AFSCommonCreate Failed open on %wZ Status %08lX\n",
1054 &pDirectoryCB->NameInformation.FileName,
1057 lCount = InterlockedDecrement( &pDirectoryCB->DirOpenReferenceCount);
1059 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1060 AFS_TRACE_LEVEL_VERBOSE,
1061 "AFSCommonCreate Decrement12 count on %wZ DE %p Ccb %p Cnt %d\n",
1062 &pDirectoryCB->NameInformation.FileName,
1067 ASSERT( lCount >= 0);
1072 if( NT_SUCCESS( ntStatus) &&
1073 ntStatus != STATUS_REPARSE)
1079 AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
1082 RtlCopyMemory( &pCcb->AuthGroup,
1087 // If we have a substitute name, then use it
1090 if( uniSubstitutedPathName.Buffer != NULL)
1093 pCcb->FullFileName = uniSubstitutedPathName;
1095 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1097 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1102 pCcb->FullFileName = uniRootFileName;
1104 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1107 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1109 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1113 if( bOpenedReparsePoint)
1115 SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1118 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1119 AFS_TRACE_LEVEL_VERBOSE,
1120 "AFSCommonCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1121 &pCcb->DirectoryCB->NameInformation.FileName,
1124 lCount = pCcb->DirectoryCB->DirOpenReferenceCount);
1126 ASSERT( lCount >= 0);
1128 pCcb->CurrentDirIndex = 0;
1130 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1133 SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1137 // Save off the name array for this instance
1140 pCcb->NameArray = pNameArray;
1144 AFSReleaseResource( &pCcb->NPCcb->CcbLock);
1148 // If we make it here then init the FO for the request.
1151 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1152 AFS_TRACE_LEVEL_VERBOSE_2,
1153 "AFSCommonCreate (%08lX) FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1159 pFileObject->FsContext = (void *)pFcb;
1161 pFileObject->FsContext2 = (void *)pCcb;
1166 ASSERT( pFcb->OpenHandleCount > 0);
1168 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1171 // For files perform additional processing
1174 switch( pFcb->Header.NodeTypeCode)
1181 pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1186 // If the user did not request nobuffering then mark the FO as cacheable
1189 if( bNoIntermediateBuffering)
1192 pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1197 pFileObject->Flags |= FO_CACHE_SUPPORTED;
1201 // If the file was opened for execution then we need to set the bit in the FO
1204 if( BooleanFlagOn( *pDesiredAccess,
1208 SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1212 // Update the last access time
1215 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1226 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1227 AFS_TRACE_LEVEL_ERROR,
1228 "AFSCommonCreate (%08lX) Returning with NULL Fcb FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1237 if( NT_SUCCESS( ntStatus) &&
1238 ntStatus == STATUS_REPARSE)
1241 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1242 AFS_TRACE_LEVEL_ERROR,
1243 "AFSCommonCreate (%08lX) STATUS_REPARSE FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1251 // Free up the sub name if we have one
1254 if( uniSubstitutedPathName.Buffer != NULL)
1257 AFSExFreePoolWithTag( uniSubstitutedPathName.Buffer, 0);
1259 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1264 // Free up the name array ...
1267 if( pNameArray != NULL)
1270 AFSFreeNameArray( pNameArray);
1273 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1276 AFSExFreePoolWithTag( uniRootFileName.Buffer, 0);
1282 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1284 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1285 AFS_TRACE_LEVEL_VERBOSE,
1286 "AFSCommonCreate Decrement count on Volume %08lX Cnt %d\n",
1292 // Setup the Irp for completion, the Information has been set previously
1295 Irp->IoStatus.Status = ntStatus;
1302 AFSOpenAFSRoot( IN PIRP Irp,
1307 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 lCount = 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,
1348 lCount = 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,
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;
1386 BOOLEAN bAllocatedCcb = FALSE;
1387 BOOLEAN bReleaseFcb = FALSE;
1388 AFSFileOpenCB stOpenCB;
1389 AFSFileOpenResultCB stOpenResultCB;
1390 ULONG ulResultLen = 0;
1396 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1397 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1398 ulOptions = pIrpSp->Parameters.Create.Options;
1400 pFileObject = pIrpSp->FileObject;
1402 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1405 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1407 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1408 AFS_TRACE_LEVEL_ERROR,
1409 "AFSOpenRoot (%08lX) Attempt to open root as file Status %08lX\n",
1413 try_return( ntStatus);
1417 // Check if we should go and retrieve updated information for the node
1420 ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1425 if( !NT_SUCCESS( ntStatus))
1428 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1429 AFS_TRACE_LEVEL_ERROR,
1430 "AFSOpenRoot (%08lX) Failed to validate root entry Status %08lX\n",
1434 try_return( ntStatus);
1438 // Check with the service that we can open the file
1441 RtlZeroMemory( &stOpenCB,
1442 sizeof( AFSFileOpenCB));
1444 stOpenCB.DesiredAccess = *pDesiredAccess;
1446 stOpenCB.ShareAccess = usShareAccess;
1448 stOpenResultCB.GrantedAccess = 0;
1450 ulResultLen = sizeof( AFSFileOpenResultCB);
1452 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1453 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1456 &VolumeCB->ObjectInformation.FileId,
1458 sizeof( AFSFileOpenCB),
1459 (void *)&stOpenResultCB,
1462 if( !NT_SUCCESS( ntStatus))
1465 UNICODE_STRING uniGUID;
1468 uniGUID.MaximumLength = 0;
1469 uniGUID.Buffer = NULL;
1471 if( AuthGroup != NULL)
1473 RtlStringFromGUID( *AuthGroup,
1477 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1478 AFS_TRACE_LEVEL_ERROR,
1479 "AFSOpenRoot (%08lX) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1481 VolumeCB->ObjectInformation.FileId.Cell,
1482 VolumeCB->ObjectInformation.FileId.Volume,
1486 if( AuthGroup != NULL)
1488 RtlFreeUnicodeString( &uniGUID);
1491 try_return( ntStatus);
1495 // If the entry is not initialized then do it now
1498 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1501 AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1504 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1507 ntStatus = AFSEnumerateDirectory( AuthGroup,
1508 &VolumeCB->ObjectInformation,
1511 if( !NT_SUCCESS( ntStatus))
1514 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1516 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1517 AFS_TRACE_LEVEL_ERROR,
1518 "AFSOpenRoot (%08lX) Failed to enumerate directory Status %08lX\n",
1522 try_return( ntStatus);
1525 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1528 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1532 // If the root fcb has been initialized then check access otherwise
1533 // init the volume fcb
1536 if( VolumeCB->RootFcb == NULL)
1539 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1542 if( !NT_SUCCESS( ntStatus))
1545 try_return( ntStatus);
1551 AFSAcquireExcl( VolumeCB->RootFcb->Header.Resource,
1558 // If there are current opens on the Fcb, check the access.
1561 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1564 ntStatus = IoCheckShareAccess( *pDesiredAccess,
1567 &VolumeCB->RootFcb->ShareAccess,
1570 if( !NT_SUCCESS( ntStatus))
1573 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1574 AFS_TRACE_LEVEL_ERROR,
1575 "AFSOpenRoot (%08lX) Access check failure Status %08lX\n",
1579 try_return( ntStatus);
1584 // Initialize the Ccb for the file.
1587 ntStatus = AFSInitCcb( Ccb);
1589 if( !NT_SUCCESS( ntStatus))
1592 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1593 AFS_TRACE_LEVEL_ERROR,
1594 "AFSOpenRoot (%08lX) Failed to allocate Ccb Status %08lX\n",
1598 try_return( ntStatus);
1601 bAllocatedCcb = TRUE;
1607 (*Ccb)->DirectoryCB = VolumeCB->DirectoryCB;
1609 (*Ccb)->GrantedAccess = *pDesiredAccess;
1612 // OK, update the share access on the fileobject
1615 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1618 IoUpdateShareAccess( pFileObject,
1619 &VolumeCB->RootFcb->ShareAccess);
1628 IoSetShareAccess( *pDesiredAccess,
1631 &VolumeCB->RootFcb->ShareAccess);
1635 // Increment the open count on this Fcb
1638 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1640 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1641 AFS_TRACE_LEVEL_VERBOSE,
1642 "AFSOpenRoot Increment count on Fcb %08lX Cnt %d\n",
1646 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1648 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1649 AFS_TRACE_LEVEL_VERBOSE,
1650 "AFSOpenRoot Increment handle count on Fcb %08lX Cnt %d\n",
1655 // Indicate the object is held
1658 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1661 // Return the open result for this file
1664 Irp->IoStatus.Information = FILE_OPENED;
1666 *RootFcb = VolumeCB->RootFcb;
1673 AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1676 if( !NT_SUCCESS( ntStatus))
1688 Irp->IoStatus.Information = 0;
1696 AFSProcessCreate( IN PIRP Irp,
1698 IN AFSVolumeCB *VolumeCB,
1699 IN AFSDirectoryCB *ParentDirCB,
1700 IN PUNICODE_STRING FileName,
1701 IN PUNICODE_STRING ComponentName,
1702 IN PUNICODE_STRING FullFileName,
1707 NTSTATUS ntStatus = STATUS_SUCCESS;
1708 PFILE_OBJECT pFileObject = NULL;
1709 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1710 ULONG ulOptions = 0;
1711 ULONG ulShareMode = 0;
1713 ULONG ulAttributes = 0;
1714 LARGE_INTEGER liAllocationSize = {0,0};
1715 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1716 PACCESS_MASK pDesiredAccess = NULL;
1717 USHORT usShareAccess;
1718 AFSDirectoryCB *pDirEntry = NULL;
1719 AFSObjectInfoCB *pParentObjectInfo = NULL;
1720 AFSObjectInfoCB *pObjectInfo = NULL;
1726 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1727 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1729 pFileObject = pIrpSp->FileObject;
1732 // Extract out the options
1735 ulOptions = pIrpSp->Parameters.Create.Options;
1738 // We pass all attributes they want to apply to the file to the create
1741 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1744 // If this is a directory create then set the attribute correctly
1747 if( ulOptions & FILE_DIRECTORY_FILE)
1750 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1753 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1754 AFS_TRACE_LEVEL_VERBOSE,
1755 "AFSProcessCreate (%08lX) Creating file %wZ Attributes %08lX\n",
1760 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1763 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1764 AFS_TRACE_LEVEL_ERROR,
1765 "AFSProcessCreate Request failed due to read only volume %wZ\n",
1768 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
1771 pParentObjectInfo = ParentDirCB->ObjectInformation;
1774 // Allocate and insert the direntry into the parent node
1777 ntStatus = AFSCreateDirEntry( AuthGroup,
1785 if( !NT_SUCCESS( ntStatus))
1788 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1789 AFS_TRACE_LEVEL_ERROR,
1790 "AFSProcessCreate (%08lX) Failed to create directory entry %wZ Status %08lX\n",
1795 try_return( ntStatus);
1798 bFileCreated = TRUE;
1800 pObjectInfo = pDirEntry->ObjectInformation;
1802 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1803 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1806 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1807 AFS_TRACE_LEVEL_VERBOSE,
1808 "AFSProcessCreate (%08lX) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1810 &pDirEntry->NameInformation.FileName,
1811 pObjectInfo->FileId.Cell,
1812 pObjectInfo->FileId.Volume,
1813 pObjectInfo->FileId.Vnode,
1814 pObjectInfo->FileId.Unique);
1816 ntStatus = AFSEvaluateNode( AuthGroup,
1819 if( !NT_SUCCESS( ntStatus))
1822 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
1825 if ( pParentObjectInfo == pObjectInfo->ParentObjectInformation)
1828 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1829 AFS_TRACE_LEVEL_ERROR,
1830 "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1832 &pDirEntry->NameInformation.FileName,
1833 pObjectInfo->FileId.Cell,
1834 pObjectInfo->FileId.Volume,
1835 pObjectInfo->FileId.Vnode,
1836 pObjectInfo->FileId.Unique,
1837 pParentObjectInfo->FileId.Cell,
1838 pParentObjectInfo->FileId.Volume,
1839 pParentObjectInfo->FileId.Vnode,
1840 pParentObjectInfo->FileId.Unique,
1843 else if ( pObjectInfo->ParentObjectInformation == NULL)
1846 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1847 AFS_TRACE_LEVEL_ERROR,
1848 "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
1850 &pDirEntry->NameInformation.FileName,
1851 pObjectInfo->FileId.Cell,
1852 pObjectInfo->FileId.Volume,
1853 pObjectInfo->FileId.Vnode,
1854 pObjectInfo->FileId.Unique,
1855 pParentObjectInfo->FileId.Cell,
1856 pParentObjectInfo->FileId.Volume,
1857 pParentObjectInfo->FileId.Vnode,
1858 pParentObjectInfo->FileId.Unique,
1864 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1865 AFS_TRACE_LEVEL_ERROR,
1866 "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1868 &pDirEntry->NameInformation.FileName,
1869 pObjectInfo->FileId.Cell,
1870 pObjectInfo->FileId.Volume,
1871 pObjectInfo->FileId.Vnode,
1872 pObjectInfo->FileId.Unique,
1873 pParentObjectInfo->FileId.Cell,
1874 pParentObjectInfo->FileId.Volume,
1875 pParentObjectInfo->FileId.Vnode,
1876 pParentObjectInfo->FileId.Unique,
1877 pObjectInfo->ParentObjectInformation->FileId.Cell,
1878 pObjectInfo->ParentObjectInformation->FileId.Volume,
1879 pObjectInfo->ParentObjectInformation->FileId.Vnode,
1880 pObjectInfo->ParentObjectInformation->FileId.Unique,
1887 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1888 AFS_TRACE_LEVEL_ERROR,
1889 "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1891 &pDirEntry->NameInformation.FileName,
1892 pObjectInfo->FileId.Cell,
1893 pObjectInfo->FileId.Volume,
1894 pObjectInfo->FileId.Vnode,
1895 pObjectInfo->FileId.Unique,
1899 try_return( ntStatus);
1902 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1906 // We may have raced and the Fcb is already created
1910 // Allocate and initialize the Fcb for the file.
1913 ntStatus = AFSInitFcb( pDirEntry);
1915 *Fcb = pObjectInfo->Fcb;
1917 if( !NT_SUCCESS( ntStatus))
1920 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1921 AFS_TRACE_LEVEL_ERROR,
1922 "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
1927 try_return( ntStatus);
1930 ntStatus = STATUS_SUCCESS;
1933 // Increment the open count on this Fcb
1936 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1938 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1939 AFS_TRACE_LEVEL_VERBOSE,
1940 "AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n",
1947 // Initialize the Ccb for the file.
1950 ntStatus = AFSInitCcb( Ccb);
1952 if( !NT_SUCCESS( ntStatus))
1955 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1956 AFS_TRACE_LEVEL_ERROR,
1957 "AFSProcessCreate (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
1962 try_return( ntStatus);
1965 bAllocatedCcb = TRUE;
1968 // Initialize the Ccb
1971 (*Ccb)->DirectoryCB = pDirEntry;
1973 (*Ccb)->GrantedAccess = *pDesiredAccess;
1976 // If this is a file, update the headers filesizes.
1979 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1983 // Update the sizes with the information passed in
1986 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
1987 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1988 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1991 // Notify the system of the addition
1994 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1996 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1997 (ULONG)FILE_ACTION_ADDED);
1999 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2001 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2005 // This is a new directory node so indicate it has been enumerated
2008 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
2011 // And the parent directory entry
2014 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2017 // Notify the system of the addition
2020 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2022 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2023 (ULONG)FILE_ACTION_ADDED);
2025 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2026 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2027 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2028 (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
2032 // And the parent directory entry
2035 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2038 // Notify the system of the addition
2041 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2043 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2044 (ULONG)FILE_ACTION_ADDED);
2048 // Save off the access for the open
2051 IoSetShareAccess( *pDesiredAccess,
2054 &(*Fcb)->ShareAccess);
2056 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2058 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2059 AFS_TRACE_LEVEL_VERBOSE,
2060 "AFSProcessCreate Increment handle count on Fcb %08lX Cnt %d\n",
2065 // Increment the open reference and handle on the parent node
2068 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2070 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2071 AFS_TRACE_LEVEL_VERBOSE,
2072 "AFSProcessCreate Increment child open handle count on Parent object %08lX Cnt %d\n",
2073 pObjectInfo->ParentObjectInformation,
2076 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2078 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2079 AFS_TRACE_LEVEL_VERBOSE,
2080 "AFSProcessCreate Increment child open ref count on Parent object %08lX Cnt %d\n",
2081 pObjectInfo->ParentObjectInformation,
2084 if( ulOptions & FILE_DELETE_ON_CLOSE)
2088 // Mark it for delete on close
2091 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2092 AFS_TRACE_LEVEL_VERBOSE,
2093 "AFSProcessCreate (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2098 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2102 // Indicate the object is locked in the service
2105 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2108 // Return the open result for this file
2111 Irp->IoStatus.Information = FILE_CREATED;
2116 // If we created the Fcb we need to release the resources
2122 if( !NT_SUCCESS( ntStatus))
2125 // Decrement the open count on this Fcb
2128 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2130 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2131 AFS_TRACE_LEVEL_VERBOSE,
2132 "AFSProcessCreate Decrement count on Fcb %08lX Cnt %d\n",
2137 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2140 if( !NT_SUCCESS( ntStatus))
2146 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2147 AFS_TRACE_LEVEL_VERBOSE,
2148 "AFSProcessCreate Create failed, removing DE %p from aprent object %p Status %08lX\n",
2154 // Remove the dir entry from the parent
2157 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2160 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2162 AFSNotifyDelete( pDirEntry,
2167 // Decrement the reference added during initialization of the DE
2170 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2172 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2173 AFS_TRACE_LEVEL_VERBOSE,
2174 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2175 &pDirEntry->NameInformation.FileName,
2179 ASSERT( lCount >= 0);
2182 // Pull the directory entry from the parent
2185 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2187 FALSE); // Leave it in the enum list so the worker cleans it up
2190 // Tag the parent as needing verification
2193 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2195 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2197 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2208 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2221 AFSOpenTargetDirectory( IN PIRP Irp,
2222 IN AFSVolumeCB *VolumeCB,
2223 IN AFSDirectoryCB *ParentDirectoryCB,
2224 IN AFSDirectoryCB *TargetDirectoryCB,
2225 IN UNICODE_STRING *TargetName,
2230 NTSTATUS ntStatus = STATUS_SUCCESS;
2231 PFILE_OBJECT pFileObject = NULL;
2232 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2233 PACCESS_MASK pDesiredAccess = NULL;
2234 USHORT usShareAccess;
2235 BOOLEAN bAllocatedCcb = FALSE;
2236 BOOLEAN bReleaseFcb = FALSE;
2237 AFSObjectInfoCB *pParentObject = NULL, *pTargetObject = NULL;
2238 UNICODE_STRING uniTargetName;
2244 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2245 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2247 pFileObject = pIrpSp->FileObject;
2249 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2250 AFS_TRACE_LEVEL_VERBOSE,
2251 "AFSOpenTargetDirectory (%08lX) Processing file %wZ\n",
2255 pParentObject = ParentDirectoryCB->ObjectInformation;
2257 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2260 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2264 // Make sure we have an Fcb for the access
2267 // Allocate and initialize the Fcb for the file.
2270 ntStatus = AFSInitFcb( ParentDirectoryCB);
2272 *Fcb = pParentObject->Fcb;
2274 if( !NT_SUCCESS( ntStatus))
2277 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2278 AFS_TRACE_LEVEL_ERROR,
2279 "AFSOpenTargetDirectory (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
2281 &ParentDirectoryCB->NameInformation.FileName,
2284 try_return( ntStatus);
2287 ntStatus = STATUS_SUCCESS;
2290 // Increment the open count on this Fcb
2293 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2295 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2296 AFS_TRACE_LEVEL_VERBOSE,
2297 "AFSOpenTargetDirectory Increment count on Fcb %08lX Cnt %d\n",
2304 // If there are current opens on the Fcb, check the access.
2307 if( pParentObject->Fcb->OpenHandleCount > 0)
2310 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2313 &pParentObject->Fcb->ShareAccess,
2316 if( !NT_SUCCESS( ntStatus))
2319 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2320 AFS_TRACE_LEVEL_ERROR,
2321 "AFSOpenTargetDirectory (%08lX) Access check failure %wZ Status %08lX\n",
2323 &ParentDirectoryCB->NameInformation.FileName,
2326 try_return( ntStatus);
2331 // Initialize the Ccb for the file.
2334 ntStatus = AFSInitCcb( Ccb);
2336 if( !NT_SUCCESS( ntStatus))
2339 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2340 AFS_TRACE_LEVEL_ERROR,
2341 "AFSOpenTargetDirectory (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2343 &ParentDirectoryCB->NameInformation.FileName,
2346 try_return( ntStatus);
2349 bAllocatedCcb = TRUE;
2352 // Initialize the Ccb
2355 (*Ccb)->DirectoryCB = ParentDirectoryCB;
2357 (*Ccb)->GrantedAccess = *pDesiredAccess;
2359 if( TargetDirectoryCB != NULL &&
2360 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2366 Irp->IoStatus.Information = FILE_EXISTS;
2368 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2373 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2375 uniTargetName = *TargetName;
2379 // Update the filename in the fileobject for rename processing
2382 RtlCopyMemory( pFileObject->FileName.Buffer,
2383 uniTargetName.Buffer,
2384 uniTargetName.Length);
2386 pFileObject->FileName.Length = uniTargetName.Length;
2389 // OK, update the share access on the fileobject
2392 if( pParentObject->Fcb->OpenHandleCount > 0)
2395 IoUpdateShareAccess( pFileObject,
2396 &pParentObject->Fcb->ShareAccess);
2405 IoSetShareAccess( *pDesiredAccess,
2408 &pParentObject->Fcb->ShareAccess);
2411 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2413 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2414 AFS_TRACE_LEVEL_VERBOSE,
2415 "AFSOpenTargetDirectory Increment handle count on Fcb %08lX Cnt %d\n",
2420 // Increment the open reference and handle on the parent node
2423 if( pParentObject->ParentObjectInformation != NULL)
2426 lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2428 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2429 AFS_TRACE_LEVEL_VERBOSE,
2430 "AFSOpenTargetDirectory Increment child open handle count on Parent object %08lX Cnt %d\n",
2431 pParentObject->ParentObjectInformation,
2434 lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2436 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2437 AFS_TRACE_LEVEL_VERBOSE,
2438 "AFSOpenTargetDirectory Increment child open ref count on Parent object %08lX Cnt %d\n",
2439 pParentObject->ParentObjectInformation,
2448 if( !NT_SUCCESS( ntStatus))
2451 // Decrement the open count on this Fcb
2454 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2456 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2457 AFS_TRACE_LEVEL_VERBOSE,
2458 "AFSOpenTargetDirectory Decrement count on Fcb %08lX Cnt %d\n",
2463 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2466 if( !NT_SUCCESS( ntStatus))
2479 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2490 AFSProcessOpen( IN PIRP Irp,
2492 IN AFSVolumeCB *VolumeCB,
2493 IN AFSDirectoryCB *ParentDirCB,
2494 IN AFSDirectoryCB *DirectoryCB,
2499 NTSTATUS ntStatus = STATUS_SUCCESS;
2500 PFILE_OBJECT pFileObject = NULL;
2501 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2502 PACCESS_MASK pDesiredAccess = NULL;
2503 USHORT usShareAccess;
2504 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE;
2505 ULONG ulAdditionalFlags = 0, ulOptions = 0;
2506 AFSFileOpenCB stOpenCB;
2507 AFSFileOpenResultCB stOpenResultCB;
2508 ULONG ulResultLen = 0;
2509 AFSObjectInfoCB *pParentObjectInfo = NULL;
2510 AFSObjectInfoCB *pObjectInfo = NULL;
2511 ULONG ulFileAccess = 0;
2512 AFSFileAccessReleaseCB stReleaseFileAccess;
2518 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2519 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2521 pFileObject = pIrpSp->FileObject;
2523 pParentObjectInfo = ParentDirCB->ObjectInformation;
2525 pObjectInfo = DirectoryCB->ObjectInformation;
2528 // Check if the entry is pending a deletion
2531 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2534 ntStatus = STATUS_DELETE_PENDING;
2536 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2537 AFS_TRACE_LEVEL_ERROR,
2538 "AFSProcessOpen (%08lX) Entry pending delete %wZ Status %08lX\n",
2540 &DirectoryCB->NameInformation.FileName,
2543 try_return( ntStatus);
2547 // Extract out the options
2550 ulOptions = pIrpSp->Parameters.Create.Options;
2553 // Check if we should go and retrieve updated information for the node
2556 ntStatus = AFSValidateEntry( DirectoryCB,
2561 if( !NT_SUCCESS( ntStatus))
2564 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2565 AFS_TRACE_LEVEL_ERROR,
2566 "AFSProcessOpen (%08lX) Failed to validate entry %wZ Status %08lX\n",
2568 &DirectoryCB->NameInformation.FileName,
2571 try_return( ntStatus);
2575 // If this is marked for delete on close then be sure we can delete the entry
2578 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2581 ntStatus = AFSNotifyDelete( DirectoryCB,
2585 if( !NT_SUCCESS( ntStatus))
2588 ntStatus = STATUS_CANNOT_DELETE;
2590 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2591 AFS_TRACE_LEVEL_ERROR,
2592 "AFSProcessOpen (%08lX) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2594 &DirectoryCB->NameInformation.FileName,
2597 try_return( ntStatus);
2602 // Be sure we have an Fcb for the current object
2605 ntStatus = AFSInitFcb( DirectoryCB);
2607 if( !NT_SUCCESS( ntStatus))
2610 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2611 AFS_TRACE_LEVEL_ERROR,
2612 "AFSProcessOpen (%08lX) Failed to init fcb on %wZ Status %08lX\n",
2614 &DirectoryCB->NameInformation.FileName,
2617 try_return( ntStatus);
2620 ntStatus = STATUS_SUCCESS;
2623 // AFSInitFcb returns the Fcb resource held
2629 // Increment the open count on this Fcb
2632 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2634 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2635 AFS_TRACE_LEVEL_VERBOSE,
2636 "AFSProcessOpen Increment2 count on Fcb %08lX Cnt %d\n",
2641 // Check access on the entry
2644 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2647 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2650 &pObjectInfo->Fcb->ShareAccess,
2653 if( !NT_SUCCESS( ntStatus))
2656 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2657 AFS_TRACE_LEVEL_ERROR,
2658 "AFSProcessOpen (%08lX) Failed to check share access on %wZ Status %08lX\n",
2660 &DirectoryCB->NameInformation.FileName,
2663 try_return( ntStatus);
2668 // Additional checks
2671 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2675 // If the caller is asking for write access then try to flush the image section
2678 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2679 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2682 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2683 AFS_TRACE_LEVEL_VERBOSE,
2684 "AFSProcessOpen Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
2685 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2686 PsGetCurrentThread());
2688 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2691 if( !MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2695 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2696 STATUS_SHARING_VIOLATION;
2698 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2699 AFS_TRACE_LEVEL_ERROR,
2700 "AFSProcessOpen (%08lX) Failed to flush image section %wZ Status %08lX\n",
2702 &DirectoryCB->NameInformation.FileName,
2705 try_return( ntStatus);
2708 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2709 AFS_TRACE_LEVEL_VERBOSE,
2710 "AFSProcessOpen Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
2711 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2712 PsGetCurrentThread());
2714 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
2717 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2720 ntStatus = STATUS_NOT_A_DIRECTORY;
2722 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2723 AFS_TRACE_LEVEL_ERROR,
2724 "AFSProcessOpen (%08lX) Attempt to open file as directory %wZ Status %08lX\n",
2726 &DirectoryCB->NameInformation.FileName,
2729 try_return( ntStatus);
2732 pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2734 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2735 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2738 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2741 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2743 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2744 AFS_TRACE_LEVEL_ERROR,
2745 "AFSProcessOpen (%08lX) Attempt to open directory as file %wZ Status %08lX\n",
2747 &DirectoryCB->NameInformation.FileName,
2750 try_return( ntStatus);
2753 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2754 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2755 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2756 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2763 try_return( ntStatus = STATUS_UNSUCCESSFUL);
2767 // Check with the service that we can open the file
2770 stOpenCB.ParentId = pParentObjectInfo->FileId;
2772 stOpenCB.DesiredAccess = *pDesiredAccess;
2774 stOpenCB.ShareAccess = usShareAccess;
2776 stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2778 stOpenCB.Identifier = (ULONGLONG)pFileObject;
2780 stOpenResultCB.GrantedAccess = 0;
2782 ulResultLen = sizeof( AFSFileOpenResultCB);
2784 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2785 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2787 &DirectoryCB->NameInformation.FileName,
2788 &pObjectInfo->FileId,
2790 sizeof( AFSFileOpenCB),
2791 (void *)&stOpenResultCB,
2794 if( !NT_SUCCESS( ntStatus))
2797 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2798 AFS_TRACE_LEVEL_ERROR,
2799 "AFSProcessOpen (%08lX) Failed open in service %wZ Status %08lX\n",
2801 &DirectoryCB->NameInformation.FileName,
2804 try_return( ntStatus);
2808 // Save the granted access in case we need to release it below
2811 ulFileAccess = stOpenResultCB.FileAccess;
2814 // Check if there is a conflict
2817 if( !AFSCheckAccess( *pDesiredAccess,
2818 stOpenResultCB.GrantedAccess,
2819 BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2822 ntStatus = STATUS_ACCESS_DENIED;
2824 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2825 AFS_TRACE_LEVEL_ERROR,
2826 "AFSProcessOpen (%08lX) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2829 stOpenResultCB.GrantedAccess,
2830 &DirectoryCB->NameInformation.FileName,
2833 try_return( ntStatus);
2837 // Initialize the Ccb for the file.
2840 ntStatus = AFSInitCcb( Ccb);
2842 if( !NT_SUCCESS( ntStatus))
2845 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2846 AFS_TRACE_LEVEL_ERROR,
2847 "AFSProcessOpen (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2849 &DirectoryCB->NameInformation.FileName,
2852 try_return( ntStatus);
2855 bAllocatedCcb = TRUE;
2857 (*Ccb)->DirectoryCB = DirectoryCB;
2859 (*Ccb)->FileAccess = ulFileAccess;
2861 (*Ccb)->GrantedAccess = *pDesiredAccess;
2864 // Perform the access check on the target if this is a mount point or symlink
2867 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2870 IoUpdateShareAccess( pFileObject,
2871 &pObjectInfo->Fcb->ShareAccess);
2880 IoSetShareAccess( *pDesiredAccess,
2883 &pObjectInfo->Fcb->ShareAccess);
2886 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2888 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2889 AFS_TRACE_LEVEL_VERBOSE,
2890 "AFSProcessOpen Increment handle count on Fcb %08lX Cnt %d\n",
2895 // Increment the open reference and handle on the parent node
2898 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2900 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2901 AFS_TRACE_LEVEL_VERBOSE,
2902 "AFSProcessOpen Increment child open handle count on Parent object %08lX Cnt %d\n",
2903 pObjectInfo->ParentObjectInformation,
2906 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2908 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2909 AFS_TRACE_LEVEL_VERBOSE,
2910 "AFSProcessOpen Increment child open ref count on Parent object %08lX Cnt %d\n",
2911 pObjectInfo->ParentObjectInformation,
2914 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2918 // Mark it for delete on close
2921 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2922 AFS_TRACE_LEVEL_VERBOSE,
2923 "AFSProcessOpen (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2926 &DirectoryCB->NameInformation.FileName);
2928 SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2932 // Indicate the object is held
2935 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2938 // Return the open result for this file
2941 Irp->IoStatus.Information = FILE_OPENED;
2943 *Fcb = pObjectInfo->Fcb;
2950 if( !NT_SUCCESS( ntStatus))
2953 // Decrement the open count on this Fcb
2956 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2958 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2959 AFS_TRACE_LEVEL_VERBOSE,
2960 "AFSProcessOpen Decrement2 count on Fcb %08lX Cnt %d\n",
2965 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2968 if( !NT_SUCCESS( ntStatus))
2971 if ( ulFileAccess > 0)
2974 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2976 stReleaseFileAccess.FileAccess = ulFileAccess;
2978 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2980 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2981 AFS_REQUEST_FLAG_SYNCHRONOUS,
2983 &DirectoryCB->NameInformation.FileName,
2984 &pObjectInfo->FileId,
2985 (void *)&stReleaseFileAccess,
2986 sizeof( AFSFileAccessReleaseCB),
3001 // Fcb will be freed by AFSPrimaryVolumeWorker thread
3012 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
3014 IN AFSVolumeCB *VolumeCB,
3016 IN AFSDirectoryCB *ParentDirCB,
3017 IN AFSDirectoryCB *DirectoryCB,
3022 NTSTATUS ntStatus = STATUS_SUCCESS;
3023 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3024 PFILE_OBJECT pFileObject = NULL;
3025 LARGE_INTEGER liZero = {0,0};
3026 BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
3027 ULONG ulAttributes = 0;
3028 LARGE_INTEGER liTime;
3029 ULONG ulCreateDisposition = 0;
3030 BOOLEAN bAllocatedCcb = FALSE;
3031 BOOLEAN bUserMapped = FALSE;
3032 PACCESS_MASK pDesiredAccess = NULL;
3033 USHORT usShareAccess;
3034 AFSObjectInfoCB *pParentObjectInfo = NULL;
3035 AFSObjectInfoCB *pObjectInfo = NULL;
3037 LARGE_INTEGER liSaveSize;
3038 LARGE_INTEGER liSaveVDL;
3039 LARGE_INTEGER liSaveAlloc;
3044 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3046 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
3048 pFileObject = pIrpSp->FileObject;
3050 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
3052 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
3054 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
3057 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3058 AFS_TRACE_LEVEL_ERROR,
3059 "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3061 &DirectoryCB->NameInformation.FileName);
3063 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3066 pParentObjectInfo = ParentDirCB->ObjectInformation;
3068 pObjectInfo = DirectoryCB->ObjectInformation;
3071 // Check if we should go and retrieve updated information for the node
3074 ntStatus = AFSValidateEntry( DirectoryCB,
3079 if( !NT_SUCCESS( ntStatus))
3082 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3083 AFS_TRACE_LEVEL_ERROR,
3084 "AFSProcessOverwriteSupersede (%08lX) Failed to validate entry %wZ Status %08lX\n",
3086 &DirectoryCB->NameInformation.FileName,
3089 try_return( ntStatus);
3093 // Be sure we have an Fcb for the object block
3096 ntStatus = AFSInitFcb( DirectoryCB);
3098 *Fcb = pObjectInfo->Fcb;
3100 if( !NT_SUCCESS( ntStatus))
3103 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3104 AFS_TRACE_LEVEL_ERROR,
3105 "AFSProcessOverwriteSupersede (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
3107 &DirectoryCB->NameInformation.FileName,
3110 try_return( ntStatus);
3113 ntStatus = STATUS_SUCCESS;
3116 // Increment the open count on this Fcb.
3119 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3121 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3122 AFS_TRACE_LEVEL_VERBOSE,
3123 "AFSProcessOverwriteSupersede Increment2 count on Fcb %08lX Cnt %d\n",
3130 // Check access on the entry
3133 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3136 ntStatus = IoCheckShareAccess( *pDesiredAccess,
3139 &pObjectInfo->Fcb->ShareAccess,
3142 if( !NT_SUCCESS( ntStatus))
3145 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3146 AFS_TRACE_LEVEL_ERROR,
3147 "AFSProcessOverwriteSupersede (%08lX) Access check failure %wZ Status %08lX\n",
3149 &DirectoryCB->NameInformation.FileName,
3152 try_return( ntStatus);
3156 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3157 AFS_TRACE_LEVEL_VERBOSE,
3158 "AFSProcessOverwriteSupercede Acquiring Fcb SectionObject lock %08lX EXCL %08lX\n",
3159 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3160 PsGetCurrentThread());
3162 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3166 // Before we actually truncate, check to see if the purge
3167 // is going to fail.
3170 bUserMapped = !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3173 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
3174 AFS_TRACE_LEVEL_VERBOSE,
3175 "AFSProcessOverwriteSupercede Releasing Fcb SectionObject lock %08lX EXCL %08lX\n",
3176 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
3177 PsGetCurrentThread());
3179 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
3184 ntStatus = STATUS_USER_MAPPED_FILE;
3186 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3187 AFS_TRACE_LEVEL_ERROR,
3188 "AFSProcessOverwriteSupersede (%08lX) File user mapped %wZ Status %08lX\n",
3190 &DirectoryCB->NameInformation.FileName,
3193 try_return( ntStatus);
3197 // Initialize the Ccb for the file.
3200 ntStatus = AFSInitCcb( Ccb);
3202 if( !NT_SUCCESS( ntStatus))
3205 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3206 AFS_TRACE_LEVEL_ERROR,
3207 "AFSProcessOverwriteSupersede (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
3209 &DirectoryCB->NameInformation.FileName,
3212 try_return( ntStatus);
3215 bAllocatedCcb = TRUE;
3218 // Initialize the Ccb
3221 (*Ccb)->DirectoryCB = DirectoryCB;
3223 (*Ccb)->GrantedAccess = *pDesiredAccess;
3226 // Set the file length to zero
3229 AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3232 bReleasePaging = TRUE;
3234 liSaveSize = pObjectInfo->Fcb->Header.FileSize;
3235 liSaveAlloc = pObjectInfo->Fcb->Header.AllocationSize;
3236 liSaveVDL = pObjectInfo->Fcb->Header.ValidDataLength;
3238 pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3239 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3240 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3242 pObjectInfo->EndOfFile.QuadPart = 0;
3243 pObjectInfo->AllocationSize.QuadPart = 0;
3246 // Trim down the extents. We do this BEFORE telling the service
3247 // the file is truncated since there is a potential race between
3248 // a worker thread releasing extents and us trimming
3251 AFSTrimExtents( pObjectInfo->Fcb,
3252 &pObjectInfo->Fcb->Header.FileSize);
3254 KeQuerySystemTime( &pObjectInfo->ChangeTime);
3256 KeQuerySystemTime( &pObjectInfo->LastAccessTime);
3258 KeQuerySystemTime( &pObjectInfo->LastWriteTime);
3261 // Set the update flag accordingly
3264 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
3265 AFS_FCB_FLAG_UPDATE_CREATE_TIME |
3266 AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
3267 AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
3268 AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
3270 ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
3274 if( !NT_SUCCESS( ntStatus))
3277 pObjectInfo->Fcb->Header.ValidDataLength = liSaveVDL;
3278 pObjectInfo->Fcb->Header.FileSize = liSaveSize;
3279 pObjectInfo->Fcb->Header.AllocationSize = liSaveAlloc;
3280 pObjectInfo->Fcb->ObjectInformation->EndOfFile = liSaveSize;
3281 pObjectInfo->Fcb->ObjectInformation->AllocationSize = liSaveAlloc;
3283 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3284 AFS_TRACE_LEVEL_ERROR,
3285 "AFSProcessOverwriteSupersede (%08lX) Failed to update file information %wZ Status %08lX\n",
3287 &DirectoryCB->NameInformation.FileName,
3290 try_return( ntStatus);
3293 ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
3295 if( ulCreateDisposition == FILE_SUPERSEDE)
3298 pObjectInfo->FileAttributes = ulAttributes;
3304 pObjectInfo->FileAttributes |= ulAttributes;
3308 // Save off the access for the open
3311 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3314 IoUpdateShareAccess( pFileObject,
3315 &pObjectInfo->Fcb->ShareAccess);
3324 IoSetShareAccess( *pDesiredAccess,
3327 &pObjectInfo->Fcb->ShareAccess);
3331 // Return the correct action
3334 if( ulCreateDisposition == FILE_SUPERSEDE)
3337 Irp->IoStatus.Information = FILE_SUPERSEDED;
3342 Irp->IoStatus.Information = FILE_OVERWRITTEN;
3345 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
3347 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3348 AFS_TRACE_LEVEL_VERBOSE,
3349 "AFSProcessOverwriteSupersede Increment handle count on Fcb %08lX Cnt %d\n",
3354 // Increment the open reference and handle on the parent node
3357 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
3359 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3360 AFS_TRACE_LEVEL_VERBOSE,
3361 "AFSProcessOverwriteSupersede Increment child open handle count on Parent object %08lX Cnt %d\n",
3362 pObjectInfo->ParentObjectInformation,
3365 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
3367 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3368 AFS_TRACE_LEVEL_VERBOSE,
3369 "AFSProcessOverwriteSupersede Increment child open ref count on Parent object %08lX Cnt %d\n",
3370 pObjectInfo->ParentObjectInformation,
3373 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3375 bReleaseFcb = FALSE;
3377 *Fcb = pObjectInfo->Fcb;
3380 // Now that the Fcb->Resource has been dropped
3381 // we can call CcSetFileSizes. We are still holding
3382 // the PagingIoResource
3385 pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
3387 pFileObject->FsContext = (void *)pObjectInfo->Fcb;
3389 pFileObject->FsContext2 = (void *)*Ccb;
3391 CcSetFileSizes( pFileObject,
3392 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3399 AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3405 if( !NT_SUCCESS( ntStatus))
3408 // Decrement the open count on this Fcb.
3411 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
3413 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3414 AFS_TRACE_LEVEL_VERBOSE,
3415 "AFSProcessOverwriteSupersede Decrement2 count on Fcb %08lX Cnt %d\n",
3420 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3423 if( !NT_SUCCESS( ntStatus))
3436 // Fcb will be freed by AFSPrimaryVolumeWorker thread
3447 AFSControlDeviceCreate( IN PIRP Irp)
3450 NTSTATUS ntStatus = STATUS_SUCCESS;
3456 // For now, jsut let the open happen
3459 Irp->IoStatus.Information = FILE_OPENED;
3466 AFSOpenIOCtlFcb( IN PIRP Irp,
3468 IN AFSDirectoryCB *ParentDirCB,
3473 NTSTATUS ntStatus = STATUS_SUCCESS;
3474 PFILE_OBJECT pFileObject = NULL;
3475 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3476 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
3477 UNICODE_STRING uniFullFileName;
3478 AFSPIOCtlOpenCloseRequestCB stPIOCtlOpen;
3480 AFSObjectInfoCB *pParentObjectInfo = NULL;
3486 pFileObject = pIrpSp->FileObject;
3488 pParentObjectInfo = ParentDirCB->ObjectInformation;
3491 // If we haven't initialized the PIOCtl DirectoryCB for this directory then do it now
3494 if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB == NULL)
3497 ntStatus = AFSInitPIOCtlDirectoryCB( pParentObjectInfo);
3499 if( !NT_SUCCESS( ntStatus))
3502 try_return( ntStatus);
3507 // Allocate and initialize the Fcb for the file.
3510 ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB);
3512 *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
3514 if( !NT_SUCCESS( ntStatus))
3517 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3518 AFS_TRACE_LEVEL_ERROR,
3519 "AFSOpenIOCtlFcb (%08lX) Failed to initialize fcb Status %08lX\n",
3523 try_return( ntStatus);
3526 ntStatus = STATUS_SUCCESS;
3529 // Increment the open reference and handle on the node
3532 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3534 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3535 AFS_TRACE_LEVEL_VERBOSE,
3536 "AFSOpenIOCtlFcb Increment count on Fcb %08lX Cnt %d\n",
3543 // Initialize the Ccb for the file.
3546 ntStatus = AFSInitCcb( Ccb);
3548 if( !NT_SUCCESS( ntStatus))
3551 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3552 AFS_TRACE_LEVEL_ERROR,
3553 "AFSOpenIOCtlFcb (%08lX) Failed to initialize ccb Status %08lX\n",
3557 try_return( ntStatus);
3560 bAllocatedCcb = TRUE;
3566 (*Ccb)->DirectoryCB = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB;
3569 // Set the PIOCtl index
3572 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3574 RtlZeroMemory( &stPIOCtlOpen,
3575 sizeof( AFSPIOCtlOpenCloseRequestCB));
3577 stPIOCtlOpen.RequestId = (*Ccb)->RequestID;
3579 stPIOCtlOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3581 RtlZeroMemory( &stFileID,
3582 sizeof( AFSFileID));
3585 // The parent directory FID of the node
3588 stFileID = pParentObjectInfo->FileId;
3591 // Issue the open request to the service
3594 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_OPEN,
3595 AFS_REQUEST_FLAG_SYNCHRONOUS,
3599 (void *)&stPIOCtlOpen,
3600 sizeof( AFSPIOCtlOpenCloseRequestCB),
3604 if( !NT_SUCCESS( ntStatus))
3607 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3608 AFS_TRACE_LEVEL_ERROR,
3609 "AFSOpenIOCtlFcb (%08lX) Failed service open Status %08lX\n",
3613 try_return( ntStatus);
3617 // Reference the directory entry
3620 lCount = InterlockedIncrement( &((*Ccb)->DirectoryCB->DirOpenReferenceCount));
3622 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3623 AFS_TRACE_LEVEL_VERBOSE,
3624 "AFSOpenIOCtlFcb Increment count on %wZ DE %p Ccb %p Cnt %d\n",
3625 &(*Ccb)->DirectoryCB->NameInformation.FileName,
3626 (*Ccb)->DirectoryCB,
3631 // Increment the handle on the node
3634 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3636 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3637 AFS_TRACE_LEVEL_VERBOSE,
3638 "AFSOpenIOCtlFcb Increment handle count on Fcb %08lX Cnt %d\n",
3643 // Increment the open reference and handle on the parent node
3646 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3648 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3649 AFS_TRACE_LEVEL_VERBOSE,
3650 "AFSOpenIOCtlFcb Increment child open handle count on Parent object %08lX Cnt %d\n",
3654 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3656 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3657 AFS_TRACE_LEVEL_VERBOSE,
3658 "AFSOpenIOCtlFcb Increment child open ref count on Parent object %08lX Cnt %d\n",
3663 // Return the open result for this file
3666 Irp->IoStatus.Information = FILE_OPENED;
3671 //Dereference the passed in parent since the returned dir entry
3672 // is already referenced
3675 lCount = InterlockedDecrement( &ParentDirCB->DirOpenReferenceCount);
3677 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3678 AFS_TRACE_LEVEL_VERBOSE,
3679 "AFSOpenIOCtlFcb Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3680 &ParentDirCB->NameInformation.FileName,
3685 ASSERT( lCount >= 0);
3688 // If we created the Fcb we need to release the resources
3694 if( !NT_SUCCESS( ntStatus))
3697 // Decrement the open reference and handle on the node
3700 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3702 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3703 AFS_TRACE_LEVEL_VERBOSE,
3704 "AFSOpenIOCtlFcb Decrement count on Fcb %08lX Cnt %d\n",
3709 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3712 if( !NT_SUCCESS( ntStatus))
3725 // Fcb will be freed by AFSPrimaryVolumeWorker thread
3736 AFSOpenSpecialShareFcb( IN PIRP Irp,
3738 IN AFSDirectoryCB *DirectoryCB,
3743 NTSTATUS ntStatus = STATUS_SUCCESS;
3744 PFILE_OBJECT pFileObject = NULL;
3745 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3746 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE, bAllocateFcb = FALSE;
3747 AFSObjectInfoCB *pParentObjectInfo = NULL;
3748 AFSPipeOpenCloseRequestCB stPipeOpen;
3754 pFileObject = pIrpSp->FileObject;
3756 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3757 AFS_TRACE_LEVEL_VERBOSE_2,
3758 "AFSOpenSpecialShareFcb (%08lX) Processing Share %wZ open\n",
3760 &DirectoryCB->NameInformation.FileName);
3762 pParentObjectInfo = DirectoryCB->ObjectInformation->ParentObjectInformation;
3764 if( DirectoryCB->ObjectInformation->Fcb == NULL)
3768 // Allocate and initialize the Fcb for the file.
3771 ntStatus = AFSInitFcb( DirectoryCB);
3773 *Fcb = DirectoryCB->ObjectInformation->Fcb;
3775 if( !NT_SUCCESS( ntStatus))
3778 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3779 AFS_TRACE_LEVEL_ERROR,
3780 "AFSOpenSpecialShareFcb (%08lX) Failed to initialize fcb Status %08lX\n",
3784 try_return( ntStatus);
3787 if ( ntStatus != STATUS_REPARSE)
3790 bAllocateFcb = TRUE;
3793 ntStatus = STATUS_SUCCESS;
3798 *Fcb = DirectoryCB->ObjectInformation->Fcb;
3800 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
3805 // Increment the open count on this Fcb
3808 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3810 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3811 AFS_TRACE_LEVEL_VERBOSE,
3812 "AFSOpenSpecialShareFcb Increment count on Fcb %08lX Cnt %d\n",
3819 // Initialize the Ccb for the file.
3822 ntStatus = AFSInitCcb( Ccb);
3824 if( !NT_SUCCESS( ntStatus))
3827 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3828 AFS_TRACE_LEVEL_ERROR,
3829 "AFSOpenSpecialShareFcb (%08lX) Failed to initialize ccb Status %08lX\n",
3833 try_return( ntStatus);
3836 bAllocatedCcb = TRUE;
3842 (*Ccb)->DirectoryCB = DirectoryCB;
3845 // Call the service to open the share
3848 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3850 RtlZeroMemory( &stPipeOpen,
3851 sizeof( AFSPipeOpenCloseRequestCB));
3853 stPipeOpen.RequestId = (*Ccb)->RequestID;
3855 stPipeOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3858 // Issue the open request to the service
3861 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_OPEN,
3862 AFS_REQUEST_FLAG_SYNCHRONOUS,
3864 &DirectoryCB->NameInformation.FileName,
3866 (void *)&stPipeOpen,
3867 sizeof( AFSPipeOpenCloseRequestCB),
3871 if( !NT_SUCCESS( ntStatus))
3874 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3875 AFS_TRACE_LEVEL_ERROR,
3876 "AFSOpenSpecialShareFcb (%08lX) Failed service open Status %08lX\n",
3880 try_return( ntStatus);
3883 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3885 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3886 AFS_TRACE_LEVEL_VERBOSE,
3887 "AFSOpenSpecialShareFcb Increment handle count on Fcb %08lX Cnt %d\n",
3892 // Increment the open reference and handle on the parent node
3895 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3897 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3898 AFS_TRACE_LEVEL_VERBOSE,
3899 "AFSOpenSpecialShareFcb Increment child open handle count on Parent object %08lX Cnt %d\n",
3903 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3905 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3906 AFS_TRACE_LEVEL_VERBOSE,
3907 "AFSOpenSpecialShareFcb Increment child open ref count on Parent object %08lX Cnt %d\n",
3912 // Return the open result for this file
3915 Irp->IoStatus.Information = FILE_OPENED;
3922 if( !NT_SUCCESS( ntStatus))
3925 // Decrement the open count on this Fcb
3928 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3930 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3931 AFS_TRACE_LEVEL_VERBOSE,
3932 "AFSOpenSpecialShareFcb Decrement count on Fcb %08lX Cnt %d\n",
3937 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3940 if( !NT_SUCCESS( ntStatus))
3956 // Need to tear down this Fcb since it is not in the tree for the worker thread
3959 AFSAcquireExcl( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
3962 AFSRemoveFcb( &DirectoryCB->ObjectInformation->Fcb);
3964 AFSReleaseResource( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);