2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSCreate.cpp
39 #include "AFSCommon.h"
42 // Function: AFSCreate
46 // This function is the dispatch handler for the IRP_MJ_CREATE requests. It makes the determination to
47 // which interface this request is destined.
51 // A status is returned for the function. The Irp completion processing is handled in the specific
56 AFSCreate( IN PDEVICE_OBJECT LibDeviceObject,
59 UNREFERENCED_PARAMETER(LibDeviceObject);
60 NTSTATUS ntStatus = STATUS_SUCCESS;
61 IO_STACK_LOCATION *pIrpSp;
62 FILE_OBJECT *pFileObject = NULL;
67 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
68 pFileObject = pIrpSp->FileObject;
70 if( pFileObject == NULL ||
71 pFileObject->FileName.Buffer == NULL)
74 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
75 AFS_TRACE_LEVEL_VERBOSE,
76 "AFSCreate (%p) Processing control device open request\n",
79 ntStatus = AFSControlDeviceCreate( Irp);
81 try_return( ntStatus);
84 if( AFSRDRDeviceObject == NULL)
87 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
88 AFS_TRACE_LEVEL_VERBOSE,
89 "AFSCreate (%p) Invalid request to open before library is initialized\n",
92 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
95 ntStatus = AFSCommonCreate( AFSRDRDeviceObject,
102 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
107 "EXCEPTION - AFSCreate\n");
109 ntStatus = STATUS_ACCESS_DENIED;
111 AFSDumpTraceFilesFnc();
115 // Complete the request
118 AFSCompleteRequest( Irp,
125 AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
129 NTSTATUS ntStatus = STATUS_SUCCESS;
130 UNICODE_STRING uniFileName;
131 ULONG ulCreateDisposition = 0;
133 BOOLEAN bNoIntermediateBuffering = FALSE;
134 FILE_OBJECT *pFileObject = NULL;
135 IO_STACK_LOCATION *pIrpSp;
138 AFSDeviceExt *pDeviceExt = NULL;
139 BOOLEAN bOpenTargetDirectory = FALSE, bReleaseVolume = FALSE;
140 PACCESS_MASK pDesiredAccess = NULL;
141 UNICODE_STRING uniComponentName, uniRootFileName, uniParsedFileName;
142 UNICODE_STRING uniSubstitutedPathName;
143 UNICODE_STRING uniRelativeName;
144 AFSNameArrayHdr *pNameArray = NULL;
145 AFSVolumeCB *pVolumeCB = NULL;
146 AFSDirectoryCB *pParentDirectoryCB = NULL, *pDirectoryCB = NULL;
147 ULONG ulParseFlags = 0;
148 GUID stAuthGroup = {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 (%p) 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 (%p) 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 (%p) 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 (%p) 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 (%p) 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 (%p) 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 (%p) 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 (%p) 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 (%p) 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 (%p) 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 (%p) FileObject %p 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 (%p) Returning with NULL Fcb FileObject %p 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 (%p) STATUS_REPARSE FileObject %p 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 (%p) 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 %p 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 %p 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 (%p) 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 (%p) 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 (%p) 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 (%p) 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 (%p) 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 (%p) 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 %p 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 %p 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 ulAttributes = 0;
1712 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1713 PACCESS_MASK pDesiredAccess = NULL;
1714 USHORT usShareAccess;
1715 AFSDirectoryCB *pDirEntry = NULL;
1716 AFSObjectInfoCB *pParentObjectInfo = NULL;
1717 AFSObjectInfoCB *pObjectInfo = NULL;
1723 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1724 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1726 pFileObject = pIrpSp->FileObject;
1729 // Extract out the options
1732 ulOptions = pIrpSp->Parameters.Create.Options;
1735 // We pass all attributes they want to apply to the file to the create
1738 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1741 // If this is a directory create then set the attribute correctly
1744 if( ulOptions & FILE_DIRECTORY_FILE)
1747 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1750 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1751 AFS_TRACE_LEVEL_VERBOSE,
1752 "AFSProcessCreate (%p) Creating file %wZ Attributes %08lX\n",
1757 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1760 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1761 AFS_TRACE_LEVEL_ERROR,
1762 "AFSProcessCreate Request failed due to read only volume %wZ\n",
1765 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
1768 pParentObjectInfo = ParentDirCB->ObjectInformation;
1771 // Allocate and insert the direntry into the parent node
1774 ntStatus = AFSCreateDirEntry( AuthGroup,
1782 if( !NT_SUCCESS( ntStatus))
1785 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1786 AFS_TRACE_LEVEL_ERROR,
1787 "AFSProcessCreate (%p) Failed to create directory entry %wZ Status %08lX\n",
1792 try_return( ntStatus);
1795 bFileCreated = TRUE;
1797 pObjectInfo = pDirEntry->ObjectInformation;
1799 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1800 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1803 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1804 AFS_TRACE_LEVEL_VERBOSE,
1805 "AFSProcessCreate (%p) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1807 &pDirEntry->NameInformation.FileName,
1808 pObjectInfo->FileId.Cell,
1809 pObjectInfo->FileId.Volume,
1810 pObjectInfo->FileId.Vnode,
1811 pObjectInfo->FileId.Unique);
1813 ntStatus = AFSEvaluateNode( AuthGroup,
1816 if( !NT_SUCCESS( ntStatus))
1819 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
1822 if ( pParentObjectInfo == pObjectInfo->ParentObjectInformation)
1825 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1826 AFS_TRACE_LEVEL_ERROR,
1827 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1829 &pDirEntry->NameInformation.FileName,
1830 pObjectInfo->FileId.Cell,
1831 pObjectInfo->FileId.Volume,
1832 pObjectInfo->FileId.Vnode,
1833 pObjectInfo->FileId.Unique,
1834 pParentObjectInfo->FileId.Cell,
1835 pParentObjectInfo->FileId.Volume,
1836 pParentObjectInfo->FileId.Vnode,
1837 pParentObjectInfo->FileId.Unique,
1840 else if ( pObjectInfo->ParentObjectInformation == NULL)
1843 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1844 AFS_TRACE_LEVEL_ERROR,
1845 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
1847 &pDirEntry->NameInformation.FileName,
1848 pObjectInfo->FileId.Cell,
1849 pObjectInfo->FileId.Volume,
1850 pObjectInfo->FileId.Vnode,
1851 pObjectInfo->FileId.Unique,
1852 pParentObjectInfo->FileId.Cell,
1853 pParentObjectInfo->FileId.Volume,
1854 pParentObjectInfo->FileId.Vnode,
1855 pParentObjectInfo->FileId.Unique,
1861 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1862 AFS_TRACE_LEVEL_ERROR,
1863 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1865 &pDirEntry->NameInformation.FileName,
1866 pObjectInfo->FileId.Cell,
1867 pObjectInfo->FileId.Volume,
1868 pObjectInfo->FileId.Vnode,
1869 pObjectInfo->FileId.Unique,
1870 pParentObjectInfo->FileId.Cell,
1871 pParentObjectInfo->FileId.Volume,
1872 pParentObjectInfo->FileId.Vnode,
1873 pParentObjectInfo->FileId.Unique,
1874 pObjectInfo->ParentObjectInformation->FileId.Cell,
1875 pObjectInfo->ParentObjectInformation->FileId.Volume,
1876 pObjectInfo->ParentObjectInformation->FileId.Vnode,
1877 pObjectInfo->ParentObjectInformation->FileId.Unique,
1884 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1885 AFS_TRACE_LEVEL_ERROR,
1886 "AFSProcessCreate (%p) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1888 &pDirEntry->NameInformation.FileName,
1889 pObjectInfo->FileId.Cell,
1890 pObjectInfo->FileId.Volume,
1891 pObjectInfo->FileId.Vnode,
1892 pObjectInfo->FileId.Unique,
1896 try_return( ntStatus);
1899 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1903 // We may have raced and the Fcb is already created
1907 // Allocate and initialize the Fcb for the file.
1910 ntStatus = AFSInitFcb( pDirEntry);
1912 *Fcb = pObjectInfo->Fcb;
1914 if( !NT_SUCCESS( ntStatus))
1917 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1918 AFS_TRACE_LEVEL_ERROR,
1919 "AFSProcessCreate (%p) Failed to initialize fcb %wZ Status %08lX\n",
1924 try_return( ntStatus);
1927 ntStatus = STATUS_SUCCESS;
1930 // Increment the open count on this Fcb
1933 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1935 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1936 AFS_TRACE_LEVEL_VERBOSE,
1937 "AFSProcessCreate Increment count on Fcb %p Cnt %d\n",
1944 // Initialize the Ccb for the file.
1947 ntStatus = AFSInitCcb( Ccb);
1949 if( !NT_SUCCESS( ntStatus))
1952 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1953 AFS_TRACE_LEVEL_ERROR,
1954 "AFSProcessCreate (%p) Failed to initialize ccb %wZ Status %08lX\n",
1959 try_return( ntStatus);
1962 bAllocatedCcb = TRUE;
1965 // Initialize the Ccb
1968 (*Ccb)->DirectoryCB = pDirEntry;
1970 (*Ccb)->GrantedAccess = *pDesiredAccess;
1973 // If this is a file, update the headers filesizes.
1976 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1980 // Update the sizes with the information passed in
1983 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
1984 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1985 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1988 // Notify the system of the addition
1991 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1993 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1994 (ULONG)FILE_ACTION_ADDED);
1996 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
1998 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2002 // This is a new directory node so indicate it has been enumerated
2005 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
2008 // And the parent directory entry
2011 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2014 // Notify the system of the addition
2017 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2019 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2020 (ULONG)FILE_ACTION_ADDED);
2022 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2023 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2024 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2025 (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
2029 // And the parent directory entry
2032 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2035 // Notify the system of the addition
2038 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2040 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2041 (ULONG)FILE_ACTION_ADDED);
2045 // Save off the access for the open
2048 IoSetShareAccess( *pDesiredAccess,
2051 &(*Fcb)->ShareAccess);
2053 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2055 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2056 AFS_TRACE_LEVEL_VERBOSE,
2057 "AFSProcessCreate Increment handle count on Fcb %p Cnt %d\n",
2062 // Increment the open reference and handle on the parent node
2065 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2067 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2068 AFS_TRACE_LEVEL_VERBOSE,
2069 "AFSProcessCreate Increment child open handle count on Parent object %p Cnt %d\n",
2070 pObjectInfo->ParentObjectInformation,
2073 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2075 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2076 AFS_TRACE_LEVEL_VERBOSE,
2077 "AFSProcessCreate Increment child open ref count on Parent object %p Cnt %d\n",
2078 pObjectInfo->ParentObjectInformation,
2081 if( ulOptions & FILE_DELETE_ON_CLOSE)
2085 // Mark it for delete on close
2088 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2089 AFS_TRACE_LEVEL_VERBOSE,
2090 "AFSProcessCreate (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2095 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2099 // Indicate the object is locked in the service
2102 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2105 // Return the open result for this file
2108 Irp->IoStatus.Information = FILE_CREATED;
2113 // If we created the Fcb we need to release the resources
2119 if( !NT_SUCCESS( ntStatus))
2122 // Decrement the open count on this Fcb
2125 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2127 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2128 AFS_TRACE_LEVEL_VERBOSE,
2129 "AFSProcessCreate Decrement count on Fcb %p Cnt %d\n",
2134 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2137 if( !NT_SUCCESS( ntStatus))
2143 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2144 AFS_TRACE_LEVEL_VERBOSE,
2145 "AFSProcessCreate Create failed, removing DE %p from parent object %p Status %08lX\n",
2151 // Remove the dir entry from the parent
2154 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2157 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2159 AFSNotifyDelete( pDirEntry,
2164 // Decrement the reference added during initialization of the DE
2167 lCount = InterlockedDecrement( &pDirEntry->DirOpenReferenceCount);
2169 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2170 AFS_TRACE_LEVEL_VERBOSE,
2171 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2172 &pDirEntry->NameInformation.FileName,
2176 ASSERT( lCount >= 0);
2179 // Pull the directory entry from the parent
2182 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2184 FALSE); // Leave it in the enum list so the worker cleans it up
2187 // Tag the parent as needing verification
2190 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2192 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2194 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2205 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2218 AFSOpenTargetDirectory( IN PIRP Irp,
2219 IN AFSVolumeCB *VolumeCB,
2220 IN AFSDirectoryCB *ParentDirectoryCB,
2221 IN AFSDirectoryCB *TargetDirectoryCB,
2222 IN UNICODE_STRING *TargetName,
2226 UNREFERENCED_PARAMETER(VolumeCB);
2227 NTSTATUS ntStatus = STATUS_SUCCESS;
2228 PFILE_OBJECT pFileObject = NULL;
2229 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2230 PACCESS_MASK pDesiredAccess = NULL;
2231 USHORT usShareAccess;
2232 BOOLEAN bAllocatedCcb = FALSE;
2233 BOOLEAN bReleaseFcb = FALSE;
2234 AFSObjectInfoCB *pParentObject = NULL;
2235 UNICODE_STRING uniTargetName;
2241 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2242 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2244 pFileObject = pIrpSp->FileObject;
2246 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2247 AFS_TRACE_LEVEL_VERBOSE,
2248 "AFSOpenTargetDirectory (%p) Processing file %wZ\n",
2252 pParentObject = ParentDirectoryCB->ObjectInformation;
2254 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2257 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2261 // Make sure we have an Fcb for the access
2264 // Allocate and initialize the Fcb for the file.
2267 ntStatus = AFSInitFcb( ParentDirectoryCB);
2269 *Fcb = pParentObject->Fcb;
2271 if( !NT_SUCCESS( ntStatus))
2274 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2275 AFS_TRACE_LEVEL_ERROR,
2276 "AFSOpenTargetDirectory (%p) Failed to initialize fcb %wZ Status %08lX\n",
2278 &ParentDirectoryCB->NameInformation.FileName,
2281 try_return( ntStatus);
2284 ntStatus = STATUS_SUCCESS;
2287 // Increment the open count on this Fcb
2290 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2292 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2293 AFS_TRACE_LEVEL_VERBOSE,
2294 "AFSOpenTargetDirectory Increment count on Fcb %p Cnt %d\n",
2301 // If there are current opens on the Fcb, check the access.
2304 if( pParentObject->Fcb->OpenHandleCount > 0)
2307 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2310 &pParentObject->Fcb->ShareAccess,
2313 if( !NT_SUCCESS( ntStatus))
2316 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2317 AFS_TRACE_LEVEL_ERROR,
2318 "AFSOpenTargetDirectory (%p) Access check failure %wZ Status %08lX\n",
2320 &ParentDirectoryCB->NameInformation.FileName,
2323 try_return( ntStatus);
2328 // Initialize the Ccb for the file.
2331 ntStatus = AFSInitCcb( Ccb);
2333 if( !NT_SUCCESS( ntStatus))
2336 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2337 AFS_TRACE_LEVEL_ERROR,
2338 "AFSOpenTargetDirectory (%p) Failed to initialize ccb %wZ Status %08lX\n",
2340 &ParentDirectoryCB->NameInformation.FileName,
2343 try_return( ntStatus);
2346 bAllocatedCcb = TRUE;
2349 // Initialize the Ccb
2352 (*Ccb)->DirectoryCB = ParentDirectoryCB;
2354 (*Ccb)->GrantedAccess = *pDesiredAccess;
2356 if( TargetDirectoryCB != NULL &&
2357 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2363 Irp->IoStatus.Information = FILE_EXISTS;
2365 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2370 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2372 uniTargetName = *TargetName;
2376 // Update the filename in the fileobject for rename processing
2379 RtlCopyMemory( pFileObject->FileName.Buffer,
2380 uniTargetName.Buffer,
2381 uniTargetName.Length);
2383 pFileObject->FileName.Length = uniTargetName.Length;
2386 // OK, update the share access on the fileobject
2389 if( pParentObject->Fcb->OpenHandleCount > 0)
2392 IoUpdateShareAccess( pFileObject,
2393 &pParentObject->Fcb->ShareAccess);
2402 IoSetShareAccess( *pDesiredAccess,
2405 &pParentObject->Fcb->ShareAccess);
2408 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2410 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2411 AFS_TRACE_LEVEL_VERBOSE,
2412 "AFSOpenTargetDirectory Increment handle count on Fcb %p Cnt %d\n",
2417 // Increment the open reference and handle on the parent node
2420 if( pParentObject->ParentObjectInformation != NULL)
2423 lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2425 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2426 AFS_TRACE_LEVEL_VERBOSE,
2427 "AFSOpenTargetDirectory Increment child open handle count on Parent object %p Cnt %d\n",
2428 pParentObject->ParentObjectInformation,
2431 lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2433 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2434 AFS_TRACE_LEVEL_VERBOSE,
2435 "AFSOpenTargetDirectory Increment child open ref count on Parent object %p Cnt %d\n",
2436 pParentObject->ParentObjectInformation,
2445 if( !NT_SUCCESS( ntStatus))
2448 // Decrement the open count on this Fcb
2451 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2453 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2454 AFS_TRACE_LEVEL_VERBOSE,
2455 "AFSOpenTargetDirectory Decrement count on Fcb %p Cnt %d\n",
2460 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2463 if( !NT_SUCCESS( ntStatus))
2476 // Fcb will be freed by AFSPrimaryVolumeWorker thread
2487 AFSProcessOpen( IN PIRP Irp,
2489 IN AFSVolumeCB *VolumeCB,
2490 IN AFSDirectoryCB *ParentDirCB,
2491 IN AFSDirectoryCB *DirectoryCB,
2495 UNREFERENCED_PARAMETER(VolumeCB);
2496 NTSTATUS ntStatus = STATUS_SUCCESS;
2497 PFILE_OBJECT pFileObject = NULL;
2498 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2499 PACCESS_MASK pDesiredAccess = NULL;
2500 USHORT usShareAccess;
2501 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE;
2502 ULONG ulOptions = 0;
2503 AFSFileOpenCB stOpenCB;
2504 AFSFileOpenResultCB stOpenResultCB;
2505 ULONG ulResultLen = 0;
2506 AFSObjectInfoCB *pParentObjectInfo = NULL;
2507 AFSObjectInfoCB *pObjectInfo = NULL;
2508 ULONG ulFileAccess = 0;
2509 AFSFileAccessReleaseCB stReleaseFileAccess;
2515 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2516 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2518 pFileObject = pIrpSp->FileObject;
2520 pParentObjectInfo = ParentDirCB->ObjectInformation;
2522 pObjectInfo = DirectoryCB->ObjectInformation;
2525 // Check if the entry is pending a deletion
2528 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2531 ntStatus = STATUS_DELETE_PENDING;
2533 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2534 AFS_TRACE_LEVEL_ERROR,
2535 "AFSProcessOpen (%p) Entry pending delete %wZ Status %08lX\n",
2537 &DirectoryCB->NameInformation.FileName,
2540 try_return( ntStatus);
2544 // Extract out the options
2547 ulOptions = pIrpSp->Parameters.Create.Options;
2550 // Check if we should go and retrieve updated information for the node
2553 ntStatus = AFSValidateEntry( DirectoryCB,
2558 if( !NT_SUCCESS( ntStatus))
2561 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2562 AFS_TRACE_LEVEL_ERROR,
2563 "AFSProcessOpen (%p) Failed to validate entry %wZ Status %08lX\n",
2565 &DirectoryCB->NameInformation.FileName,
2568 try_return( ntStatus);
2572 // If this is marked for delete on close then be sure we can delete the entry
2575 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2578 ntStatus = AFSNotifyDelete( DirectoryCB,
2582 if( !NT_SUCCESS( ntStatus))
2585 ntStatus = STATUS_CANNOT_DELETE;
2587 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2588 AFS_TRACE_LEVEL_ERROR,
2589 "AFSProcessOpen (%p) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2591 &DirectoryCB->NameInformation.FileName,
2594 try_return( ntStatus);
2599 // Be sure we have an Fcb for the current object
2602 ntStatus = AFSInitFcb( DirectoryCB);
2604 if( !NT_SUCCESS( ntStatus))
2607 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2608 AFS_TRACE_LEVEL_ERROR,
2609 "AFSProcessOpen (%p) Failed to init fcb on %wZ Status %08lX\n",
2611 &DirectoryCB->NameInformation.FileName,
2614 try_return( ntStatus);
2617 ntStatus = STATUS_SUCCESS;
2620 // AFSInitFcb returns the Fcb resource held
2626 // Increment the open count on this Fcb
2629 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2631 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2632 AFS_TRACE_LEVEL_VERBOSE,
2633 "AFSProcessOpen Increment2 count on Fcb %p Cnt %d\n",
2638 // Check access on the entry
2641 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2644 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2647 &pObjectInfo->Fcb->ShareAccess,
2650 if( !NT_SUCCESS( ntStatus))
2653 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2654 AFS_TRACE_LEVEL_ERROR,
2655 "AFSProcessOpen (%p) Failed to check share access on %wZ Status %08lX\n",
2657 &DirectoryCB->NameInformation.FileName,
2660 try_return( ntStatus);
2665 // Additional checks
2668 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2672 // If the caller is asking for write access then try to flush the image section
2675 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2676 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2681 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2682 AFS_TRACE_LEVEL_VERBOSE,
2683 "AFSProcessOpen Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
2684 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2685 PsGetCurrentThread());
2687 AFSAcquireExcl( &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2690 bMmFlushed = MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2693 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
2694 AFS_TRACE_LEVEL_VERBOSE,
2695 "AFSProcessOpen Releasing Fcb SectionObject lock %p EXCL %08lX\n",
2696 &pObjectInfo->Fcb->NPFcb->SectionObjectResource,
2697 PsGetCurrentThread());
2699 AFSReleaseResource( &pObjectInfo->Fcb->NPFcb->SectionObjectResource);
2704 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2705 STATUS_SHARING_VIOLATION;
2707 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2708 AFS_TRACE_LEVEL_ERROR,
2709 "AFSProcessOpen (%p) Failed to flush image section %wZ Status %08lX\n",
2711 &DirectoryCB->NameInformation.FileName,
2714 try_return( ntStatus);
2718 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2721 ntStatus = STATUS_NOT_A_DIRECTORY;
2723 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2724 AFS_TRACE_LEVEL_ERROR,
2725 "AFSProcessOpen (%p) Attempt to open file as directory %wZ Status %08lX\n",
2727 &DirectoryCB->NameInformation.FileName,
2730 try_return( ntStatus);
2733 pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2735 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2736 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2739 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2742 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2744 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2745 AFS_TRACE_LEVEL_ERROR,
2746 "AFSProcessOpen (%p) Attempt to open directory as file %wZ Status %08lX\n",
2748 &DirectoryCB->NameInformation.FileName,
2751 try_return( ntStatus);
2754 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2755 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2756 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2757 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2764 try_return( ntStatus = STATUS_UNSUCCESSFUL);
2768 // Check with the service that we can open the file
2771 stOpenCB.ParentId = pParentObjectInfo->FileId;
2773 stOpenCB.DesiredAccess = *pDesiredAccess;
2775 stOpenCB.ShareAccess = usShareAccess;
2777 stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2779 stOpenCB.Identifier = (ULONGLONG)pFileObject;
2781 stOpenResultCB.GrantedAccess = 0;
2783 ulResultLen = sizeof( AFSFileOpenResultCB);
2785 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2786 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2788 &DirectoryCB->NameInformation.FileName,
2789 &pObjectInfo->FileId,
2791 sizeof( AFSFileOpenCB),
2792 (void *)&stOpenResultCB,
2795 if( !NT_SUCCESS( ntStatus))
2798 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2799 AFS_TRACE_LEVEL_ERROR,
2800 "AFSProcessOpen (%p) Failed open in service %wZ Status %08lX\n",
2802 &DirectoryCB->NameInformation.FileName,
2805 try_return( ntStatus);
2809 // Save the granted access in case we need to release it below
2812 ulFileAccess = stOpenResultCB.FileAccess;
2815 // Check if there is a conflict
2818 if( !AFSCheckAccess( *pDesiredAccess,
2819 stOpenResultCB.GrantedAccess,
2820 BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2823 ntStatus = STATUS_ACCESS_DENIED;
2825 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2826 AFS_TRACE_LEVEL_ERROR,
2827 "AFSProcessOpen (%p) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2830 stOpenResultCB.GrantedAccess,
2831 &DirectoryCB->NameInformation.FileName,
2834 try_return( ntStatus);
2838 // Initialize the Ccb for the file.
2841 ntStatus = AFSInitCcb( Ccb);
2843 if( !NT_SUCCESS( ntStatus))
2846 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2847 AFS_TRACE_LEVEL_ERROR,
2848 "AFSProcessOpen (%p) Failed to initialize ccb %wZ Status %08lX\n",
2850 &DirectoryCB->NameInformation.FileName,
2853 try_return( ntStatus);
2856 bAllocatedCcb = TRUE;
2858 (*Ccb)->DirectoryCB = DirectoryCB;
2860 (*Ccb)->FileAccess = ulFileAccess;
2862 (*Ccb)->GrantedAccess = *pDesiredAccess;
2865 // Perform the access check on the target if this is a mount point or symlink
2868 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2871 IoUpdateShareAccess( pFileObject,
2872 &pObjectInfo->Fcb->ShareAccess);
2881 IoSetShareAccess( *pDesiredAccess,
2884 &pObjectInfo->Fcb->ShareAccess);
2887 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2889 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2890 AFS_TRACE_LEVEL_VERBOSE,
2891 "AFSProcessOpen Increment handle count on Fcb %p Cnt %d\n",
2896 // Increment the open reference and handle on the parent node
2899 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2901 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2902 AFS_TRACE_LEVEL_VERBOSE,
2903 "AFSProcessOpen Increment child open handle count on Parent object %p Cnt %d\n",
2904 pObjectInfo->ParentObjectInformation,
2907 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2909 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2910 AFS_TRACE_LEVEL_VERBOSE,
2911 "AFSProcessOpen Increment child open ref count on Parent object %p Cnt %d\n",
2912 pObjectInfo->ParentObjectInformation,
2915 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2919 // Mark it for delete on close
2922 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2923 AFS_TRACE_LEVEL_VERBOSE,
2924 "AFSProcessOpen (%p) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2927 &DirectoryCB->NameInformation.FileName);
2929 SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2933 // Indicate the object is held
2936 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2939 // Return the open result for this file
2942 Irp->IoStatus.Information = FILE_OPENED;
2944 *Fcb = pObjectInfo->Fcb;
2951 if( !NT_SUCCESS( ntStatus))
2954 // Decrement the open count on this Fcb
2957 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2959 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2960 AFS_TRACE_LEVEL_VERBOSE,
2961 "AFSProcessOpen Decrement2 count on Fcb %p Cnt %d\n",
2966 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2969 if( !NT_SUCCESS( ntStatus))
2972 if ( ulFileAccess > 0)
2975 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2977 stReleaseFileAccess.FileAccess = ulFileAccess;
2979 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2981 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2982 AFS_REQUEST_FLAG_SYNCHRONOUS,
2984 &DirectoryCB->NameInformation.FileName,
2985 &pObjectInfo->FileId,
2986 (void *)&stReleaseFileAccess,
2987 sizeof( AFSFileAccessReleaseCB),
3002 // Fcb will be freed by AFSPrimaryVolumeWorker thread
3013 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
3015 IN AFSVolumeCB *VolumeCB,
3017 IN AFSDirectoryCB *ParentDirCB,
3018 IN AFSDirectoryCB *DirectoryCB,
3022 UNREFERENCED_PARAMETER(DeviceObject);
3023 NTSTATUS ntStatus = STATUS_SUCCESS;
3024 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3025 PFILE_OBJECT pFileObject = NULL;
3026 LARGE_INTEGER liZero = {0,0};
3027 BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
3028 ULONG ulAttributes = 0;
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 (%p) 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 (%p) 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 %p 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 (%p) 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 %p 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 %p 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 (%p) 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 (%p) 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 (%p) 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 %p 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 %p 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 %p 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 %p 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;
3455 if ( KernelMode == Irp->RequestorMode) {
3457 // For now, just let the open happen
3459 Irp->IoStatus.Information = FILE_OPENED;
3464 // Not from usermode, All access must be via
3465 // the FS component (which will do the
3468 ntStatus = STATUS_ACCESS_DENIED;
3476 AFSOpenIOCtlFcb( IN PIRP Irp,
3478 IN AFSDirectoryCB *ParentDirCB,
3483 NTSTATUS ntStatus = STATUS_SUCCESS;
3484 PFILE_OBJECT pFileObject = NULL;
3485 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3486 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
3487 AFSPIOCtlOpenCloseRequestCB stPIOCtlOpen;
3489 AFSObjectInfoCB *pParentObjectInfo = NULL;
3495 pFileObject = pIrpSp->FileObject;
3497 pParentObjectInfo = ParentDirCB->ObjectInformation;
3500 // If we haven't initialized the PIOCtl DirectoryCB for this directory then do it now
3503 if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB == NULL)
3506 ntStatus = AFSInitPIOCtlDirectoryCB( pParentObjectInfo);
3508 if( !NT_SUCCESS( ntStatus))
3511 try_return( ntStatus);
3516 // Allocate and initialize the Fcb for the file.
3519 ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB);
3521 *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
3523 if( !NT_SUCCESS( ntStatus))
3526 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3527 AFS_TRACE_LEVEL_ERROR,
3528 "AFSOpenIOCtlFcb (%p) Failed to initialize fcb Status %08lX\n",
3532 try_return( ntStatus);
3535 ntStatus = STATUS_SUCCESS;
3538 // Increment the open reference and handle on the node
3541 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3543 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3544 AFS_TRACE_LEVEL_VERBOSE,
3545 "AFSOpenIOCtlFcb Increment count on Fcb %p Cnt %d\n",
3552 // Initialize the Ccb for the file.
3555 ntStatus = AFSInitCcb( Ccb);
3557 if( !NT_SUCCESS( ntStatus))
3560 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3561 AFS_TRACE_LEVEL_ERROR,
3562 "AFSOpenIOCtlFcb (%p) Failed to initialize ccb Status %08lX\n",
3566 try_return( ntStatus);
3569 bAllocatedCcb = TRUE;
3575 (*Ccb)->DirectoryCB = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB;
3578 // Set the PIOCtl index
3581 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3583 RtlZeroMemory( &stPIOCtlOpen,
3584 sizeof( AFSPIOCtlOpenCloseRequestCB));
3586 stPIOCtlOpen.RequestId = (*Ccb)->RequestID;
3588 stPIOCtlOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3590 RtlZeroMemory( &stFileID,
3591 sizeof( AFSFileID));
3594 // The parent directory FID of the node
3597 stFileID = pParentObjectInfo->FileId;
3600 // Issue the open request to the service
3603 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_OPEN,
3604 AFS_REQUEST_FLAG_SYNCHRONOUS,
3608 (void *)&stPIOCtlOpen,
3609 sizeof( AFSPIOCtlOpenCloseRequestCB),
3613 if( !NT_SUCCESS( ntStatus))
3616 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3617 AFS_TRACE_LEVEL_ERROR,
3618 "AFSOpenIOCtlFcb (%p) Failed service open Status %08lX\n",
3622 try_return( ntStatus);
3626 // Reference the directory entry
3629 lCount = InterlockedIncrement( &((*Ccb)->DirectoryCB->DirOpenReferenceCount));
3631 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3632 AFS_TRACE_LEVEL_VERBOSE,
3633 "AFSOpenIOCtlFcb Increment count on %wZ DE %p Ccb %p Cnt %d\n",
3634 &(*Ccb)->DirectoryCB->NameInformation.FileName,
3635 (*Ccb)->DirectoryCB,
3640 // Increment the handle on the node
3643 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3645 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3646 AFS_TRACE_LEVEL_VERBOSE,
3647 "AFSOpenIOCtlFcb Increment handle count on Fcb %p Cnt %d\n",
3652 // Increment the open reference and handle on the parent node
3655 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3657 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3658 AFS_TRACE_LEVEL_VERBOSE,
3659 "AFSOpenIOCtlFcb Increment child open handle count on Parent object %p Cnt %d\n",
3663 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3665 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3666 AFS_TRACE_LEVEL_VERBOSE,
3667 "AFSOpenIOCtlFcb Increment child open ref count on Parent object %p Cnt %d\n",
3672 // Return the open result for this file
3675 Irp->IoStatus.Information = FILE_OPENED;
3680 //Dereference the passed in parent since the returned dir entry
3681 // is already referenced
3684 lCount = InterlockedDecrement( &ParentDirCB->DirOpenReferenceCount);
3686 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3687 AFS_TRACE_LEVEL_VERBOSE,
3688 "AFSOpenIOCtlFcb Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3689 &ParentDirCB->NameInformation.FileName,
3694 ASSERT( lCount >= 0);
3697 // If we created the Fcb we need to release the resources
3703 if( !NT_SUCCESS( ntStatus))
3706 // Decrement the open reference and handle on the node
3709 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3711 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3712 AFS_TRACE_LEVEL_VERBOSE,
3713 "AFSOpenIOCtlFcb Decrement count on Fcb %p Cnt %d\n",
3718 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3721 if( !NT_SUCCESS( ntStatus))
3734 // Fcb will be freed by AFSPrimaryVolumeWorker thread
3745 AFSOpenSpecialShareFcb( IN PIRP Irp,
3747 IN AFSDirectoryCB *DirectoryCB,
3752 NTSTATUS ntStatus = STATUS_SUCCESS;
3753 PFILE_OBJECT pFileObject = NULL;
3754 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3755 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE, bAllocateFcb = FALSE;
3756 AFSObjectInfoCB *pParentObjectInfo = NULL;
3757 AFSPipeOpenCloseRequestCB stPipeOpen;
3763 pFileObject = pIrpSp->FileObject;
3765 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3766 AFS_TRACE_LEVEL_VERBOSE_2,
3767 "AFSOpenSpecialShareFcb (%p) Processing Share %wZ open\n",
3769 &DirectoryCB->NameInformation.FileName);
3771 pParentObjectInfo = DirectoryCB->ObjectInformation->ParentObjectInformation;
3773 if( DirectoryCB->ObjectInformation->Fcb == NULL)
3777 // Allocate and initialize the Fcb for the file.
3780 ntStatus = AFSInitFcb( DirectoryCB);
3782 *Fcb = DirectoryCB->ObjectInformation->Fcb;
3784 if( !NT_SUCCESS( ntStatus))
3787 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3788 AFS_TRACE_LEVEL_ERROR,
3789 "AFSOpenSpecialShareFcb (%p) Failed to initialize fcb Status %08lX\n",
3793 try_return( ntStatus);
3796 if ( ntStatus != STATUS_REPARSE)
3799 bAllocateFcb = TRUE;
3802 ntStatus = STATUS_SUCCESS;
3807 *Fcb = DirectoryCB->ObjectInformation->Fcb;
3809 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
3814 // Increment the open count on this Fcb
3817 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3819 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3820 AFS_TRACE_LEVEL_VERBOSE,
3821 "AFSOpenSpecialShareFcb Increment count on Fcb %p Cnt %d\n",
3828 // Initialize the Ccb for the file.
3831 ntStatus = AFSInitCcb( Ccb);
3833 if( !NT_SUCCESS( ntStatus))
3836 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3837 AFS_TRACE_LEVEL_ERROR,
3838 "AFSOpenSpecialShareFcb (%p) Failed to initialize ccb Status %08lX\n",
3842 try_return( ntStatus);
3845 bAllocatedCcb = TRUE;
3851 (*Ccb)->DirectoryCB = DirectoryCB;
3854 // Call the service to open the share
3857 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3859 RtlZeroMemory( &stPipeOpen,
3860 sizeof( AFSPipeOpenCloseRequestCB));
3862 stPipeOpen.RequestId = (*Ccb)->RequestID;
3864 stPipeOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3867 // Issue the open request to the service
3870 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_OPEN,
3871 AFS_REQUEST_FLAG_SYNCHRONOUS,
3873 &DirectoryCB->NameInformation.FileName,
3875 (void *)&stPipeOpen,
3876 sizeof( AFSPipeOpenCloseRequestCB),
3880 if( !NT_SUCCESS( ntStatus))
3883 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3884 AFS_TRACE_LEVEL_ERROR,
3885 "AFSOpenSpecialShareFcb (%p) Failed service open Status %08lX\n",
3889 try_return( ntStatus);
3892 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3894 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3895 AFS_TRACE_LEVEL_VERBOSE,
3896 "AFSOpenSpecialShareFcb Increment handle count on Fcb %p Cnt %d\n",
3901 // Increment the open reference and handle on the parent node
3904 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3906 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3907 AFS_TRACE_LEVEL_VERBOSE,
3908 "AFSOpenSpecialShareFcb Increment child open handle count on Parent object %p Cnt %d\n",
3912 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3914 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3915 AFS_TRACE_LEVEL_VERBOSE,
3916 "AFSOpenSpecialShareFcb Increment child open ref count on Parent object %p Cnt %d\n",
3921 // Return the open result for this file
3924 Irp->IoStatus.Information = FILE_OPENED;
3931 if( !NT_SUCCESS( ntStatus))
3934 // Decrement the open count on this Fcb
3937 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3939 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3940 AFS_TRACE_LEVEL_VERBOSE,
3941 "AFSOpenSpecialShareFcb Decrement count on Fcb %p Cnt %d\n",
3946 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3949 if( !NT_SUCCESS( ntStatus))
3965 // Need to tear down this Fcb since it is not in the tree for the worker thread
3968 AFSAcquireExcl( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
3971 AFSRemoveFcb( &DirectoryCB->ObjectInformation->Fcb);
3973 AFSReleaseResource( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);