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->OpenReferenceCount);
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,
381 try_return( ntStatus);
385 // We have a reference on the root volume
388 bReleaseVolume = TRUE;
391 // Attempt to locate the node in the name tree if this is not a target
392 // open and the target is not the root
395 uniComponentName.Length = 0;
396 uniComponentName.Buffer = NULL;
398 if( uniFileName.Length > sizeof( WCHAR) ||
399 uniFileName.Buffer[ 0] != L'\\')
402 if( !AFSValidNameFormat( &uniFileName))
405 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
407 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
408 AFS_TRACE_LEVEL_VERBOSE,
409 "AFSCommonCreate (%08lX) Invalid name %wZ Status %08lX\n",
414 try_return( ntStatus);
418 // Opening a reparse point directly?
421 ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
423 if( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
425 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
426 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
427 AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
430 uniSubstitutedPathName = uniRootFileName;
432 ntStatus = AFSLocateNameEntry( &stAuthGroup,
437 ulNameProcessingFlags,
443 if( !NT_SUCCESS( ntStatus) &&
444 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
447 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
449 uniSubstitutedPathName.Buffer = NULL;
453 // The routine above released the root while walking the
457 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
458 AFS_TRACE_LEVEL_VERBOSE,
459 "AFSCommonCreate (%08lX) Failed to locate name entry for %wZ Status %08lX\n",
465 // We released any root volume locks in the above on failure
468 bReleaseVolume = FALSE;
470 try_return( ntStatus);
474 // Check for STATUS_REPARSE
477 if( ntStatus == STATUS_REPARSE)
480 uniSubstitutedPathName.Buffer = NULL;
483 // Update the information and return
486 Irp->IoStatus.Information = IO_REPARSE;
489 // We released the volume lock above
492 bReleaseVolume = FALSE;
494 try_return( ntStatus);
498 // If we re-allocated the name, then update our substitute name
501 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
504 uniSubstitutedPathName = uniRootFileName;
509 uniSubstitutedPathName.Buffer = NULL;
513 // Check for a symlink access
516 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
517 pParentDirectoryCB != NULL)
520 UNICODE_STRING uniFinalComponent;
522 uniFinalComponent.Length = 0;
523 uniFinalComponent.MaximumLength = 0;
524 uniFinalComponent.Buffer = NULL;
526 AFSRetrieveFinalComponent( &uniFileName,
529 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
532 if( !NT_SUCCESS( ntStatus) &&
533 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
536 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
537 AFS_TRACE_LEVEL_VERBOSE,
538 "AFSCommonCreate (%08lX) Failing access to symlink %wZ Status %08lX\n",
543 try_return( ntStatus);
549 // If we have no parent then this is a root open, be sure there is a directory entry
553 else if( pParentDirectoryCB == NULL &&
554 pDirectoryCB == NULL)
557 pDirectoryCB = pVolumeCB->DirectoryCB;
560 if( bOpenTargetDirectory)
564 // If we have a directory cb for the entry then dereference it and reference the parent
567 if( pDirectoryCB != NULL)
571 // Perform in this order to prevent thrashing
574 lCount = InterlockedIncrement( &pParentDirectoryCB->OpenReferenceCount);
576 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
577 AFS_TRACE_LEVEL_VERBOSE,
578 "AFSCommonCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
579 &pParentDirectoryCB->NameInformation.FileName,
585 // Do NOT decrement the reference count on the pDirectoryCB yet.
586 // The BackupEntry below might drop the count to zero leaving
587 // the entry subject to being deleted and we need some of the
588 // contents during later processing
591 AFSBackupEntry( pNameArray);
595 // OK, open the target directory
598 if( uniComponentName.Length == 0)
600 AFSRetrieveFinalComponent( &uniFileName,
604 ntStatus = AFSOpenTargetDirectory( Irp,
611 if( pDirectoryCB != NULL)
614 // It is now safe to drop the Reference Count
616 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
618 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
619 AFS_TRACE_LEVEL_VERBOSE,
620 "AFSCommonCreate Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
621 &pDirectoryCB->NameInformation.FileName,
627 if( !NT_SUCCESS( ntStatus))
630 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
631 AFS_TRACE_LEVEL_ERROR,
632 "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
633 &pParentDirectoryCB->NameInformation.FileName,
637 // Decrement the reference on the parent
640 lCount = InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
642 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
643 AFS_TRACE_LEVEL_VERBOSE,
644 "AFSCommonCreate Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
645 &pParentDirectoryCB->NameInformation.FileName,
651 try_return( ntStatus);
654 if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
657 if( pDirectoryCB == NULL ||
658 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
660 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
661 AFS_TRACE_LEVEL_VERBOSE,
662 "AFSCommonCreate (%08lX) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
666 pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0);
670 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
671 AFS_TRACE_LEVEL_VERBOSE,
672 "AFSCommonCreate (%08lX) Opening as reparse point %wZ Type %08lX\n",
675 pDirectoryCB->ObjectInformation->FileType);
677 bOpenedReparsePoint = TRUE;
682 // Based on the options passed in, process the file accordingly.
685 if( ulCreateDisposition == FILE_CREATE ||
686 ( ( ulCreateDisposition == FILE_OPEN_IF ||
687 ulCreateDisposition == FILE_OVERWRITE_IF) &&
688 pDirectoryCB == NULL))
692 BooleanFlagOn( pVolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
695 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
696 AFS_TRACE_LEVEL_VERBOSE,
697 "AFSCommonCreate ReadOnly Device on create Status %08lX\n",
700 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
702 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
703 AFS_TRACE_LEVEL_VERBOSE,
704 "AFSCommonCreate Decrement13 count on %wZ DE %p Ccb %p Cnt %d\n",
705 &pParentDirectoryCB->NameInformation.FileName,
708 pParentDirectoryCB->OpenReferenceCount);
710 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
713 if( uniComponentName.Length == 0 ||
714 pDirectoryCB != NULL)
718 // We traversed the entire path so we found each entry,
719 // fail with collision
722 if( pDirectoryCB != NULL)
725 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
726 AFS_TRACE_LEVEL_VERBOSE,
727 "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
728 &pDirectoryCB->NameInformation.FileName,
731 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
733 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
734 AFS_TRACE_LEVEL_VERBOSE,
735 "AFSCommonCreate Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
736 &pDirectoryCB->NameInformation.FileName,
744 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
745 AFS_TRACE_LEVEL_VERBOSE,
746 "AFSCommonCreate Object name collision on create Status %08lX\n",
749 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
751 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
752 AFS_TRACE_LEVEL_VERBOSE,
753 "AFSCommonCreate Decrement5 count on %wZ DE %p Ccb %p Cnt %d\n",
754 &pParentDirectoryCB->NameInformation.FileName,
757 pParentDirectoryCB->OpenReferenceCount);
760 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
764 // OK, go and create the node
767 ntStatus = AFSProcessCreate( Irp,
777 if( !NT_SUCCESS( ntStatus))
780 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
781 AFS_TRACE_LEVEL_ERROR,
782 "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
784 &pParentDirectoryCB->NameInformation.FileName,
789 // Dereference the parent entry
792 lCount = InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
794 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
795 AFS_TRACE_LEVEL_VERBOSE,
796 "AFSCreate Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
797 &pParentDirectoryCB->NameInformation.FileName,
802 try_return( ntStatus);
806 // We should not have an extra component except for PIOCtl opens
809 if( uniComponentName.Length > 0)
813 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
816 if( RtlCompareUnicodeString( &AFSPIOCtlName,
821 ntStatus = AFSOpenIOCtlFcb( Irp,
827 if( !NT_SUCCESS( ntStatus))
830 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
831 AFS_TRACE_LEVEL_ERROR,
832 "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
840 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
841 AFS_TRACE_LEVEL_VERBOSE,
842 "AFSCommonCreate (%08lX) File %wZ name not found\n",
846 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
849 if( !NT_SUCCESS( ntStatus))
853 // Dereference the parent entry
856 if( pDirectoryCB != NULL)
859 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
861 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
862 AFS_TRACE_LEVEL_VERBOSE,
863 "AFSCommonCreate Decrement7a count on %wZ DE %p Ccb %p Cnt %d\n",
864 &pDirectoryCB->NameInformation.FileName,
872 lCount = InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
874 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
875 AFS_TRACE_LEVEL_VERBOSE,
876 "AFSCommonCreate Decrement7b count on %wZ DE %p Ccb %p Cnt %d\n",
877 &pParentDirectoryCB->NameInformation.FileName,
884 try_return( ntStatus);
888 // For root opens the parent will be NULL
891 if( pParentDirectoryCB == NULL)
895 // Check for the delete on close flag for the root
898 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
901 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
902 AFS_TRACE_LEVEL_ERROR,
903 "AFSCommonCreate (%08lX) Attempt to open root as delete on close\n",
906 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
908 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
909 AFS_TRACE_LEVEL_VERBOSE,
910 "AFSCommonCreate Decrement8 count on %wZ DE %p Ccb %p Cnt %d\n",
911 &pDirectoryCB->NameInformation.FileName,
916 try_return( ntStatus = STATUS_CANNOT_DELETE);
920 // If this is the target directory, then bail
923 if( bOpenTargetDirectory)
926 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
927 AFS_TRACE_LEVEL_ERROR,
928 "AFSCommonCreate (%08lX) Attempt to open root as target directory\n",
931 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
933 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
934 AFS_TRACE_LEVEL_VERBOSE,
935 "AFSCommonCreate Decrement9 count on %wZ DE %p Ccb %p Cnt %d\n",
936 &pDirectoryCB->NameInformation.FileName,
941 try_return( ntStatus = STATUS_INVALID_PARAMETER);
945 // Go and open the root of the volume
948 ntStatus = AFSOpenRoot( Irp,
954 if( !NT_SUCCESS( ntStatus))
957 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
958 AFS_TRACE_LEVEL_ERROR,
959 "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
960 pVolumeCB->ObjectInformation.FileId.Cell,
961 pVolumeCB->ObjectInformation.FileId.Volume,
964 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
966 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
967 AFS_TRACE_LEVEL_VERBOSE,
968 "AFSCommonCreate Decrement10 count on %wZ DE %p Ccb %p Cnt %d\n",
969 &pDirectoryCB->NameInformation.FileName,
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->OpenReferenceCount);
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,
1031 try_return( ntStatus);
1035 // Trying to open the file
1038 ntStatus = AFSProcessOpen( Irp,
1046 if( !NT_SUCCESS( ntStatus))
1049 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1050 AFS_TRACE_LEVEL_ERROR,
1051 "AFSCommonCreate Failed open on %wZ Status %08lX\n",
1052 &pDirectoryCB->NameInformation.FileName,
1055 lCount = InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
1057 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1058 AFS_TRACE_LEVEL_VERBOSE,
1059 "AFSCommonCreate Decrement12 count on %wZ DE %p Ccb %p Cnt %d\n",
1060 &pDirectoryCB->NameInformation.FileName,
1068 if( NT_SUCCESS( ntStatus) &&
1069 ntStatus != STATUS_REPARSE)
1075 AFSAcquireExcl( &pCcb->NPCcb->CcbLock,
1078 RtlCopyMemory( &pCcb->AuthGroup,
1083 // If we have a substitute name, then use it
1086 if( uniSubstitutedPathName.Buffer != NULL)
1089 pCcb->FullFileName = uniSubstitutedPathName;
1091 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1093 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1098 pCcb->FullFileName = uniRootFileName;
1100 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1103 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1105 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1109 if( bOpenedReparsePoint)
1111 SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1114 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1115 AFS_TRACE_LEVEL_VERBOSE,
1116 "AFSCommonCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1117 &pCcb->DirectoryCB->NameInformation.FileName,
1120 pCcb->DirectoryCB->OpenReferenceCount);
1122 ASSERT( pCcb->DirectoryCB->OpenReferenceCount > 0);
1124 pCcb->CurrentDirIndex = 0;
1126 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1129 SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1133 // Save off the name array for this instance
1136 pCcb->NameArray = pNameArray;
1140 AFSReleaseResource( &pCcb->NPCcb->CcbLock);
1144 // If we make it here then init the FO for the request.
1147 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1148 AFS_TRACE_LEVEL_VERBOSE_2,
1149 "AFSCommonCreate (%08lX) FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1155 pFileObject->FsContext = (void *)pFcb;
1157 pFileObject->FsContext2 = (void *)pCcb;
1162 ASSERT( pFcb->OpenHandleCount > 0);
1164 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1167 // For files perform additional processing
1170 switch( pFcb->Header.NodeTypeCode)
1177 pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1182 // If the user did not request nobuffering then mark the FO as cacheable
1185 if( bNoIntermediateBuffering)
1188 pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1193 pFileObject->Flags |= FO_CACHE_SUPPORTED;
1197 // If the file was opened for execution then we need to set the bit in the FO
1200 if( BooleanFlagOn( *pDesiredAccess,
1204 SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1208 // Update the last access time
1211 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1222 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1223 AFS_TRACE_LEVEL_ERROR,
1224 "AFSCommonCreate (%08lX) Returning with NULL Fcb FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1233 if( NT_SUCCESS( ntStatus) &&
1234 ntStatus == STATUS_REPARSE)
1237 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1238 AFS_TRACE_LEVEL_ERROR,
1239 "AFSCommonCreate (%08lX) STATUS_REPARSE FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1247 // Free up the sub name if we have one
1250 if( uniSubstitutedPathName.Buffer != NULL)
1253 AFSExFreePoolWithTag( uniSubstitutedPathName.Buffer, 0);
1255 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1260 // Free up the name array ...
1263 if( pNameArray != NULL)
1266 AFSFreeNameArray( pNameArray);
1269 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1272 AFSExFreePoolWithTag( uniRootFileName.Buffer, 0);
1278 lCount = InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1280 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1281 AFS_TRACE_LEVEL_VERBOSE,
1282 "AFSCommonCreate Decrement count on Volume %08lX Cnt %d\n",
1288 // Setup the Irp for completion, the Information has been set previously
1291 Irp->IoStatus.Status = ntStatus;
1298 AFSOpenAFSRoot( IN PIRP Irp,
1303 NTSTATUS ntStatus = STATUS_SUCCESS;
1310 // Initialize the Ccb for the file.
1313 ntStatus = AFSInitCcb( Ccb);
1315 if( !NT_SUCCESS( ntStatus))
1318 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1319 AFS_TRACE_LEVEL_ERROR,
1320 "AFSOpenAFSRoot (%08lX) Failed to allocate Ccb\n",
1323 try_return( ntStatus);
1330 (*Ccb)->DirectoryCB = AFSGlobalRoot->DirectoryCB;
1333 // Increment the open count on this Fcb
1336 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1338 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1339 AFS_TRACE_LEVEL_VERBOSE,
1340 "AFSOpenAFSRoot Increment count on Fcb %08lX Cnt %d\n",
1341 AFSGlobalRoot->RootFcb,
1344 lCount = InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1346 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1347 AFS_TRACE_LEVEL_VERBOSE,
1348 "AFSOpenAFSRoot Increment handle count on Fcb %08lX Cnt %d\n",
1349 AFSGlobalRoot->RootFcb,
1352 *Fcb = AFSGlobalRoot->RootFcb;
1355 // Return the open result for this file
1358 Irp->IoStatus.Information = FILE_OPENED;
1369 AFSOpenRoot( IN PIRP Irp,
1370 IN AFSVolumeCB *VolumeCB,
1372 OUT AFSFcb **RootFcb,
1376 NTSTATUS ntStatus = STATUS_SUCCESS;
1377 PFILE_OBJECT pFileObject = NULL;
1378 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1379 PACCESS_MASK pDesiredAccess = NULL;
1380 USHORT usShareAccess;
1382 BOOLEAN bAllocatedCcb = FALSE;
1383 BOOLEAN bReleaseFcb = FALSE;
1384 AFSFileOpenCB stOpenCB;
1385 AFSFileOpenResultCB stOpenResultCB;
1386 ULONG ulResultLen = 0;
1392 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1393 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1394 ulOptions = pIrpSp->Parameters.Create.Options;
1396 pFileObject = pIrpSp->FileObject;
1398 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
1401 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
1403 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1404 AFS_TRACE_LEVEL_ERROR,
1405 "AFSOpenRoot (%08lX) Attempt to open root as file Status %08lX\n",
1409 try_return( ntStatus);
1413 // Check if we should go and retrieve updated information for the node
1416 ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1420 if( !NT_SUCCESS( ntStatus))
1423 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1424 AFS_TRACE_LEVEL_ERROR,
1425 "AFSOpenRoot (%08lX) Failed to validate root entry Status %08lX\n",
1429 try_return( ntStatus);
1433 // Check with the service that we can open the file
1436 RtlZeroMemory( &stOpenCB,
1437 sizeof( AFSFileOpenCB));
1439 stOpenCB.DesiredAccess = *pDesiredAccess;
1441 stOpenCB.ShareAccess = usShareAccess;
1443 stOpenResultCB.GrantedAccess = 0;
1445 ulResultLen = sizeof( AFSFileOpenResultCB);
1447 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1448 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1451 &VolumeCB->ObjectInformation.FileId,
1453 sizeof( AFSFileOpenCB),
1454 (void *)&stOpenResultCB,
1457 if( !NT_SUCCESS( ntStatus))
1460 UNICODE_STRING uniGUID;
1463 uniGUID.MaximumLength = 0;
1464 uniGUID.Buffer = NULL;
1466 if( AuthGroup != NULL)
1468 RtlStringFromGUID( *AuthGroup,
1472 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1473 AFS_TRACE_LEVEL_ERROR,
1474 "AFSOpenRoot (%08lX) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1476 VolumeCB->ObjectInformation.FileId.Cell,
1477 VolumeCB->ObjectInformation.FileId.Volume,
1481 if( AuthGroup != NULL)
1483 RtlFreeUnicodeString( &uniGUID);
1486 try_return( ntStatus);
1490 // If the entry is not initialized then do it now
1493 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1496 AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1499 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1502 ntStatus = AFSEnumerateDirectory( AuthGroup,
1503 &VolumeCB->ObjectInformation,
1506 if( !NT_SUCCESS( ntStatus))
1509 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1511 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1512 AFS_TRACE_LEVEL_ERROR,
1513 "AFSOpenRoot (%08lX) Failed to enumerate directory Status %08lX\n",
1517 try_return( ntStatus);
1520 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1523 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1527 // If the root fcb has been initialized then check access otherwise
1528 // init the volume fcb
1531 if( VolumeCB->RootFcb == NULL)
1534 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1537 if( !NT_SUCCESS( ntStatus))
1540 try_return( ntStatus);
1546 AFSAcquireExcl( VolumeCB->RootFcb->Header.Resource,
1553 // If there are current opens on the Fcb, check the access.
1556 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1559 ntStatus = IoCheckShareAccess( *pDesiredAccess,
1562 &VolumeCB->RootFcb->ShareAccess,
1565 if( !NT_SUCCESS( ntStatus))
1568 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1569 AFS_TRACE_LEVEL_ERROR,
1570 "AFSOpenRoot (%08lX) Access check failure Status %08lX\n",
1574 try_return( ntStatus);
1579 // Initialize the Ccb for the file.
1582 ntStatus = AFSInitCcb( Ccb);
1584 if( !NT_SUCCESS( ntStatus))
1587 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1588 AFS_TRACE_LEVEL_ERROR,
1589 "AFSOpenRoot (%08lX) Failed to allocate Ccb Status %08lX\n",
1593 try_return( ntStatus);
1596 bAllocatedCcb = TRUE;
1602 (*Ccb)->DirectoryCB = VolumeCB->DirectoryCB;
1604 (*Ccb)->GrantedAccess = *pDesiredAccess;
1607 // OK, update the share access on the fileobject
1610 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1613 IoUpdateShareAccess( pFileObject,
1614 &VolumeCB->RootFcb->ShareAccess);
1623 IoSetShareAccess( *pDesiredAccess,
1626 &VolumeCB->RootFcb->ShareAccess);
1630 // Increment the open count on this Fcb
1633 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1635 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1636 AFS_TRACE_LEVEL_VERBOSE,
1637 "AFSOpenRoot Increment count on Fcb %08lX Cnt %d\n",
1641 lCount = InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1643 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1644 AFS_TRACE_LEVEL_VERBOSE,
1645 "AFSOpenRoot Increment handle count on Fcb %08lX Cnt %d\n",
1650 // Indicate the object is held
1653 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1656 // Return the open result for this file
1659 Irp->IoStatus.Information = FILE_OPENED;
1661 *RootFcb = VolumeCB->RootFcb;
1668 AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1671 if( !NT_SUCCESS( ntStatus))
1683 Irp->IoStatus.Information = 0;
1691 AFSProcessCreate( IN PIRP Irp,
1693 IN AFSVolumeCB *VolumeCB,
1694 IN AFSDirectoryCB *ParentDirCB,
1695 IN PUNICODE_STRING FileName,
1696 IN PUNICODE_STRING ComponentName,
1697 IN PUNICODE_STRING FullFileName,
1702 NTSTATUS ntStatus = STATUS_SUCCESS;
1703 PFILE_OBJECT pFileObject = NULL;
1704 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1705 ULONG ulOptions = 0;
1706 ULONG ulShareMode = 0;
1708 ULONG ulAttributes = 0;
1709 LARGE_INTEGER liAllocationSize = {0,0};
1710 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1711 BOOLEAN bAllocatedFcb = FALSE;
1712 PACCESS_MASK pDesiredAccess = NULL;
1713 USHORT usShareAccess;
1714 AFSDirectoryCB *pDirEntry = NULL;
1715 AFSObjectInfoCB *pParentObjectInfo = NULL;
1716 AFSObjectInfoCB *pObjectInfo = NULL;
1722 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1723 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1725 pFileObject = pIrpSp->FileObject;
1728 // Extract out the options
1731 ulOptions = pIrpSp->Parameters.Create.Options;
1734 // We pass all attributes they want to apply to the file to the create
1737 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1740 // If this is a directory create then set the attribute correctly
1743 if( ulOptions & FILE_DIRECTORY_FILE)
1746 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1749 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1750 AFS_TRACE_LEVEL_VERBOSE,
1751 "AFSProcessCreate (%08lX) Creating file %wZ Attributes %08lX\n",
1756 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1759 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1760 AFS_TRACE_LEVEL_ERROR,
1761 "AFSProcessCreate Request failed due to read only volume %wZ\n",
1764 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
1767 pParentObjectInfo = ParentDirCB->ObjectInformation;
1770 // Allocate and insert the direntry into the parent node
1773 ntStatus = AFSCreateDirEntry( AuthGroup,
1781 if( !NT_SUCCESS( ntStatus))
1784 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1785 AFS_TRACE_LEVEL_ERROR,
1786 "AFSProcessCreate (%08lX) Failed to create directory entry %wZ Status %08lX\n",
1791 try_return( ntStatus);
1794 bFileCreated = TRUE;
1796 pObjectInfo = pDirEntry->ObjectInformation;
1798 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1799 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1802 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1803 AFS_TRACE_LEVEL_VERBOSE,
1804 "AFSProcessCreate (%08lX) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1806 &pDirEntry->NameInformation.FileName,
1807 pObjectInfo->FileId.Cell,
1808 pObjectInfo->FileId.Volume,
1809 pObjectInfo->FileId.Vnode,
1810 pObjectInfo->FileId.Unique);
1812 ntStatus = AFSEvaluateNode( AuthGroup,
1815 if( !NT_SUCCESS( ntStatus))
1818 if ( ntStatus == STATUS_NOT_A_DIRECTORY)
1821 if ( pParentObjectInfo == pObjectInfo->ParentObjectInformation)
1824 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1825 AFS_TRACE_LEVEL_ERROR,
1826 "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1828 &pDirEntry->NameInformation.FileName,
1829 pObjectInfo->FileId.Cell,
1830 pObjectInfo->FileId.Volume,
1831 pObjectInfo->FileId.Vnode,
1832 pObjectInfo->FileId.Unique,
1833 pParentObjectInfo->FileId.Cell,
1834 pParentObjectInfo->FileId.Volume,
1835 pParentObjectInfo->FileId.Vnode,
1836 pParentObjectInfo->FileId.Unique,
1839 else if ( pObjectInfo->ParentObjectInformation == NULL)
1842 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1843 AFS_TRACE_LEVEL_ERROR,
1844 "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != NULL Status %08lX\n",
1846 &pDirEntry->NameInformation.FileName,
1847 pObjectInfo->FileId.Cell,
1848 pObjectInfo->FileId.Volume,
1849 pObjectInfo->FileId.Vnode,
1850 pObjectInfo->FileId.Unique,
1851 pParentObjectInfo->FileId.Cell,
1852 pParentObjectInfo->FileId.Volume,
1853 pParentObjectInfo->FileId.Vnode,
1854 pParentObjectInfo->FileId.Unique,
1860 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1861 AFS_TRACE_LEVEL_ERROR,
1862 "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX PARENT %08lX-%08lX-%08lX-%08lX != %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1864 &pDirEntry->NameInformation.FileName,
1865 pObjectInfo->FileId.Cell,
1866 pObjectInfo->FileId.Volume,
1867 pObjectInfo->FileId.Vnode,
1868 pObjectInfo->FileId.Unique,
1869 pParentObjectInfo->FileId.Cell,
1870 pParentObjectInfo->FileId.Volume,
1871 pParentObjectInfo->FileId.Vnode,
1872 pParentObjectInfo->FileId.Unique,
1873 pObjectInfo->ParentObjectInformation->FileId.Cell,
1874 pObjectInfo->ParentObjectInformation->FileId.Volume,
1875 pObjectInfo->ParentObjectInformation->FileId.Vnode,
1876 pObjectInfo->ParentObjectInformation->FileId.Unique,
1883 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1884 AFS_TRACE_LEVEL_ERROR,
1885 "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
1887 &pDirEntry->NameInformation.FileName,
1888 pObjectInfo->FileId.Cell,
1889 pObjectInfo->FileId.Volume,
1890 pObjectInfo->FileId.Vnode,
1891 pObjectInfo->FileId.Unique,
1895 try_return( ntStatus);
1898 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1902 // We may have raced and the Fcb is already created
1905 if( pObjectInfo->Fcb != NULL)
1908 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1909 AFS_TRACE_LEVEL_VERBOSE,
1910 "AFSProcessCreate (%08lX) Not allocating Fcb for file %wZ\n",
1914 *Fcb = pObjectInfo->Fcb;
1916 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
1923 // Allocate and initialize the Fcb for the file.
1926 ntStatus = AFSInitFcb( pDirEntry);
1928 *Fcb = pObjectInfo->Fcb;
1930 if( !NT_SUCCESS( ntStatus))
1933 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1934 AFS_TRACE_LEVEL_ERROR,
1935 "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
1940 try_return( ntStatus);
1943 if ( ntStatus != STATUS_REPARSE)
1946 bAllocatedFcb = TRUE;
1949 ntStatus = STATUS_SUCCESS;
1953 // Increment the open count on this Fcb
1956 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
1958 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1959 AFS_TRACE_LEVEL_VERBOSE,
1960 "AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n",
1967 // Initialize the Ccb for the file.
1970 ntStatus = AFSInitCcb( Ccb);
1972 if( !NT_SUCCESS( ntStatus))
1975 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1976 AFS_TRACE_LEVEL_ERROR,
1977 "AFSProcessCreate (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
1982 try_return( ntStatus);
1985 bAllocatedCcb = TRUE;
1988 // Initialize the Ccb
1991 (*Ccb)->DirectoryCB = pDirEntry;
1993 (*Ccb)->GrantedAccess = *pDesiredAccess;
1996 // If this is a file, update the headers filesizes.
1999 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
2003 // Update the sizes with the information passed in
2006 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
2007 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2008 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
2011 // Notify the system of the addition
2014 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2016 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
2017 (ULONG)FILE_ACTION_ADDED);
2019 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2021 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
2025 // This is a new directory node so indicate it has been enumerated
2028 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
2031 // And the parent directory entry
2034 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2037 // Notify the system of the addition
2040 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2042 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2043 (ULONG)FILE_ACTION_ADDED);
2045 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2046 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2047 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2048 (*Fcb)->Header.NodeTypeCode == AFS_INVALID_FCB)
2052 // And the parent directory entry
2055 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
2058 // Notify the system of the addition
2061 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
2063 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
2064 (ULONG)FILE_ACTION_ADDED);
2068 // Save off the access for the open
2071 IoSetShareAccess( *pDesiredAccess,
2074 &(*Fcb)->ShareAccess);
2076 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2078 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2079 AFS_TRACE_LEVEL_VERBOSE,
2080 "AFSProcessCreate Increment handle count on Fcb %08lX Cnt %d\n",
2085 // Increment the open reference and handle on the parent node
2088 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2090 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2091 AFS_TRACE_LEVEL_VERBOSE,
2092 "AFSProcessCreate Increment child open handle count on Parent object %08lX Cnt %d\n",
2093 pObjectInfo->ParentObjectInformation,
2096 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2098 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2099 AFS_TRACE_LEVEL_VERBOSE,
2100 "AFSProcessCreate Increment child open ref count on Parent object %08lX Cnt %d\n",
2101 pObjectInfo->ParentObjectInformation,
2104 if( ulOptions & FILE_DELETE_ON_CLOSE)
2108 // Mark it for delete on close
2111 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2112 AFS_TRACE_LEVEL_VERBOSE,
2113 "AFSProcessCreate (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2118 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2122 // Indicate the object is locked in the service
2125 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2128 // Return the open result for this file
2131 Irp->IoStatus.Information = FILE_CREATED;
2136 // If we created the Fcb we need to release the resources
2142 if( !NT_SUCCESS( ntStatus))
2145 // Decrement the open count on this Fcb
2148 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
2150 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2151 AFS_TRACE_LEVEL_VERBOSE,
2152 "AFSProcessCreate Decrement count on Fcb %08lX Cnt %d\n",
2157 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2160 if( !NT_SUCCESS( ntStatus))
2166 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2167 AFS_TRACE_LEVEL_VERBOSE,
2168 "AFSProcessCreate Create failed, removing DE %p from aprent object %p Status %08lX\n",
2174 // Remove the dir entry from the parent
2177 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2180 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2182 AFSNotifyDelete( pDirEntry,
2187 // Decrement the reference added during initialization of the DE
2190 lCount = InterlockedDecrement( &pDirEntry->OpenReferenceCount);
2192 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2193 AFS_TRACE_LEVEL_VERBOSE,
2194 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2195 &pDirEntry->NameInformation.FileName,
2200 // Pull the directory entry from the parent
2203 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2205 FALSE); // Leave it in the enum list so the worker cleans it up
2208 // Tag the parent as needing verification
2211 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2213 pParentObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
2215 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2228 AFSAcquireExcl( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
2231 AFSRemoveFcb( &pObjectInfo->Fcb);
2233 AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
2246 AFSOpenTargetDirectory( IN PIRP Irp,
2247 IN AFSVolumeCB *VolumeCB,
2248 IN AFSDirectoryCB *ParentDirectoryCB,
2249 IN AFSDirectoryCB *TargetDirectoryCB,
2250 IN UNICODE_STRING *TargetName,
2255 NTSTATUS ntStatus = STATUS_SUCCESS;
2256 PFILE_OBJECT pFileObject = NULL;
2257 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2258 PACCESS_MASK pDesiredAccess = NULL;
2259 USHORT usShareAccess;
2260 BOOLEAN bAllocatedCcb = FALSE;
2261 BOOLEAN bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2262 AFSObjectInfoCB *pParentObject = NULL, *pTargetObject = NULL;
2263 UNICODE_STRING uniTargetName;
2269 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2270 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2272 pFileObject = pIrpSp->FileObject;
2274 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2275 AFS_TRACE_LEVEL_VERBOSE,
2276 "AFSOpenTargetDirectory (%08lX) Processing file %wZ\n",
2280 pParentObject = ParentDirectoryCB->ObjectInformation;
2282 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2285 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2289 // Make sure we have an Fcb for the access
2292 if( pParentObject->Fcb != NULL)
2295 *Fcb = pParentObject->Fcb;
2297 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
2304 // Allocate and initialize the Fcb for the file.
2307 ntStatus = AFSInitFcb( ParentDirectoryCB);
2309 *Fcb = pParentObject->Fcb;
2311 if( !NT_SUCCESS( ntStatus))
2314 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2315 AFS_TRACE_LEVEL_ERROR,
2316 "AFSOpenTargetDirectory (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
2318 &ParentDirectoryCB->NameInformation.FileName,
2321 try_return( ntStatus);
2324 if ( ntStatus != STATUS_REPARSE)
2327 bAllocatedFcb = TRUE;
2330 ntStatus = STATUS_SUCCESS;
2334 // Increment the open count on this Fcb
2337 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2339 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2340 AFS_TRACE_LEVEL_VERBOSE,
2341 "AFSOpenTargetDirectory Increment count on Fcb %08lX Cnt %d\n",
2348 // If there are current opens on the Fcb, check the access.
2351 if( pParentObject->Fcb->OpenHandleCount > 0)
2354 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2357 &pParentObject->Fcb->ShareAccess,
2360 if( !NT_SUCCESS( ntStatus))
2363 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2364 AFS_TRACE_LEVEL_ERROR,
2365 "AFSOpenTargetDirectory (%08lX) Access check failure %wZ Status %08lX\n",
2367 &ParentDirectoryCB->NameInformation.FileName,
2370 try_return( ntStatus);
2375 // Initialize the Ccb for the file.
2378 ntStatus = AFSInitCcb( Ccb);
2380 if( !NT_SUCCESS( ntStatus))
2383 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2384 AFS_TRACE_LEVEL_ERROR,
2385 "AFSOpenTargetDirectory (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2387 &ParentDirectoryCB->NameInformation.FileName,
2390 try_return( ntStatus);
2393 bAllocatedCcb = TRUE;
2396 // Initialize the Ccb
2399 (*Ccb)->DirectoryCB = ParentDirectoryCB;
2401 (*Ccb)->GrantedAccess = *pDesiredAccess;
2403 if( TargetDirectoryCB != NULL &&
2404 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2410 Irp->IoStatus.Information = FILE_EXISTS;
2412 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2417 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2419 uniTargetName = *TargetName;
2423 // Update the filename in the fileobject for rename processing
2426 RtlCopyMemory( pFileObject->FileName.Buffer,
2427 uniTargetName.Buffer,
2428 uniTargetName.Length);
2430 pFileObject->FileName.Length = uniTargetName.Length;
2433 // OK, update the share access on the fileobject
2436 if( pParentObject->Fcb->OpenHandleCount > 0)
2439 IoUpdateShareAccess( pFileObject,
2440 &pParentObject->Fcb->ShareAccess);
2449 IoSetShareAccess( *pDesiredAccess,
2452 &pParentObject->Fcb->ShareAccess);
2455 lCount = InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2457 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2458 AFS_TRACE_LEVEL_VERBOSE,
2459 "AFSOpenTargetDirectory Increment handle count on Fcb %08lX Cnt %d\n",
2464 // Increment the open reference and handle on the parent node
2467 if( pParentObject->ParentObjectInformation != NULL)
2470 lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2472 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2473 AFS_TRACE_LEVEL_VERBOSE,
2474 "AFSOpenTargetDirectory Increment child open handle count on Parent object %08lX Cnt %d\n",
2475 pParentObject->ParentObjectInformation,
2478 lCount = InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2480 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2481 AFS_TRACE_LEVEL_VERBOSE,
2482 "AFSOpenTargetDirectory Increment child open ref count on Parent object %08lX Cnt %d\n",
2483 pParentObject->ParentObjectInformation,
2492 if( !NT_SUCCESS( ntStatus))
2495 // Decrement the open count on this Fcb
2498 lCount = InterlockedDecrement( &pParentObject->Fcb->OpenReferenceCount);
2500 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2501 AFS_TRACE_LEVEL_VERBOSE,
2502 "AFSOpenTargetDirectory Decrement count on Fcb %08lX Cnt %d\n",
2507 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2510 if( !NT_SUCCESS( ntStatus))
2525 AFSAcquireExcl( &pParentObject->NonPagedInfo->ObjectInfoLock,
2528 AFSRemoveFcb( &pParentObject->Fcb);
2530 AFSReleaseResource( &pParentObject->NonPagedInfo->ObjectInfoLock);
2541 AFSProcessOpen( IN PIRP Irp,
2543 IN AFSVolumeCB *VolumeCB,
2544 IN AFSDirectoryCB *ParentDirCB,
2545 IN AFSDirectoryCB *DirectoryCB,
2550 NTSTATUS ntStatus = STATUS_SUCCESS;
2551 PFILE_OBJECT pFileObject = NULL;
2552 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2553 PACCESS_MASK pDesiredAccess = NULL;
2554 USHORT usShareAccess;
2555 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2556 ULONG ulAdditionalFlags = 0, ulOptions = 0;
2557 AFSFileOpenCB stOpenCB;
2558 AFSFileOpenResultCB stOpenResultCB;
2559 ULONG ulResultLen = 0;
2560 AFSObjectInfoCB *pParentObjectInfo = NULL;
2561 AFSObjectInfoCB *pObjectInfo = NULL;
2562 ULONG ulFileAccess = 0;
2563 AFSFileAccessReleaseCB stReleaseFileAccess;
2569 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2570 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2572 pFileObject = pIrpSp->FileObject;
2574 pParentObjectInfo = ParentDirCB->ObjectInformation;
2576 pObjectInfo = DirectoryCB->ObjectInformation;
2579 // Check if the entry is pending a deletion
2582 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2585 ntStatus = STATUS_DELETE_PENDING;
2587 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2588 AFS_TRACE_LEVEL_ERROR,
2589 "AFSProcessOpen (%08lX) Entry pending delete %wZ Status %08lX\n",
2591 &DirectoryCB->NameInformation.FileName,
2594 try_return( ntStatus);
2598 // Extract out the options
2601 ulOptions = pIrpSp->Parameters.Create.Options;
2604 // Check if we should go and retrieve updated information for the node
2607 ntStatus = AFSValidateEntry( DirectoryCB,
2611 if( !NT_SUCCESS( ntStatus))
2614 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2615 AFS_TRACE_LEVEL_ERROR,
2616 "AFSProcessOpen (%08lX) Failed to validate entry %wZ Status %08lX\n",
2618 &DirectoryCB->NameInformation.FileName,
2621 try_return( ntStatus);
2625 // If this is marked for delete on close then be sure we can delete the entry
2628 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2631 ntStatus = AFSNotifyDelete( DirectoryCB,
2635 if( !NT_SUCCESS( ntStatus))
2638 ntStatus = STATUS_CANNOT_DELETE;
2640 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2641 AFS_TRACE_LEVEL_ERROR,
2642 "AFSProcessOpen (%08lX) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2644 &DirectoryCB->NameInformation.FileName,
2647 try_return( ntStatus);
2652 // Be sure we have an Fcb for the current object
2655 ntStatus = AFSInitFcb( DirectoryCB);
2657 if( !NT_SUCCESS( ntStatus))
2660 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2661 AFS_TRACE_LEVEL_ERROR,
2662 "AFSProcessOpen (%08lX) Failed to init fcb on %wZ Status %08lX\n",
2664 &DirectoryCB->NameInformation.FileName,
2667 try_return( ntStatus);
2670 if ( ntStatus != STATUS_REPARSE)
2673 bAllocatedFcb = TRUE;
2676 ntStatus = STATUS_SUCCESS;
2679 // AFSInitFcb returns the Fcb resource held
2685 // Increment the open count on this Fcb
2688 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2690 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2691 AFS_TRACE_LEVEL_VERBOSE,
2692 "AFSProcessOpen Increment2 count on Fcb %08lX Cnt %d\n",
2697 // Check access on the entry
2700 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2703 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2706 &pObjectInfo->Fcb->ShareAccess,
2709 if( !NT_SUCCESS( ntStatus))
2712 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2713 AFS_TRACE_LEVEL_ERROR,
2714 "AFSProcessOpen (%08lX) Failed to check share access on %wZ Status %08lX\n",
2716 &DirectoryCB->NameInformation.FileName,
2719 try_return( ntStatus);
2724 // Additional checks
2727 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2731 // If the caller is asking for write access then try to flush the image section
2734 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2735 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2738 if( !MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2742 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2743 STATUS_SHARING_VIOLATION;
2745 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2746 AFS_TRACE_LEVEL_ERROR,
2747 "AFSProcessOpen (%08lX) Failed to flush image section %wZ Status %08lX\n",
2749 &DirectoryCB->NameInformation.FileName,
2752 try_return( ntStatus);
2756 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2759 ntStatus = STATUS_NOT_A_DIRECTORY;
2761 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2762 AFS_TRACE_LEVEL_ERROR,
2763 "AFSProcessOpen (%08lX) Attempt to open file as directory %wZ Status %08lX\n",
2765 &DirectoryCB->NameInformation.FileName,
2768 try_return( ntStatus);
2771 pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2773 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2774 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2777 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2780 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2782 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2783 AFS_TRACE_LEVEL_ERROR,
2784 "AFSProcessOpen (%08lX) Attempt to open directory as file %wZ Status %08lX\n",
2786 &DirectoryCB->NameInformation.FileName,
2789 try_return( ntStatus);
2792 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2793 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2794 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB ||
2795 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_INVALID_FCB)
2802 try_return( ntStatus = STATUS_UNSUCCESSFUL);
2806 // Check with the service that we can open the file
2809 stOpenCB.ParentId = pParentObjectInfo->FileId;
2811 stOpenCB.DesiredAccess = *pDesiredAccess;
2813 stOpenCB.ShareAccess = usShareAccess;
2815 stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2817 stOpenCB.Identifier = (ULONGLONG)pFileObject;
2819 stOpenResultCB.GrantedAccess = 0;
2821 ulResultLen = sizeof( AFSFileOpenResultCB);
2823 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2824 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2826 &DirectoryCB->NameInformation.FileName,
2827 &pObjectInfo->FileId,
2829 sizeof( AFSFileOpenCB),
2830 (void *)&stOpenResultCB,
2833 if( !NT_SUCCESS( ntStatus))
2836 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2837 AFS_TRACE_LEVEL_ERROR,
2838 "AFSProcessOpen (%08lX) Failed open in service %wZ Status %08lX\n",
2840 &DirectoryCB->NameInformation.FileName,
2843 try_return( ntStatus);
2847 // Save the granted access in case we need to release it below
2850 ulFileAccess = stOpenResultCB.FileAccess;
2853 // Check if there is a conflict
2856 if( !AFSCheckAccess( *pDesiredAccess,
2857 stOpenResultCB.GrantedAccess,
2858 BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2861 ntStatus = STATUS_ACCESS_DENIED;
2863 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2864 AFS_TRACE_LEVEL_ERROR,
2865 "AFSProcessOpen (%08lX) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2868 stOpenResultCB.GrantedAccess,
2869 &DirectoryCB->NameInformation.FileName,
2872 try_return( ntStatus);
2876 // Initialize the Ccb for the file.
2879 ntStatus = AFSInitCcb( Ccb);
2881 if( !NT_SUCCESS( ntStatus))
2884 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2885 AFS_TRACE_LEVEL_ERROR,
2886 "AFSProcessOpen (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2888 &DirectoryCB->NameInformation.FileName,
2891 try_return( ntStatus);
2894 bAllocatedCcb = TRUE;
2896 (*Ccb)->DirectoryCB = DirectoryCB;
2898 (*Ccb)->FileAccess = ulFileAccess;
2900 (*Ccb)->GrantedAccess = *pDesiredAccess;
2903 // Perform the access check on the target if this is a mount point or symlink
2906 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2909 IoUpdateShareAccess( pFileObject,
2910 &pObjectInfo->Fcb->ShareAccess);
2919 IoSetShareAccess( *pDesiredAccess,
2922 &pObjectInfo->Fcb->ShareAccess);
2925 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2927 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2928 AFS_TRACE_LEVEL_VERBOSE,
2929 "AFSProcessOpen Increment handle count on Fcb %08lX Cnt %d\n",
2934 // Increment the open reference and handle on the parent node
2937 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2939 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2940 AFS_TRACE_LEVEL_VERBOSE,
2941 "AFSProcessOpen Increment child open handle count on Parent object %08lX Cnt %d\n",
2942 pObjectInfo->ParentObjectInformation,
2945 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2947 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2948 AFS_TRACE_LEVEL_VERBOSE,
2949 "AFSProcessOpen Increment child open ref count on Parent object %08lX Cnt %d\n",
2950 pObjectInfo->ParentObjectInformation,
2953 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2957 // Mark it for delete on close
2960 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2961 AFS_TRACE_LEVEL_VERBOSE,
2962 "AFSProcessOpen (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2965 &DirectoryCB->NameInformation.FileName);
2967 SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2971 // Indicate the object is held
2974 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2977 // Return the open result for this file
2980 Irp->IoStatus.Information = FILE_OPENED;
2982 *Fcb = pObjectInfo->Fcb;
2989 if( !NT_SUCCESS( ntStatus))
2992 // Decrement the open count on this Fcb
2995 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2997 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2998 AFS_TRACE_LEVEL_VERBOSE,
2999 "AFSProcessOpen Decrement2 count on Fcb %08lX Cnt %d\n",
3004 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3007 if( !NT_SUCCESS( ntStatus))
3010 if ( ulFileAccess > 0)
3013 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
3015 stReleaseFileAccess.FileAccess = ulFileAccess;
3017 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
3019 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
3020 AFS_REQUEST_FLAG_SYNCHRONOUS,
3022 &DirectoryCB->NameInformation.FileName,
3023 &pObjectInfo->FileId,
3024 (void *)&stReleaseFileAccess,
3025 sizeof( AFSFileAccessReleaseCB),
3042 AFSAcquireExcl( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
3045 AFSRemoveFcb( &pObjectInfo->Fcb);
3047 AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
3058 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
3060 IN AFSVolumeCB *VolumeCB,
3062 IN AFSDirectoryCB *ParentDirCB,
3063 IN AFSDirectoryCB *DirectoryCB,
3068 NTSTATUS ntStatus = STATUS_SUCCESS;
3069 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3070 PFILE_OBJECT pFileObject = NULL;
3071 LARGE_INTEGER liZero = {0,0};
3072 BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
3073 ULONG ulAttributes = 0;
3074 LARGE_INTEGER liTime;
3075 ULONG ulCreateDisposition = 0;
3076 BOOLEAN bAllocatedCcb = FALSE, bAllocatedFcb = FALSE;
3077 PACCESS_MASK pDesiredAccess = NULL;
3078 USHORT usShareAccess;
3079 AFSObjectInfoCB *pParentObjectInfo = NULL;
3080 AFSObjectInfoCB *pObjectInfo = NULL;
3082 LARGE_INTEGER liSaveSize;
3083 LARGE_INTEGER liSaveVDL;
3084 LARGE_INTEGER liSaveAlloc;
3089 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
3091 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
3093 pFileObject = pIrpSp->FileObject;
3095 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
3097 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
3099 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
3102 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3103 AFS_TRACE_LEVEL_ERROR,
3104 "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
3106 &DirectoryCB->NameInformation.FileName);
3108 try_return( ntStatus = STATUS_MEDIA_WRITE_PROTECTED);
3111 pParentObjectInfo = ParentDirCB->ObjectInformation;
3113 pObjectInfo = DirectoryCB->ObjectInformation;
3116 // Check if we should go and retrieve updated information for the node
3119 ntStatus = AFSValidateEntry( DirectoryCB,
3123 if( !NT_SUCCESS( ntStatus))
3126 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3127 AFS_TRACE_LEVEL_ERROR,
3128 "AFSProcessOverwriteSupersede (%08lX) Failed to validate entry %wZ Status %08lX\n",
3130 &DirectoryCB->NameInformation.FileName,
3133 try_return( ntStatus);
3137 // Be sure we have an Fcb for the object block
3140 if( pObjectInfo->Fcb == NULL)
3143 ntStatus = AFSInitFcb( DirectoryCB);
3145 *Fcb = pObjectInfo->Fcb;
3147 if( !NT_SUCCESS( ntStatus))
3150 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3151 AFS_TRACE_LEVEL_ERROR,
3152 "AFSProcessOverwriteSupersede (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
3154 &DirectoryCB->NameInformation.FileName,
3157 try_return( ntStatus);
3160 if ( ntStatus != STATUS_REPARSE)
3163 bAllocatedFcb = TRUE;
3166 ntStatus = STATUS_SUCCESS;
3171 AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
3176 // Increment the open count on this Fcb.
3179 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3181 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3182 AFS_TRACE_LEVEL_VERBOSE,
3183 "AFSProcessOverwriteSupersede Increment2 count on Fcb %08lX Cnt %d\n",
3190 // Check access on the entry
3193 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3196 ntStatus = IoCheckShareAccess( *pDesiredAccess,
3199 &pObjectInfo->Fcb->ShareAccess,
3202 if( !NT_SUCCESS( ntStatus))
3205 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3206 AFS_TRACE_LEVEL_ERROR,
3207 "AFSProcessOverwriteSupersede (%08lX) Access check failure %wZ Status %08lX\n",
3209 &DirectoryCB->NameInformation.FileName,
3212 try_return( ntStatus);
3217 // Before we actually truncate, check to see if the purge
3218 // is going to fail.
3221 if( !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3225 ntStatus = STATUS_USER_MAPPED_FILE;
3227 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3228 AFS_TRACE_LEVEL_ERROR,
3229 "AFSProcessOverwriteSupersede (%08lX) File user mapped %wZ Status %08lX\n",
3231 &DirectoryCB->NameInformation.FileName,
3234 try_return( ntStatus);
3238 // Initialize the Ccb for the file.
3241 ntStatus = AFSInitCcb( Ccb);
3243 if( !NT_SUCCESS( ntStatus))
3246 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3247 AFS_TRACE_LEVEL_ERROR,
3248 "AFSProcessOverwriteSupersede (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
3250 &DirectoryCB->NameInformation.FileName,
3253 try_return( ntStatus);
3256 bAllocatedCcb = TRUE;
3259 // Initialize the Ccb
3262 (*Ccb)->DirectoryCB = DirectoryCB;
3264 (*Ccb)->GrantedAccess = *pDesiredAccess;
3267 // Set the file length to zero
3270 AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3273 bReleasePaging = TRUE;
3275 liSaveSize = pObjectInfo->Fcb->Header.FileSize;
3276 liSaveAlloc = pObjectInfo->Fcb->Header.AllocationSize;
3277 liSaveVDL = pObjectInfo->Fcb->Header.ValidDataLength;
3279 pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3280 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3281 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3283 pObjectInfo->EndOfFile.QuadPart = 0;
3284 pObjectInfo->AllocationSize.QuadPart = 0;
3287 // Trim down the extents. We do this BEFORE telling the service
3288 // the file is truncated since there is a potential race between
3289 // a worker thread releasing extents and us trimming
3292 AFSTrimExtents( pObjectInfo->Fcb,
3293 &pObjectInfo->Fcb->Header.FileSize);
3295 KeQuerySystemTime( &pObjectInfo->ChangeTime);
3297 KeQuerySystemTime( &pObjectInfo->LastAccessTime);
3299 KeQuerySystemTime( &pObjectInfo->LastWriteTime);
3302 // Set the update flag accordingly
3305 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
3306 AFS_FCB_FLAG_UPDATE_CREATE_TIME |
3307 AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
3308 AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
3309 AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
3311 ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
3315 if( !NT_SUCCESS( ntStatus))
3318 pObjectInfo->Fcb->Header.ValidDataLength = liSaveVDL;
3319 pObjectInfo->Fcb->Header.FileSize = liSaveSize;
3320 pObjectInfo->Fcb->Header.AllocationSize = liSaveAlloc;
3321 pObjectInfo->Fcb->ObjectInformation->EndOfFile = liSaveSize;
3322 pObjectInfo->Fcb->ObjectInformation->AllocationSize = liSaveAlloc;
3324 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3325 AFS_TRACE_LEVEL_ERROR,
3326 "AFSProcessOverwriteSupersede (%08lX) Failed to update file information %wZ Status %08lX\n",
3328 &DirectoryCB->NameInformation.FileName,
3331 try_return( ntStatus);
3334 ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
3336 if( ulCreateDisposition == FILE_SUPERSEDE)
3339 pObjectInfo->FileAttributes = ulAttributes;
3345 pObjectInfo->FileAttributes |= ulAttributes;
3349 // Save off the access for the open
3352 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3355 IoUpdateShareAccess( pFileObject,
3356 &pObjectInfo->Fcb->ShareAccess);
3365 IoSetShareAccess( *pDesiredAccess,
3368 &pObjectInfo->Fcb->ShareAccess);
3372 // Return the correct action
3375 if( ulCreateDisposition == FILE_SUPERSEDE)
3378 Irp->IoStatus.Information = FILE_SUPERSEDED;
3383 Irp->IoStatus.Information = FILE_OVERWRITTEN;
3386 lCount = InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
3388 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3389 AFS_TRACE_LEVEL_VERBOSE,
3390 "AFSProcessOverwriteSupersede Increment handle count on Fcb %08lX Cnt %d\n",
3395 // Increment the open reference and handle on the parent node
3398 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
3400 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3401 AFS_TRACE_LEVEL_VERBOSE,
3402 "AFSProcessOverwriteSupersede Increment child open handle count on Parent object %08lX Cnt %d\n",
3403 pObjectInfo->ParentObjectInformation,
3406 lCount = InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
3408 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3409 AFS_TRACE_LEVEL_VERBOSE,
3410 "AFSProcessOverwriteSupersede Increment child open ref count on Parent object %08lX Cnt %d\n",
3411 pObjectInfo->ParentObjectInformation,
3414 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3416 bReleaseFcb = FALSE;
3418 *Fcb = pObjectInfo->Fcb;
3421 // Now that the Fcb->Resource has been dropped
3422 // we can call CcSetFileSizes. We are still holding
3423 // the PagingIoResource
3426 pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
3428 pFileObject->FsContext = (void *)pObjectInfo->Fcb;
3430 pFileObject->FsContext2 = (void *)*Ccb;
3432 CcSetFileSizes( pFileObject,
3433 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3440 AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3446 if( !NT_SUCCESS( ntStatus))
3449 // Decrement the open count on this Fcb.
3452 lCount = InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
3454 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3455 AFS_TRACE_LEVEL_VERBOSE,
3456 "AFSProcessOverwriteSupersede Decrement2 count on Fcb %08lX Cnt %d\n",
3461 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3464 if( !NT_SUCCESS( ntStatus))
3479 AFSAcquireExcl( &pObjectInfo->NonPagedInfo->ObjectInfoLock,
3482 AFSRemoveFcb( &pObjectInfo->Fcb);
3484 AFSReleaseResource( &pObjectInfo->NonPagedInfo->ObjectInfoLock);
3495 AFSControlDeviceCreate( IN PIRP Irp)
3498 NTSTATUS ntStatus = STATUS_SUCCESS;
3504 // For now, jsut let the open happen
3507 Irp->IoStatus.Information = FILE_OPENED;
3514 AFSOpenIOCtlFcb( IN PIRP Irp,
3516 IN AFSDirectoryCB *ParentDirCB,
3521 NTSTATUS ntStatus = STATUS_SUCCESS;
3522 PFILE_OBJECT pFileObject = NULL;
3523 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3524 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE, bAllocatedFcb = FALSE;
3525 UNICODE_STRING uniFullFileName;
3526 AFSPIOCtlOpenCloseRequestCB stPIOCtlOpen;
3528 AFSObjectInfoCB *pParentObjectInfo = NULL;
3534 pFileObject = pIrpSp->FileObject;
3536 pParentObjectInfo = ParentDirCB->ObjectInformation;
3539 // If we haven't initialized the PIOCtl DirectoryCB for this directory then do it now
3542 if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB == NULL)
3545 ntStatus = AFSInitPIOCtlDirectoryCB( pParentObjectInfo);
3547 if( !NT_SUCCESS( ntStatus))
3550 try_return( ntStatus);
3554 if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb == NULL)
3558 // Allocate and initialize the Fcb for the file.
3561 ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB);
3563 *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
3565 if( !NT_SUCCESS( ntStatus))
3568 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3569 AFS_TRACE_LEVEL_ERROR,
3570 "AFSOpenIOCtlFcb (%08lX) Failed to initialize fcb Status %08lX\n",
3574 try_return( ntStatus);
3577 if ( ntStatus != STATUS_REPARSE)
3580 bAllocatedFcb = TRUE;
3583 ntStatus = STATUS_SUCCESS;
3588 *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
3590 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
3595 // Increment the open reference and handle on the node
3598 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3600 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3601 AFS_TRACE_LEVEL_VERBOSE,
3602 "AFSOpenIOCtlFcb Increment count on Fcb %08lX Cnt %d\n",
3609 // Initialize the Ccb for the file.
3612 ntStatus = AFSInitCcb( Ccb);
3614 if( !NT_SUCCESS( ntStatus))
3617 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3618 AFS_TRACE_LEVEL_ERROR,
3619 "AFSOpenIOCtlFcb (%08lX) Failed to initialize ccb Status %08lX\n",
3623 try_return( ntStatus);
3626 bAllocatedCcb = TRUE;
3632 (*Ccb)->DirectoryCB = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB;
3635 // Set the PIOCtl index
3638 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3640 RtlZeroMemory( &stPIOCtlOpen,
3641 sizeof( AFSPIOCtlOpenCloseRequestCB));
3643 stPIOCtlOpen.RequestId = (*Ccb)->RequestID;
3645 stPIOCtlOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3647 RtlZeroMemory( &stFileID,
3648 sizeof( AFSFileID));
3651 // The parent directory FID of the node
3654 stFileID = pParentObjectInfo->FileId;
3657 // Issue the open request to the service
3660 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_OPEN,
3661 AFS_REQUEST_FLAG_SYNCHRONOUS,
3665 (void *)&stPIOCtlOpen,
3666 sizeof( AFSPIOCtlOpenCloseRequestCB),
3670 if( !NT_SUCCESS( ntStatus))
3673 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3674 AFS_TRACE_LEVEL_ERROR,
3675 "AFSOpenIOCtlFcb (%08lX) Failed service open Status %08lX\n",
3679 try_return( ntStatus);
3683 // Reference the directory entry
3686 lCount = InterlockedIncrement( &((*Ccb)->DirectoryCB->OpenReferenceCount));
3688 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3689 AFS_TRACE_LEVEL_VERBOSE,
3690 "AFSOpenIOCtlFcb Increment count on %wZ DE %p Ccb %p Cnt %d\n",
3691 &(*Ccb)->DirectoryCB->NameInformation.FileName,
3692 (*Ccb)->DirectoryCB,
3697 // Increment the handle on the node
3700 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3702 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3703 AFS_TRACE_LEVEL_VERBOSE,
3704 "AFSOpenIOCtlFcb Increment handle count on Fcb %08lX Cnt %d\n",
3709 // Increment the open reference and handle on the parent node
3712 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3714 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3715 AFS_TRACE_LEVEL_VERBOSE,
3716 "AFSOpenIOCtlFcb Increment child open handle count on Parent object %08lX Cnt %d\n",
3720 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3722 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3723 AFS_TRACE_LEVEL_VERBOSE,
3724 "AFSOpenIOCtlFcb Increment child open ref count on Parent object %08lX Cnt %d\n",
3729 // Return the open result for this file
3732 Irp->IoStatus.Information = FILE_OPENED;
3737 //Dereference the passed in parent since the returned dir entry
3738 // is already referenced
3741 lCount = InterlockedDecrement( &ParentDirCB->OpenReferenceCount);
3743 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3744 AFS_TRACE_LEVEL_VERBOSE,
3745 "AFSOpenIOCtlFcb Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3746 &ParentDirCB->NameInformation.FileName,
3752 // If we created the Fcb we need to release the resources
3758 if( !NT_SUCCESS( ntStatus))
3761 // Decrement the open reference and handle on the node
3764 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
3766 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3767 AFS_TRACE_LEVEL_VERBOSE,
3768 "AFSOpenIOCtlFcb Decrement count on Fcb %08lX Cnt %d\n",
3773 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3776 if( !NT_SUCCESS( ntStatus))
3792 // Need to tear down this Fcb since it is not in the tree for the worker thread
3795 AFSAcquireExcl( &pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
3798 AFSRemoveFcb( &pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb);
3800 AFSReleaseResource( &pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);
3811 AFSOpenSpecialShareFcb( IN PIRP Irp,
3813 IN AFSDirectoryCB *DirectoryCB,
3818 NTSTATUS ntStatus = STATUS_SUCCESS;
3819 PFILE_OBJECT pFileObject = NULL;
3820 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3821 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE, bAllocateFcb = FALSE;
3822 AFSObjectInfoCB *pParentObjectInfo = NULL;
3823 AFSPipeOpenCloseRequestCB stPipeOpen;
3829 pFileObject = pIrpSp->FileObject;
3831 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3832 AFS_TRACE_LEVEL_VERBOSE_2,
3833 "AFSOpenSpecialShareFcb (%08lX) Processing Share %wZ open\n",
3835 &DirectoryCB->NameInformation.FileName);
3837 pParentObjectInfo = DirectoryCB->ObjectInformation->ParentObjectInformation;
3839 if( DirectoryCB->ObjectInformation->Fcb == NULL)
3843 // Allocate and initialize the Fcb for the file.
3846 ntStatus = AFSInitFcb( DirectoryCB);
3848 *Fcb = DirectoryCB->ObjectInformation->Fcb;
3850 if( !NT_SUCCESS( ntStatus))
3853 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3854 AFS_TRACE_LEVEL_ERROR,
3855 "AFSOpenSpecialShareFcb (%08lX) Failed to initialize fcb Status %08lX\n",
3859 try_return( ntStatus);
3862 if ( ntStatus != STATUS_REPARSE)
3865 bAllocateFcb = TRUE;
3868 ntStatus = STATUS_SUCCESS;
3873 *Fcb = DirectoryCB->ObjectInformation->Fcb;
3875 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
3880 // Increment the open count on this Fcb
3883 lCount = InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3885 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3886 AFS_TRACE_LEVEL_VERBOSE,
3887 "AFSOpenSpecialShareFcb Increment count on Fcb %08lX Cnt %d\n",
3894 // Initialize the Ccb for the file.
3897 ntStatus = AFSInitCcb( Ccb);
3899 if( !NT_SUCCESS( ntStatus))
3902 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3903 AFS_TRACE_LEVEL_ERROR,
3904 "AFSOpenSpecialShareFcb (%08lX) Failed to initialize ccb Status %08lX\n",
3908 try_return( ntStatus);
3911 bAllocatedCcb = TRUE;
3917 (*Ccb)->DirectoryCB = DirectoryCB;
3920 // Call the service to open the share
3923 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3925 RtlZeroMemory( &stPipeOpen,
3926 sizeof( AFSPipeOpenCloseRequestCB));
3928 stPipeOpen.RequestId = (*Ccb)->RequestID;
3930 stPipeOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3933 // Issue the open request to the service
3936 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_OPEN,
3937 AFS_REQUEST_FLAG_SYNCHRONOUS,
3939 &DirectoryCB->NameInformation.FileName,
3941 (void *)&stPipeOpen,
3942 sizeof( AFSPipeOpenCloseRequestCB),
3946 if( !NT_SUCCESS( ntStatus))
3949 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3950 AFS_TRACE_LEVEL_ERROR,
3951 "AFSOpenSpecialShareFcb (%08lX) Failed service open Status %08lX\n",
3955 try_return( ntStatus);
3958 lCount = InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3960 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3961 AFS_TRACE_LEVEL_VERBOSE,
3962 "AFSOpenSpecialShareFcb Increment handle count on Fcb %08lX Cnt %d\n",
3967 // Increment the open reference and handle on the parent node
3970 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3972 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3973 AFS_TRACE_LEVEL_VERBOSE,
3974 "AFSOpenSpecialShareFcb Increment child open handle count on Parent object %08lX Cnt %d\n",
3978 lCount = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3980 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3981 AFS_TRACE_LEVEL_VERBOSE,
3982 "AFSOpenSpecialShareFcb Increment child open ref count on Parent object %08lX Cnt %d\n",
3987 // Return the open result for this file
3990 Irp->IoStatus.Information = FILE_OPENED;
3997 if( !NT_SUCCESS( ntStatus))
4000 // Decrement the open count on this Fcb
4003 lCount = InterlockedDecrement( &(*Fcb)->OpenReferenceCount);
4005 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
4006 AFS_TRACE_LEVEL_VERBOSE,
4007 "AFSOpenSpecialShareFcb Decrement count on Fcb %08lX Cnt %d\n",
4012 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
4015 if( !NT_SUCCESS( ntStatus))
4031 // Need to tear down this Fcb since it is not in the tree for the worker thread
4034 AFSAcquireExcl( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock,
4037 AFSRemoveFcb( &DirectoryCB->ObjectInformation->Fcb);
4039 AFSReleaseResource( &DirectoryCB->ObjectInformation->NonPagedInfo->ObjectInfoLock);