2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSCreate.cpp
39 #include "AFSCommon.h"
42 // Function: AFSCreate
46 // This function is the dispatch handler for the IRP_MJ_CREATE requests. It makes the determination to
47 // which interface this request is destined.
51 // A status is returned for the function. The Irp completion processing is handled in the specific
56 AFSCreate( IN PDEVICE_OBJECT LibDeviceObject,
60 NTSTATUS ntStatus = STATUS_SUCCESS;
61 IO_STACK_LOCATION *pIrpSp;
62 FILE_OBJECT *pFileObject = NULL;
67 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
68 pFileObject = pIrpSp->FileObject;
70 if( pFileObject == NULL ||
71 pFileObject->FileName.Buffer == NULL)
74 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
75 AFS_TRACE_LEVEL_VERBOSE,
76 "AFSCreate (%08lX) Processing control device open request\n",
79 ntStatus = AFSControlDeviceCreate( Irp);
81 try_return( ntStatus);
84 if( AFSRDRDeviceObject == NULL)
87 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
88 AFS_TRACE_LEVEL_VERBOSE,
89 "AFSCreate (%08lX) Invalid request to open before library is initialized\n",
92 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
95 ntStatus = AFSCommonCreate( AFSRDRDeviceObject,
102 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
107 "EXCEPTION - AFSCreate\n");
109 ntStatus = STATUS_ACCESS_DENIED;
113 // Complete the request
116 AFSCompleteRequest( Irp,
123 AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
127 NTSTATUS ntStatus = STATUS_SUCCESS;
128 UNICODE_STRING uniFileName;
129 ULONG ulCreateDisposition = 0;
131 BOOLEAN bNoIntermediateBuffering = FALSE;
132 FILE_OBJECT *pFileObject = NULL;
133 IO_STACK_LOCATION *pIrpSp;
136 AFSDeviceExt *pDeviceExt = NULL;
137 BOOLEAN bOpenTargetDirectory = FALSE, bReleaseVolume = FALSE;
138 PACCESS_MASK pDesiredAccess = NULL;
139 UNICODE_STRING uniComponentName, uniPathName, uniRootFileName, uniParsedFileName;
140 UNICODE_STRING uniSubstitutedPathName;
141 UNICODE_STRING uniRelativeName;
142 AFSNameArrayHdr *pNameArray = NULL;
143 AFSVolumeCB *pVolumeCB = NULL;
144 AFSDirectoryCB *pParentDirectoryCB = NULL, *pDirectoryCB = NULL;
145 ULONG ulParseFlags = 0;
147 ULONG ulNameProcessingFlags = 0;
148 BOOLEAN bOpenedReparsePoint = FALSE;
153 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
154 pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
155 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
156 ulOptions = pIrpSp->Parameters.Create.Options;
157 bNoIntermediateBuffering = BooleanFlagOn( ulOptions, FILE_NO_INTERMEDIATE_BUFFERING);
158 bOpenTargetDirectory = BooleanFlagOn( pIrpSp->Flags, SL_OPEN_TARGET_DIRECTORY);
159 pFileObject = pIrpSp->FileObject;
160 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
162 uniFileName.Length = uniFileName.MaximumLength = 0;
163 uniFileName.Buffer = NULL;
165 uniRootFileName.Length = uniRootFileName.MaximumLength = 0;
166 uniRootFileName.Buffer = NULL;
168 uniParsedFileName.Length = uniParsedFileName.MaximumLength = 0;
169 uniParsedFileName.Buffer = NULL;
171 uniSubstitutedPathName.Buffer = NULL;
172 uniSubstitutedPathName.Length = 0;
174 uniRelativeName.Buffer = NULL;
175 uniRelativeName.Length = 0;
177 if( AFSGlobalRoot == NULL)
179 try_return( ntStatus = STATUS_DEVICE_NOT_READY);
182 RtlZeroMemory( &stAuthGroup,
185 AFSRetrieveAuthGroupFnc( (ULONGLONG)PsGetCurrentProcessId(),
186 (ULONGLONG)PsGetCurrentThreadId(),
189 if( !BooleanFlagOn( AFSGlobalRoot->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
192 ntStatus = AFSEnumerateGlobalRoot( &stAuthGroup);
194 if( !NT_SUCCESS( ntStatus))
197 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
198 AFS_TRACE_LEVEL_ERROR,
199 "AFSCommonCreate Failed to enumerate global root Status %08lX\n",
202 try_return( ntStatus);
207 // If we are in shutdown mode then fail the request
210 if( BooleanFlagOn( pDeviceExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN))
213 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
214 AFS_TRACE_LEVEL_WARNING,
215 "AFSCommonCreate (%08lX) Open request after shutdown\n",
218 try_return( ntStatus = STATUS_TOO_LATE);
222 // Go and parse the name for processing.
223 // If ulParseFlags is returned with AFS_PARSE_FLAG_FREE_FILE_BUFFER set,
224 // then we are responsible for releasing the uniRootFileName.Buffer.
227 ntStatus = AFSParseName( Irp,
237 if( !NT_SUCCESS( ntStatus))
240 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
241 uniFileName.Length > 0 ? AFS_TRACE_LEVEL_ERROR : AFS_TRACE_LEVEL_VERBOSE,
242 "AFSCommonCreate (%08lX) Failed to parse name \"%wZ\" Status %08lX\n",
247 try_return( ntStatus);
251 // Check for STATUS_REPARSE
254 if( ntStatus == STATUS_REPARSE)
258 // Update the information and return
261 Irp->IoStatus.Information = IO_REPARSE;
263 try_return( ntStatus);
267 // If the returned volume cb is NULL then we are dealing with the \\Server\GlobalRoot
271 if( pVolumeCB == NULL)
275 // Remove any leading or trailing slashes
278 if( uniFileName.Length >= sizeof( WCHAR) &&
279 uniFileName.Buffer[ (uniFileName.Length/sizeof( WCHAR)) - 1] == L'\\')
282 uniFileName.Length -= sizeof( WCHAR);
285 if( uniFileName.Length >= sizeof( WCHAR) &&
286 uniFileName.Buffer[ 0] == L'\\')
289 uniFileName.Buffer = &uniFileName.Buffer[ 1];
291 uniFileName.Length -= sizeof( WCHAR);
295 // If there is a remaining portion returned for this request then
296 // check if it is for the PIOCtl interface
299 if( uniFileName.Length > 0)
303 // We don't accept any other opens off of the AFS Root
306 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
309 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
312 if( RtlCompareUnicodeString( &AFSPIOCtlName,
317 ntStatus = AFSOpenIOCtlFcb( Irp,
319 AFSGlobalRoot->DirectoryCB,
323 if( !NT_SUCCESS( ntStatus))
326 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
327 AFS_TRACE_LEVEL_ERROR,
328 "AFSCommonCreate Failed to open root IOCtl Fcb Status %08lX\n",
332 else if( pParentDirectoryCB != NULL &&
333 pParentDirectoryCB->ObjectInformation->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
336 ntStatus = AFSOpenSpecialShareFcb( Irp,
342 if( !NT_SUCCESS( ntStatus))
345 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
346 AFS_TRACE_LEVEL_ERROR,
347 "AFSCommonCreate Failed to open special share Fcb Status %08lX\n",
352 try_return( ntStatus);
355 ntStatus = AFSOpenAFSRoot( Irp,
359 if( !NT_SUCCESS( ntStatus))
362 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
363 AFS_TRACE_LEVEL_ERROR,
364 "AFSCommonCreate Failed to open root Status %08lX\n",
367 InterlockedDecrement( &AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
369 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
370 AFS_TRACE_LEVEL_VERBOSE,
371 "AFSCreate Decrement1 count on &wZ DE %p Ccb %p Cnt %d\n",
372 &AFSGlobalRoot->DirectoryCB->NameInformation.FileName,
373 AFSGlobalRoot->DirectoryCB,
375 AFSGlobalRoot->DirectoryCB->OpenReferenceCount);
378 try_return( ntStatus);
382 // We have our root node shared
385 bReleaseVolume = TRUE;
388 // Attempt to locate the node in the name tree if this is not a target
389 // open and the target is not the root
392 uniComponentName.Length = 0;
393 uniComponentName.Buffer = NULL;
395 if( uniFileName.Length > sizeof( WCHAR) ||
396 uniFileName.Buffer[ 0] != L'\\')
399 if( !AFSValidNameFormat( &uniFileName))
402 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
404 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
405 AFS_TRACE_LEVEL_VERBOSE,
406 "AFSCommonCreate (%08lX) Invalid name %wZ Status %08lX\n",
411 try_return( ntStatus);
415 // Opening a reparse point directly?
418 ulNameProcessingFlags = AFS_LOCATE_FLAGS_SUBSTITUTE_NAME;
420 if( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
422 ulNameProcessingFlags |= (AFS_LOCATE_FLAGS_NO_MP_TARGET_EVAL |
423 AFS_LOCATE_FLAGS_NO_SL_TARGET_EVAL |
424 AFS_LOCATE_FLAGS_NO_DFS_LINK_EVAL);
427 uniSubstitutedPathName = uniRootFileName;
429 ntStatus = AFSLocateNameEntry( &stAuthGroup,
434 ulNameProcessingFlags,
440 if( !NT_SUCCESS( ntStatus) &&
441 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
444 if ( uniSubstitutedPathName.Buffer == uniRootFileName.Buffer)
446 uniSubstitutedPathName.Buffer = NULL;
450 // The routine above released the root while walking the
454 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
455 AFS_TRACE_LEVEL_VERBOSE,
456 "AFSCommonCreate (%08lX) Failed to locate name entry for %wZ Status %08lX\n",
462 // We released any root volume locks in the above on failure
465 bReleaseVolume = FALSE;
467 try_return( ntStatus);
471 // Check for STATUS_REPARSE
474 if( ntStatus == STATUS_REPARSE)
477 uniSubstitutedPathName.Buffer = NULL;
480 // Update the information and return
483 Irp->IoStatus.Information = IO_REPARSE;
486 // We released the volume lock above
489 bReleaseVolume = FALSE;
491 try_return( ntStatus);
495 // If we re-allocated the name, then update our substitute name
498 if( uniSubstitutedPathName.Buffer != uniRootFileName.Buffer)
501 uniSubstitutedPathName = uniRootFileName;
506 uniSubstitutedPathName.Buffer = NULL;
510 // Check for a symlink access
513 if( ntStatus == STATUS_OBJECT_NAME_NOT_FOUND &&
514 pParentDirectoryCB != NULL)
517 UNICODE_STRING uniFinalComponent;
519 uniFinalComponent.Length = 0;
520 uniFinalComponent.MaximumLength = 0;
521 uniFinalComponent.Buffer = NULL;
523 AFSRetrieveFinalComponent( &uniFileName,
526 ntStatus = AFSCheckSymlinkAccess( pParentDirectoryCB,
529 if( !NT_SUCCESS( ntStatus) &&
530 ntStatus != STATUS_OBJECT_NAME_NOT_FOUND)
533 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
534 AFS_TRACE_LEVEL_VERBOSE,
535 "AFSCommonCreate (%08lX) Failing access to symlink %wZ Status %08lX\n",
540 try_return( ntStatus);
546 // If we have no parent then this is a root open, be sure there is a directory entry
550 else if( pParentDirectoryCB == NULL &&
551 pDirectoryCB == NULL)
554 pDirectoryCB = pVolumeCB->DirectoryCB;
557 if( bOpenTargetDirectory)
561 // If we have a directory cb for the entry then dereference it and reference the parent
564 if( pDirectoryCB != NULL)
568 // Perform in this order to prevent thrashing
571 InterlockedIncrement( &pParentDirectoryCB->OpenReferenceCount);
573 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
574 AFS_TRACE_LEVEL_VERBOSE,
575 "AFSCreate Increment1 count on %wZ DE %p Ccb %p Cnt %d\n",
576 &pParentDirectoryCB->NameInformation.FileName,
579 pParentDirectoryCB->OpenReferenceCount);
582 // Do NOT decrement the reference count on the pDirectoryCB yet.
583 // The BackupEntry below might drop the count to zero leaving
584 // the entry subject to being deleted and we need some of the
585 // contents during later processing
588 AFSBackupEntry( pNameArray);
592 // OK, open the target directory
595 if( uniComponentName.Length == 0)
597 AFSRetrieveFinalComponent( &uniFileName,
601 ntStatus = AFSOpenTargetDirectory( Irp,
608 if( pDirectoryCB != NULL)
611 // It is now safe to drop the Reference Count
613 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
615 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
616 AFS_TRACE_LEVEL_VERBOSE,
617 "AFSCreate Decrement2 count on %wZ DE %p Ccb %p Cnt %d\n",
618 &pDirectoryCB->NameInformation.FileName,
621 pDirectoryCB->OpenReferenceCount);
624 if( !NT_SUCCESS( ntStatus))
627 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
628 AFS_TRACE_LEVEL_ERROR,
629 "AFSCommonCreate Failed to open target directory %wZ Status %08lX\n",
630 &pParentDirectoryCB->NameInformation.FileName,
634 // Decrement the reference on the parent
637 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
639 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
640 AFS_TRACE_LEVEL_VERBOSE,
641 "AFSCreate Decrement3 count on %wZ DE %p Ccb %p Cnt %d\n",
642 &pParentDirectoryCB->NameInformation.FileName,
645 pParentDirectoryCB->OpenReferenceCount);
648 try_return( ntStatus);
651 if ( BooleanFlagOn( ulOptions, FILE_OPEN_REPARSE_POINT))
654 if( pDirectoryCB == NULL ||
655 !BooleanFlagOn( pDirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
657 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
658 AFS_TRACE_LEVEL_VERBOSE,
659 "AFSCommonCreate (%08lX) Reparse open request but attribute not set for %wZ DirCB %p Type %08lX\n",
663 pDirectoryCB ? pDirectoryCB->ObjectInformation->FileType : 0);
667 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
668 AFS_TRACE_LEVEL_VERBOSE,
669 "AFSCommonCreate (%08lX) Opening as reparse point %wZ Type %08lX\n",
672 pDirectoryCB->ObjectInformation->FileType);
674 bOpenedReparsePoint = TRUE;
679 // Based on the options passed in, process the file accordingly.
682 if( ulCreateDisposition == FILE_CREATE ||
683 ( ( ulCreateDisposition == FILE_OPEN_IF ||
684 ulCreateDisposition == FILE_OVERWRITE_IF) &&
685 pDirectoryCB == NULL))
688 if( uniComponentName.Length == 0 ||
689 pDirectoryCB != NULL)
693 // We traversed the entire path so we found each entry,
694 // fail with collision
697 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
698 AFS_TRACE_LEVEL_VERBOSE,
699 "AFSCommonCreate Object name collision on create of %wZ Status %08lX\n",
700 &pDirectoryCB->NameInformation.FileName,
703 if( pDirectoryCB != NULL)
706 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
708 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
709 AFS_TRACE_LEVEL_VERBOSE,
710 "AFSCreate Decrement4 count on %wZ DE %p Ccb %p Cnt %d\n",
711 &pDirectoryCB->NameInformation.FileName,
714 pDirectoryCB->OpenReferenceCount);
719 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
721 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
722 AFS_TRACE_LEVEL_VERBOSE,
723 "AFSCreate Decrement5 count on %wZ DE %p Ccb %p Cnt %d\n",
724 &pParentDirectoryCB->NameInformation.FileName,
727 pParentDirectoryCB->OpenReferenceCount);
730 try_return( ntStatus = STATUS_OBJECT_NAME_COLLISION);
734 // OK, go and create the node
737 ntStatus = AFSProcessCreate( Irp,
747 if( !NT_SUCCESS( ntStatus))
750 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
751 AFS_TRACE_LEVEL_ERROR,
752 "AFSCommonCreate Failed to create of %wZ in directory %wZ Status %08lX\n",
754 &pParentDirectoryCB->NameInformation.FileName,
759 // Dereference the parent entry
762 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
764 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
765 AFS_TRACE_LEVEL_VERBOSE,
766 "AFSCreate Decrement6 count on %wZ DE %p Ccb %p Cnt %d\n",
767 &pParentDirectoryCB->NameInformation.FileName,
770 pParentDirectoryCB->OpenReferenceCount);
772 try_return( ntStatus);
776 // We should not have an extra component except for PIOCtl opens
779 if( uniComponentName.Length > 0)
783 // If this is an open on "_._AFS_IOCTL_._" then perform handling on it accordingly
786 if( RtlCompareUnicodeString( &AFSPIOCtlName,
791 ntStatus = AFSOpenIOCtlFcb( Irp,
797 if( !NT_SUCCESS( ntStatus))
800 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
801 AFS_TRACE_LEVEL_ERROR,
802 "AFSCommonCreate Failed to IOCtl open on %wZ Status %08lX\n",
810 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
811 AFS_TRACE_LEVEL_VERBOSE,
812 "AFSCommonCreate (%08lX) File %wZ name not found\n",
816 ntStatus = STATUS_OBJECT_NAME_NOT_FOUND;
819 if( !NT_SUCCESS( ntStatus))
823 // Dereference the parent entry
826 if( pDirectoryCB != NULL)
829 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
831 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
832 AFS_TRACE_LEVEL_VERBOSE,
833 "AFSCreate Decrement7a count on %wZ DE %p Ccb %p Cnt %d\n",
834 &pDirectoryCB->NameInformation.FileName,
837 pDirectoryCB->OpenReferenceCount);
842 InterlockedDecrement( &pParentDirectoryCB->OpenReferenceCount);
844 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
845 AFS_TRACE_LEVEL_VERBOSE,
846 "AFSCreate Decrement7b count on %wZ DE %p Ccb %p Cnt %d\n",
847 &pParentDirectoryCB->NameInformation.FileName,
850 pParentDirectoryCB->OpenReferenceCount);
854 try_return( ntStatus);
858 // For root opens the parent will be NULL
861 if( pParentDirectoryCB == NULL)
865 // Check for the delete on close flag for the root
868 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE ))
871 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
872 AFS_TRACE_LEVEL_ERROR,
873 "AFSCommonCreate (%08lX) Attempt to open root as delete on close\n",
876 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
878 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
879 AFS_TRACE_LEVEL_VERBOSE,
880 "AFSCreate Decrement8 count on %wZ DE %p Ccb %p Cnt %d\n",
881 &pDirectoryCB->NameInformation.FileName,
884 pDirectoryCB->OpenReferenceCount);
886 try_return( ntStatus = STATUS_CANNOT_DELETE);
890 // If this is the target directory, then bail
893 if( bOpenTargetDirectory)
896 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
897 AFS_TRACE_LEVEL_ERROR,
898 "AFSCommonCreate (%08lX) Attempt to open root as target directory\n",
901 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
903 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
904 AFS_TRACE_LEVEL_VERBOSE,
905 "AFSCreate Decrement9 count on %wZ DE %p Ccb %p Cnt %d\n",
906 &pDirectoryCB->NameInformation.FileName,
909 pDirectoryCB->OpenReferenceCount);
911 try_return( ntStatus = STATUS_INVALID_PARAMETER);
915 // Go and open the root of the volume
918 ntStatus = AFSOpenRoot( Irp,
924 if( !NT_SUCCESS( ntStatus))
927 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
928 AFS_TRACE_LEVEL_ERROR,
929 "AFSCommonCreate Failed to open volume root %08lX-%08lX Status %08lX\n",
930 pVolumeCB->ObjectInformation.FileId.Cell,
931 pVolumeCB->ObjectInformation.FileId.Volume,
934 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
936 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
937 AFS_TRACE_LEVEL_VERBOSE,
938 "AFSCreate Decrement10 count on %wZ DE %p Ccb %p Cnt %d\n",
939 &pDirectoryCB->NameInformation.FileName,
942 pDirectoryCB->OpenReferenceCount);
945 try_return( ntStatus);
949 // At this point if we have no pDirectoryCB it was not found.
952 if( pDirectoryCB == NULL)
955 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
956 AFS_TRACE_LEVEL_ERROR,
957 "AFSCommonCreate Failing access to %wZ\n",
960 try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
963 if( ulCreateDisposition == FILE_OVERWRITE ||
964 ulCreateDisposition == FILE_SUPERSEDE ||
965 ulCreateDisposition == FILE_OVERWRITE_IF)
969 // Go process a file for overwrite or supersede.
972 ntStatus = AFSProcessOverwriteSupersede( DeviceObject,
981 if( !NT_SUCCESS( ntStatus))
984 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
985 AFS_TRACE_LEVEL_ERROR,
986 "AFSCommonCreate Failed overwrite/supersede on %wZ Status %08lX\n",
987 &pDirectoryCB->NameInformation.FileName,
990 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
992 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
993 AFS_TRACE_LEVEL_VERBOSE,
994 "AFSCreate Decrement11 count on %wZ DE %p Ccb %p Cnt %d\n",
995 &pDirectoryCB->NameInformation.FileName,
998 pDirectoryCB->OpenReferenceCount);
1001 try_return( ntStatus);
1005 // Trying to open the file
1008 ntStatus = AFSProcessOpen( Irp,
1016 if( !NT_SUCCESS( ntStatus))
1019 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1020 AFS_TRACE_LEVEL_ERROR,
1021 "AFSCommonCreate Failed open on %wZ Status %08lX\n",
1022 &pDirectoryCB->NameInformation.FileName,
1025 InterlockedDecrement( &pDirectoryCB->OpenReferenceCount);
1027 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1028 AFS_TRACE_LEVEL_VERBOSE,
1029 "AFSCreate Decrement12 count on %wZ DE %p Ccb %p Cnt %d\n",
1030 &pDirectoryCB->NameInformation.FileName,
1033 pDirectoryCB->OpenReferenceCount);
1038 if( NT_SUCCESS( ntStatus) &&
1039 ntStatus != STATUS_REPARSE)
1046 // If we have a substitute name, then use it
1049 if( uniSubstitutedPathName.Buffer != NULL)
1052 pCcb->FullFileName = uniSubstitutedPathName;
1054 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1056 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1061 pCcb->FullFileName = uniRootFileName;
1063 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1066 SetFlag( pCcb->Flags, CCB_FLAG_FREE_FULL_PATHNAME);
1068 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1072 if( bOpenedReparsePoint)
1074 SetFlag( pCcb->Flags, CCB_FLAG_MASK_OPENED_REPARSE_POINT);
1077 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
1078 AFS_TRACE_LEVEL_VERBOSE,
1079 "AFSCreate Count on %wZ DE %p Ccb %p Cnt %d\n",
1080 &pCcb->DirectoryCB->NameInformation.FileName,
1083 pCcb->DirectoryCB->OpenReferenceCount);
1085 ASSERT( pCcb->DirectoryCB->OpenReferenceCount > 0);
1087 pCcb->CurrentDirIndex = 0;
1089 if( !BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_ROOT_ACCESS))
1092 SetFlag( pCcb->Flags, CCB_FLAG_RETURN_RELATIVE_ENTRIES);
1096 // Save off the name array for this instance
1099 pCcb->NameArray = pNameArray;
1105 // If we make it here then init the FO for the request.
1108 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1109 AFS_TRACE_LEVEL_VERBOSE_2,
1110 "AFSCommonCreate (%08lX) FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1116 pFileObject->FsContext = (void *)pFcb;
1118 pFileObject->FsContext2 = (void *)pCcb;
1123 ASSERT( pFcb->OpenHandleCount > 0);
1125 ClearFlag( pFcb->Flags, AFS_FCB_FILE_CLOSED);
1127 RtlCopyMemory( &pFcb->AuthGroup,
1132 // For files perform additional processing
1135 if( pFcb->Header.NodeTypeCode == AFS_FILE_FCB)
1137 pFileObject->SectionObjectPointer = &pFcb->NPFcb->SectionObjectPointers;
1141 // If the user did not request nobuffering then mark the FO as cacheable
1144 if( bNoIntermediateBuffering)
1147 pFileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
1152 pFileObject->Flags |= FO_CACHE_SUPPORTED;
1156 // If the file was opened for execution then we need to set the bit in the FO
1159 if( BooleanFlagOn( *pDesiredAccess,
1163 SetFlag( pFileObject->Flags, FO_FILE_FAST_IO_READ);
1167 // Update the last access time
1170 KeQuerySystemTime( &pFcb->ObjectInformation->LastAccessTime);
1175 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1176 AFS_TRACE_LEVEL_ERROR,
1177 "AFSCommonCreate (%08lX) Returning with NULL Fcb FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1186 if( NT_SUCCESS( ntStatus) &&
1187 ntStatus == STATUS_REPARSE)
1190 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1191 AFS_TRACE_LEVEL_ERROR,
1192 "AFSCommonCreate (%08lX) STATUS_REPARSE FileObject %08lX FsContext %08lX FsContext2 %08lX\n",
1200 // Free up the sub name if we have one
1203 if( uniSubstitutedPathName.Buffer != NULL)
1206 AFSExFreePool( uniSubstitutedPathName.Buffer);
1208 ClearFlag( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER);
1213 // Free up the name array ...
1216 if( pNameArray != NULL)
1219 AFSFreeNameArray( pNameArray);
1222 if( BooleanFlagOn( ulParseFlags, AFS_PARSE_FLAG_FREE_FILE_BUFFER))
1225 AFSExFreePool( uniRootFileName.Buffer);
1231 InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
1233 AFSDbgLogMsg( AFS_SUBSYSTEM_VOLUME_REF_COUNTING,
1234 AFS_TRACE_LEVEL_VERBOSE,
1235 "AFSCommonCreate Decrement count on Volume %08lX Cnt %d\n",
1237 pVolumeCB->VolumeReferenceCount);
1239 AFSReleaseResource( pVolumeCB->VolumeLock);
1243 // Setup the Irp for completion, the Information has been set previously
1246 Irp->IoStatus.Status = ntStatus;
1253 AFSOpenRedirector( IN PIRP Irp,
1258 NTSTATUS ntStatus = STATUS_SUCCESS;
1264 // Initialize the Ccb for the file.
1267 ntStatus = AFSInitCcb( Ccb);
1269 if( !NT_SUCCESS( ntStatus))
1272 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1273 AFS_TRACE_LEVEL_ERROR,
1274 "AFSOpenRedirector (%08lX) Failed to allocate Ccb\n",
1277 try_return( ntStatus);
1284 (*Ccb)->DirectoryCB = AFSRedirectorRoot->DirectoryCB;
1287 // Increment the open count on this Fcb
1290 InterlockedIncrement( &AFSRedirectorRoot->RootFcb->OpenReferenceCount);
1292 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1293 AFS_TRACE_LEVEL_VERBOSE,
1294 "AFSOpenRedirector Increment count on Fcb %08lX Cnt %d\n",
1295 AFSRedirectorRoot->RootFcb,
1296 AFSRedirectorRoot->RootFcb->OpenReferenceCount);
1298 InterlockedIncrement( &AFSRedirectorRoot->RootFcb->OpenHandleCount);
1300 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1301 AFS_TRACE_LEVEL_VERBOSE,
1302 "AFSOpenRedirector Increment handle count on Fcb %08lX Cnt %d\n",
1303 AFSRedirectorRoot->RootFcb,
1304 AFSRedirectorRoot->RootFcb->OpenHandleCount);
1306 *Fcb = AFSRedirectorRoot->RootFcb;
1308 InterlockedIncrement( &(*Ccb)->DirectoryCB->OpenReferenceCount);
1311 // Return the open result for this file
1314 Irp->IoStatus.Information = FILE_OPENED;
1325 AFSOpenAFSRoot( IN PIRP Irp,
1330 NTSTATUS ntStatus = STATUS_SUCCESS;
1336 // Initialize the Ccb for the file.
1339 ntStatus = AFSInitCcb( Ccb);
1341 if( !NT_SUCCESS( ntStatus))
1344 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1345 AFS_TRACE_LEVEL_ERROR,
1346 "AFSOpenAFSRoot (%08lX) Failed to allocate Ccb\n",
1349 try_return( ntStatus);
1356 (*Ccb)->DirectoryCB = AFSGlobalRoot->DirectoryCB;
1359 // Increment the open count on this Fcb
1362 InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenReferenceCount);
1364 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1365 AFS_TRACE_LEVEL_VERBOSE,
1366 "AFSOpenAFSRoot Increment count on Fcb %08lX Cnt %d\n",
1367 AFSGlobalRoot->RootFcb,
1368 AFSGlobalRoot->RootFcb->OpenReferenceCount);
1370 InterlockedIncrement( &AFSGlobalRoot->RootFcb->OpenHandleCount);
1372 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1373 AFS_TRACE_LEVEL_VERBOSE,
1374 "AFSOpenAFSRoot Increment handle count on Fcb %08lX Cnt %d\n",
1375 AFSGlobalRoot->RootFcb,
1376 AFSGlobalRoot->RootFcb->OpenHandleCount);
1378 *Fcb = AFSGlobalRoot->RootFcb;
1381 // Return the open result for this file
1384 Irp->IoStatus.Information = FILE_OPENED;
1395 AFSOpenRoot( IN PIRP Irp,
1396 IN AFSVolumeCB *VolumeCB,
1398 OUT AFSFcb **RootFcb,
1402 NTSTATUS ntStatus = STATUS_SUCCESS;
1403 PFILE_OBJECT pFileObject = NULL;
1404 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1405 PACCESS_MASK pDesiredAccess = NULL;
1406 USHORT usShareAccess;
1407 BOOLEAN bAllocatedCcb = FALSE;
1408 BOOLEAN bReleaseFcb = FALSE;
1409 AFSFileOpenCB stOpenCB;
1410 AFSFileOpenResultCB stOpenResultCB;
1411 ULONG ulResultLen = 0;
1416 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1417 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1419 pFileObject = pIrpSp->FileObject;
1422 // Check if we should go and retrieve updated information for the node
1425 ntStatus = AFSValidateEntry( VolumeCB->DirectoryCB,
1430 if( !NT_SUCCESS( ntStatus))
1433 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1434 AFS_TRACE_LEVEL_ERROR,
1435 "AFSOpenRoot (%08lX) Failed to validate root entry Status %08lX\n",
1439 try_return( ntStatus);
1443 // Check with the service that we can open the file
1446 RtlZeroMemory( &stOpenCB,
1447 sizeof( AFSFileOpenCB));
1449 stOpenCB.DesiredAccess = *pDesiredAccess;
1451 stOpenCB.ShareAccess = usShareAccess;
1453 stOpenResultCB.GrantedAccess = 0;
1455 ulResultLen = sizeof( AFSFileOpenResultCB);
1457 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
1458 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
1461 &VolumeCB->ObjectInformation.FileId,
1463 sizeof( AFSFileOpenCB),
1464 (void *)&stOpenResultCB,
1467 if( !NT_SUCCESS( ntStatus))
1470 UNICODE_STRING uniGUID;
1473 uniGUID.MaximumLength = 0;
1474 uniGUID.Buffer = NULL;
1476 if( AuthGroup != NULL)
1478 RtlStringFromGUID( *AuthGroup,
1482 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1483 AFS_TRACE_LEVEL_ERROR,
1484 "AFSOpenRoot (%08lX) Failed open in service volume %08lX-%08lX AuthGroup %wZ Status %08lX\n",
1486 VolumeCB->ObjectInformation.FileId.Cell,
1487 VolumeCB->ObjectInformation.FileId.Volume,
1491 if( AuthGroup != NULL)
1493 RtlFreeUnicodeString( &uniGUID);
1496 try_return( ntStatus);
1500 // If the entry is not initialized then do it now
1503 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1506 AFSAcquireExcl( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock,
1509 if( !BooleanFlagOn( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED))
1512 ntStatus = AFSEnumerateDirectory( AuthGroup,
1513 &VolumeCB->ObjectInformation,
1516 if( !NT_SUCCESS( ntStatus))
1519 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1521 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1522 AFS_TRACE_LEVEL_ERROR,
1523 "AFSOpenRoot (%08lX) Failed to enumerate directory Status %08lX\n",
1527 try_return( ntStatus);
1530 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1533 AFSReleaseResource( VolumeCB->ObjectInformation.Specific.Directory.DirectoryNodeHdr.TreeLock);
1537 // If the root fcb has been initialized then check access otherwise
1538 // init the volume fcb
1541 if( VolumeCB->RootFcb == NULL)
1544 ntStatus = AFSInitRootFcb( (ULONGLONG)PsGetCurrentProcessId(),
1547 if( !NT_SUCCESS( ntStatus))
1550 try_return( ntStatus);
1556 AFSAcquireExcl( VolumeCB->RootFcb->Header.Resource,
1563 // If there are current opens on the Fcb, check the access.
1566 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1569 ntStatus = IoCheckShareAccess( *pDesiredAccess,
1572 &VolumeCB->RootFcb->ShareAccess,
1575 if( !NT_SUCCESS( ntStatus))
1578 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1579 AFS_TRACE_LEVEL_ERROR,
1580 "AFSOpenRoot (%08lX) Access check failure Status %08lX\n",
1584 try_return( ntStatus);
1589 // Initialize the Ccb for the file.
1592 ntStatus = AFSInitCcb( Ccb);
1594 if( !NT_SUCCESS( ntStatus))
1597 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1598 AFS_TRACE_LEVEL_ERROR,
1599 "AFSOpenRoot (%08lX) Failed to allocate Ccb Status %08lX\n",
1603 try_return( ntStatus);
1606 bAllocatedCcb = TRUE;
1612 (*Ccb)->DirectoryCB = VolumeCB->DirectoryCB;
1615 // OK, update the share access on the fileobject
1618 if( VolumeCB->RootFcb->OpenHandleCount > 0)
1621 IoUpdateShareAccess( pFileObject,
1622 &VolumeCB->RootFcb->ShareAccess);
1631 IoSetShareAccess( *pDesiredAccess,
1634 &VolumeCB->RootFcb->ShareAccess);
1638 // Increment the open count on this Fcb
1641 InterlockedIncrement( &VolumeCB->RootFcb->OpenReferenceCount);
1643 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1644 AFS_TRACE_LEVEL_VERBOSE,
1645 "AFSOpenRoot Increment count on Fcb %08lX Cnt %d\n",
1647 VolumeCB->RootFcb->OpenReferenceCount);
1649 InterlockedIncrement( &VolumeCB->RootFcb->OpenHandleCount);
1651 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
1652 AFS_TRACE_LEVEL_VERBOSE,
1653 "AFSOpenRoot Increment handle count on Fcb %08lX Cnt %d\n",
1655 VolumeCB->RootFcb->OpenHandleCount);
1658 // Indicate the object is held
1661 SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_HELD_IN_SERVICE);
1664 // Return the open result for this file
1667 Irp->IoStatus.Information = FILE_OPENED;
1669 *RootFcb = VolumeCB->RootFcb;
1676 AFSReleaseResource( VolumeCB->RootFcb->Header.Resource);
1679 if( !NT_SUCCESS( ntStatus))
1685 AFSRemoveCcb( *Ccb);
1690 Irp->IoStatus.Information = 0;
1698 AFSProcessCreate( IN PIRP Irp,
1700 IN AFSVolumeCB *VolumeCB,
1701 IN AFSDirectoryCB *ParentDirCB,
1702 IN PUNICODE_STRING FileName,
1703 IN PUNICODE_STRING ComponentName,
1704 IN PUNICODE_STRING FullFileName,
1709 NTSTATUS ntStatus = STATUS_SUCCESS;
1710 PFILE_OBJECT pFileObject = NULL;
1711 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1712 ULONG ulOptions = 0;
1713 ULONG ulShareMode = 0;
1715 ULONG ulAttributes = 0;
1716 LARGE_INTEGER liAllocationSize = {0,0};
1717 BOOLEAN bFileCreated = FALSE, bReleaseFcb = FALSE, bAllocatedCcb = FALSE;
1718 BOOLEAN bAllocatedFcb = FALSE;
1719 PACCESS_MASK pDesiredAccess = NULL;
1720 USHORT usShareAccess;
1721 AFSDirectoryCB *pDirEntry = NULL;
1722 AFSObjectInfoCB *pParentObjectInfo = NULL;
1723 AFSObjectInfoCB *pObjectInfo = NULL;
1728 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
1729 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
1731 pFileObject = pIrpSp->FileObject;
1734 // Extract out the options
1737 ulOptions = pIrpSp->Parameters.Create.Options;
1740 // We pass all attributes they want to apply to the file to the create
1743 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
1746 // If this is a directory create then set the attribute correctly
1749 if( ulOptions & FILE_DIRECTORY_FILE)
1752 ulAttributes |= FILE_ATTRIBUTE_DIRECTORY;
1755 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1756 AFS_TRACE_LEVEL_VERBOSE,
1757 "AFSProcessCreate (%08lX) Creating file %wZ Attributes %08lX\n",
1762 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
1765 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1766 AFS_TRACE_LEVEL_ERROR,
1767 "AFSProcessCreate Request failed due to read only volume %wZ\n",
1770 try_return( ntStatus = STATUS_ACCESS_DENIED);
1773 pParentObjectInfo = ParentDirCB->ObjectInformation;
1776 // Allocate and insert the direntry into the parent node
1779 ntStatus = AFSCreateDirEntry( AuthGroup,
1787 if( !NT_SUCCESS( ntStatus))
1790 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1791 AFS_TRACE_LEVEL_ERROR,
1792 "AFSProcessCreate (%08lX) Failed to create directory entry %wZ Status %08lX\n",
1797 try_return( ntStatus);
1800 bFileCreated = TRUE;
1802 pObjectInfo = pDirEntry->ObjectInformation;
1804 if( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED) ||
1805 pObjectInfo->FileType == AFS_FILE_TYPE_UNKNOWN)
1808 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1809 AFS_TRACE_LEVEL_VERBOSE,
1810 "AFSProcessCreate (%08lX) Evaluating object %wZ FID %08lX-%08lX-%08lX-%08lX\n",
1812 &pDirEntry->NameInformation.FileName,
1813 pObjectInfo->FileId.Cell,
1814 pObjectInfo->FileId.Volume,
1815 pObjectInfo->FileId.Vnode,
1816 pObjectInfo->FileId.Unique);
1818 ntStatus = AFSEvaluateNode( AuthGroup,
1821 if( !NT_SUCCESS( ntStatus))
1824 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1825 AFS_TRACE_LEVEL_ERROR,
1826 "AFSProcessCreate (%08lX) Failed to evaluate object %wZ FID %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,
1835 try_return( ntStatus);
1838 ClearFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_NOT_EVALUATED);
1842 // We may have raced and the Fcb is already created
1845 if( pObjectInfo->Fcb != NULL)
1848 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1849 AFS_TRACE_LEVEL_VERBOSE,
1850 "AFSProcessCreate (%08lX) Not allocating Fcb for file %wZ\n",
1854 *Fcb = pObjectInfo->Fcb;
1856 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
1863 // Allocate and initialize the Fcb for the file.
1866 ntStatus = AFSInitFcb( pDirEntry,
1869 if( !NT_SUCCESS( ntStatus))
1872 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1873 AFS_TRACE_LEVEL_ERROR,
1874 "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
1879 try_return( ntStatus);
1882 bAllocatedFcb = TRUE;
1888 // Initialize the Ccb for the file.
1891 ntStatus = AFSInitCcb( Ccb);
1893 if( !NT_SUCCESS( ntStatus))
1896 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1897 AFS_TRACE_LEVEL_ERROR,
1898 "AFSProcessCreate (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
1903 try_return( ntStatus);
1906 bAllocatedCcb = TRUE;
1909 // Initialize the Ccb
1912 (*Ccb)->DirectoryCB = pDirEntry;
1915 // If this is a file, update the headers filesizes.
1918 if( (*Fcb)->Header.NodeTypeCode == AFS_FILE_FCB)
1922 // Update the sizes with the information passed in
1925 (*Fcb)->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
1926 (*Fcb)->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1927 (*Fcb)->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;
1930 // Notify the system of the addition
1933 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1935 (ULONG)FILE_NOTIFY_CHANGE_FILE_NAME,
1936 (ULONG)FILE_ACTION_ADDED);
1938 (*Fcb)->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
1940 else if( (*Fcb)->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
1944 // This is a new directory node so indicate it has been enumerated
1947 SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_DIRECTORY_ENUMERATED);
1950 // And the parent directory entry
1953 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1956 // Notify the system of the addition
1959 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1961 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1962 (ULONG)FILE_ACTION_ADDED);
1964 else if( (*Fcb)->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
1965 (*Fcb)->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
1966 (*Fcb)->Header.NodeTypeCode == AFS_DFS_LINK_FCB)
1970 // And the parent directory entry
1973 KeQuerySystemTime( &pParentObjectInfo->ChangeTime);
1976 // Notify the system of the addition
1979 AFSFsRtlNotifyFullReportChange( pParentObjectInfo,
1981 (ULONG)FILE_NOTIFY_CHANGE_DIR_NAME,
1982 (ULONG)FILE_ACTION_ADDED);
1986 // Save off the access for the open
1989 IoSetShareAccess( *pDesiredAccess,
1992 &(*Fcb)->ShareAccess);
1995 // Increment the open count on this Fcb
1998 InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
2000 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2001 AFS_TRACE_LEVEL_VERBOSE,
2002 "AFSProcessCreate Increment count on Fcb %08lX Cnt %d\n",
2004 (*Fcb)->OpenReferenceCount);
2006 InterlockedIncrement( &(*Fcb)->OpenHandleCount);
2008 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2009 AFS_TRACE_LEVEL_VERBOSE,
2010 "AFSProcessCreate Increment handle count on Fcb %08lX Cnt %d\n",
2012 (*Fcb)->OpenHandleCount);
2015 // Increment the open reference and handle on the parent node
2018 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2020 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2021 AFS_TRACE_LEVEL_VERBOSE,
2022 "AFSProcessCreate Increment child open handle count on Parent object %08lX Cnt %d\n",
2023 pObjectInfo->ParentObjectInformation,
2024 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2026 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2028 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2029 AFS_TRACE_LEVEL_VERBOSE,
2030 "AFSProcessCreate Increment child open ref count on Parent object %08lX Cnt %d\n",
2031 pObjectInfo->ParentObjectInformation,
2032 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2034 if( ulOptions & FILE_DELETE_ON_CLOSE)
2038 // Mark it for delete on close
2041 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2042 AFS_TRACE_LEVEL_VERBOSE,
2043 "AFSProcessCreate (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2048 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2052 // Indicate the object is locked in the service
2055 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2058 // Return the open result for this file
2061 Irp->IoStatus.Information = FILE_CREATED;
2066 // If we created the Fcb we need to release the resources
2072 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
2075 if( !NT_SUCCESS( ntStatus))
2081 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2082 AFS_TRACE_LEVEL_VERBOSE,
2083 "AFSProcessCreate Create failed, removing DE %p from aprent object %p Status %08lX\n",
2089 // Remove the dir entry from the parent
2092 AFSAcquireExcl( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
2095 SetFlag( pDirEntry->Flags, AFS_DIR_ENTRY_DELETED);
2098 // Decrement the reference added during initialization of the DE
2101 InterlockedDecrement( &pDirEntry->OpenReferenceCount);
2103 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
2104 AFS_TRACE_LEVEL_VERBOSE,
2105 "AFSProcessCreate Decrement count on %wZ DE %p Cnt %d\n",
2106 &pDirEntry->NameInformation.FileName,
2108 pDirEntry->OpenReferenceCount);
2111 // Pull the directory entry from the parent
2114 AFSRemoveDirNodeFromParent( pParentObjectInfo,
2116 FALSE); // Leave it in the enum list so the worker cleans it up
2118 AFSNotifyDelete( pDirEntry,
2122 // Tag the parent as needing verification
2125 SetFlag( pParentObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
2127 AFSReleaseResource( pParentObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
2133 AFSRemoveCcb( *Ccb);
2139 AFSRemoveFcb( pObjectInfo->Fcb);
2141 pObjectInfo->Fcb = NULL;
2154 AFSOpenTargetDirectory( IN PIRP Irp,
2155 IN AFSVolumeCB *VolumeCB,
2156 IN AFSDirectoryCB *ParentDirectoryCB,
2157 IN AFSDirectoryCB *TargetDirectoryCB,
2158 IN UNICODE_STRING *TargetName,
2163 NTSTATUS ntStatus = STATUS_SUCCESS;
2164 PFILE_OBJECT pFileObject = NULL;
2165 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2166 PACCESS_MASK pDesiredAccess = NULL;
2167 USHORT usShareAccess;
2168 BOOLEAN bAllocatedCcb = FALSE;
2169 BOOLEAN bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2170 AFSObjectInfoCB *pParentObject = NULL, *pTargetObject = NULL;
2171 UNICODE_STRING uniTargetName;
2176 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2177 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2179 pFileObject = pIrpSp->FileObject;
2181 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2182 AFS_TRACE_LEVEL_VERBOSE,
2183 "AFSOpenTargetDirectory (%08lX) Processing file %wZ\n",
2187 pParentObject = ParentDirectoryCB->ObjectInformation;
2189 if( pParentObject->FileType != AFS_FILE_TYPE_DIRECTORY)
2192 try_return( ntStatus = STATUS_INVALID_PARAMETER);
2196 // Make sure we have an Fcb for the access
2199 if( pParentObject->Fcb != NULL)
2202 *Fcb = pParentObject->Fcb;
2204 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
2211 // Allocate and initialize the Fcb for the file.
2214 ntStatus = AFSInitFcb( ParentDirectoryCB,
2217 if( !NT_SUCCESS( ntStatus))
2220 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2221 AFS_TRACE_LEVEL_ERROR,
2222 "AFSProcessCreate (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
2224 &ParentDirectoryCB->NameInformation.FileName,
2227 try_return( ntStatus);
2230 bAllocatedFcb = TRUE;
2236 // If there are current opens on the Fcb, check the access.
2239 if( pParentObject->Fcb->OpenHandleCount > 0)
2242 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2245 &pParentObject->Fcb->ShareAccess,
2248 if( !NT_SUCCESS( ntStatus))
2251 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2252 AFS_TRACE_LEVEL_ERROR,
2253 "AFSOpenTargetDirectory (%08lX) Access check failure %wZ Status %08lX\n",
2255 &ParentDirectoryCB->NameInformation.FileName,
2258 try_return( ntStatus);
2263 // Initialize the Ccb for the file.
2266 ntStatus = AFSInitCcb( Ccb);
2268 if( !NT_SUCCESS( ntStatus))
2271 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2272 AFS_TRACE_LEVEL_ERROR,
2273 "AFSOpenTargetDirectory (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2275 &ParentDirectoryCB->NameInformation.FileName,
2278 try_return( ntStatus);
2281 bAllocatedCcb = TRUE;
2284 // Initialize the Ccb
2287 (*Ccb)->DirectoryCB = ParentDirectoryCB;
2289 if( TargetDirectoryCB != NULL &&
2290 FsRtlAreNamesEqual( &TargetDirectoryCB->NameInformation.FileName,
2296 Irp->IoStatus.Information = FILE_EXISTS;
2298 uniTargetName = TargetDirectoryCB->NameInformation.FileName;
2303 Irp->IoStatus.Information = FILE_DOES_NOT_EXIST;
2305 uniTargetName = *TargetName;
2309 // Update the filename in the fileobject for rename processing
2312 RtlCopyMemory( pFileObject->FileName.Buffer,
2313 uniTargetName.Buffer,
2314 uniTargetName.Length);
2316 pFileObject->FileName.Length = uniTargetName.Length;
2319 // OK, update the share access on the fileobject
2322 if( pParentObject->Fcb->OpenHandleCount > 0)
2325 IoUpdateShareAccess( pFileObject,
2326 &pParentObject->Fcb->ShareAccess);
2335 IoSetShareAccess( *pDesiredAccess,
2338 &pParentObject->Fcb->ShareAccess);
2342 // Increment the open count on this Fcb
2345 InterlockedIncrement( &pParentObject->Fcb->OpenReferenceCount);
2347 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2348 AFS_TRACE_LEVEL_VERBOSE,
2349 "AFSOpenTargetDirectory Increment count on Fcb %08lX Cnt %d\n",
2351 pParentObject->Fcb->OpenReferenceCount);
2353 InterlockedIncrement( &pParentObject->Fcb->OpenHandleCount);
2355 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2356 AFS_TRACE_LEVEL_VERBOSE,
2357 "AFSOpenTargetDirectory Increment handle count on Fcb %08lX Cnt %d\n",
2359 pParentObject->Fcb->OpenHandleCount);
2362 // Increment the open reference and handle on the parent node
2365 if( pParentObject->ParentObjectInformation != NULL)
2368 InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2370 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2371 AFS_TRACE_LEVEL_VERBOSE,
2372 "AFSOpenTargetDirectory Increment child open handle count on Parent object %08lX Cnt %d\n",
2373 pParentObject->ParentObjectInformation,
2374 pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2376 InterlockedIncrement( &pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2378 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2379 AFS_TRACE_LEVEL_VERBOSE,
2380 "AFSOpenTargetDirectory Increment child open ref count on Parent object %08lX Cnt %d\n",
2381 pParentObject->ParentObjectInformation,
2382 pParentObject->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2390 AFSReleaseResource( &pParentObject->Fcb->NPFcb->Resource);
2393 if( !NT_SUCCESS( ntStatus))
2399 AFSRemoveCcb( *Ccb);
2407 AFSRemoveFcb( pParentObject->Fcb);
2409 pParentObject->Fcb = NULL;
2420 AFSProcessOpen( IN PIRP Irp,
2422 IN AFSVolumeCB *VolumeCB,
2423 IN AFSDirectoryCB *ParentDirCB,
2424 IN AFSDirectoryCB *DirectoryCB,
2429 NTSTATUS ntStatus = STATUS_SUCCESS;
2430 PFILE_OBJECT pFileObject = NULL;
2431 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2432 PACCESS_MASK pDesiredAccess = NULL;
2433 USHORT usShareAccess;
2434 BOOLEAN bAllocatedCcb = FALSE, bReleaseFcb = FALSE, bAllocatedFcb = FALSE;
2435 ULONG ulAdditionalFlags = 0, ulOptions = 0;
2436 AFSFileOpenCB stOpenCB;
2437 AFSFileOpenResultCB stOpenResultCB;
2438 ULONG ulResultLen = 0;
2439 AFSObjectInfoCB *pParentObjectInfo = NULL;
2440 AFSObjectInfoCB *pObjectInfo = NULL;
2441 ULONG ulFileAccess = 0;
2442 AFSFileAccessReleaseCB stReleaseFileAccess;
2447 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2448 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2450 pFileObject = pIrpSp->FileObject;
2452 pParentObjectInfo = ParentDirCB->ObjectInformation;
2454 pObjectInfo = DirectoryCB->ObjectInformation;
2457 // Check if the entry is pending a deletion
2460 if( BooleanFlagOn( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
2463 ntStatus = STATUS_DELETE_PENDING;
2465 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2466 AFS_TRACE_LEVEL_ERROR,
2467 "AFSProcessOpen (%08lX) Entry pending delete %wZ Status %08lX\n",
2469 &DirectoryCB->NameInformation.FileName,
2472 try_return( ntStatus);
2476 // Extract out the options
2479 ulOptions = pIrpSp->Parameters.Create.Options;
2482 // Check if we should go and retrieve updated information for the node
2485 ntStatus = AFSValidateEntry( DirectoryCB,
2490 if( !NT_SUCCESS( ntStatus))
2493 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2494 AFS_TRACE_LEVEL_ERROR,
2495 "AFSProcessOpen (%08lX) Failed to validate entry %wZ Status %08lX\n",
2497 &DirectoryCB->NameInformation.FileName,
2500 try_return( ntStatus);
2504 // If this is marked for delete on close then be sure we can delete the entry
2507 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2510 ntStatus = AFSNotifyDelete( DirectoryCB,
2513 if( !NT_SUCCESS( ntStatus))
2516 ntStatus = STATUS_CANNOT_DELETE;
2518 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2519 AFS_TRACE_LEVEL_ERROR,
2520 "AFSProcessOpen (%08lX) Cannot delete entry %wZ marked for delete on close Status %08lX\n",
2522 &DirectoryCB->NameInformation.FileName,
2525 try_return( ntStatus);
2530 // Be sure we have an Fcb for the current object
2533 if( pObjectInfo->Fcb == NULL)
2536 ntStatus = AFSInitFcb( DirectoryCB,
2539 if( !NT_SUCCESS( ntStatus))
2542 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2543 AFS_TRACE_LEVEL_ERROR,
2544 "AFSProcessOpen (%08lX) Failed to init fcb on %wZ Status %08lX\n",
2546 &DirectoryCB->NameInformation.FileName,
2549 try_return( ntStatus);
2552 bAllocatedFcb = TRUE;
2557 AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
2564 // Reference the Fcb so it won't go away while we call into the service for processing
2567 InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2569 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2570 AFS_TRACE_LEVEL_VERBOSE,
2571 "AFSProcessOpen Increment count on Fcb %08lX Cnt %d\n",
2573 pObjectInfo->Fcb->OpenReferenceCount);
2576 // Check access on the entry
2579 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2582 ntStatus = IoCheckShareAccess( *pDesiredAccess,
2585 &pObjectInfo->Fcb->ShareAccess,
2588 if( !NT_SUCCESS( ntStatus))
2591 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2592 AFS_TRACE_LEVEL_ERROR,
2593 "AFSProcessOpen (%08lX) Failed to check share access on %wZ Status %08lX\n",
2595 &DirectoryCB->NameInformation.FileName,
2598 try_return( ntStatus);
2603 // Additional checks
2606 if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_FILE_FCB)
2610 // If the caller is asking for write access then try to flush the image section
2613 if( FlagOn( *pDesiredAccess, FILE_WRITE_DATA) ||
2614 BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE))
2617 if( !MmFlushImageSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
2621 ntStatus = BooleanFlagOn(ulOptions, FILE_DELETE_ON_CLOSE) ? STATUS_CANNOT_DELETE :
2622 STATUS_SHARING_VIOLATION;
2624 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2625 AFS_TRACE_LEVEL_ERROR,
2626 "AFSProcessOpen (%08lX) Failed to flush image section %wZ Status %08lX\n",
2628 &DirectoryCB->NameInformation.FileName,
2631 try_return( ntStatus);
2635 if( BooleanFlagOn( ulOptions, FILE_DIRECTORY_FILE))
2638 ntStatus = STATUS_NOT_A_DIRECTORY;
2640 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2641 AFS_TRACE_LEVEL_ERROR,
2642 "AFSProcessOpen (%08lX) Attempt to open file as directory %wZ Status %08lX\n",
2644 &DirectoryCB->NameInformation.FileName,
2647 try_return( ntStatus);
2650 pObjectInfo->Fcb->NPFcb->Specific.File.ExtentsRequestStatus = STATUS_SUCCESS;
2652 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB ||
2653 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_ROOT_FCB)
2656 if( BooleanFlagOn( ulOptions, FILE_NON_DIRECTORY_FILE))
2659 ntStatus = STATUS_FILE_IS_A_DIRECTORY;
2661 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2662 AFS_TRACE_LEVEL_ERROR,
2663 "AFSProcessOpen (%08lX) Attempt to open directory as file %wZ Status %08lX\n",
2665 &DirectoryCB->NameInformation.FileName,
2668 try_return( ntStatus);
2671 else if( pObjectInfo->Fcb->Header.NodeTypeCode == AFS_MOUNT_POINT_FCB ||
2672 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_SYMBOLIC_LINK_FCB ||
2673 pObjectInfo->Fcb->Header.NodeTypeCode == AFS_DFS_LINK_FCB)
2680 try_return( ntStatus = STATUS_UNSUCCESSFUL);
2684 // Check with the service that we can open the file
2687 stOpenCB.ParentId = pParentObjectInfo->FileId;
2689 stOpenCB.DesiredAccess = *pDesiredAccess;
2691 stOpenCB.ShareAccess = usShareAccess;
2693 stOpenCB.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2695 stOpenCB.Identifier = (ULONGLONG)pFileObject;
2697 stOpenResultCB.GrantedAccess = 0;
2699 ulResultLen = sizeof( AFSFileOpenResultCB);
2701 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_OPEN_FILE,
2702 AFS_REQUEST_FLAG_SYNCHRONOUS | AFS_REQUEST_FLAG_HOLD_FID,
2704 &DirectoryCB->NameInformation.FileName,
2705 &pObjectInfo->FileId,
2707 sizeof( AFSFileOpenCB),
2708 (void *)&stOpenResultCB,
2711 if( !NT_SUCCESS( ntStatus))
2714 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2715 AFS_TRACE_LEVEL_ERROR,
2716 "AFSProcessOpen (%08lX) Failed open in service %wZ Status %08lX\n",
2718 &DirectoryCB->NameInformation.FileName,
2721 try_return( ntStatus);
2725 // Save the granted access in case we need to release it below
2728 ulFileAccess = stOpenResultCB.FileAccess;
2731 // Check if there is a conflict
2734 if( !AFSCheckAccess( *pDesiredAccess,
2735 stOpenResultCB.GrantedAccess,
2736 BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_DIRECTORY)))
2739 ntStatus = STATUS_ACCESS_DENIED;
2741 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2742 AFS_TRACE_LEVEL_ERROR,
2743 "AFSProcessOpen (%08lX) Failed to check access from service Desired %08lX Granted %08lX Entry %wZ Status %08lX\n",
2746 stOpenResultCB.GrantedAccess,
2747 &DirectoryCB->NameInformation.FileName,
2750 try_return( ntStatus);
2754 // Initialize the Ccb for the file.
2757 ntStatus = AFSInitCcb( Ccb);
2759 if( !NT_SUCCESS( ntStatus))
2762 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2763 AFS_TRACE_LEVEL_ERROR,
2764 "AFSProcessOpen (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
2766 &DirectoryCB->NameInformation.FileName,
2769 try_return( ntStatus);
2772 bAllocatedCcb = TRUE;
2774 (*Ccb)->DirectoryCB = DirectoryCB;
2776 (*Ccb)->FileAccess = ulFileAccess;
2779 // Perform the access check on the target if this is a mount point or symlink
2782 if( pObjectInfo->Fcb->OpenHandleCount > 0)
2785 IoUpdateShareAccess( pFileObject,
2786 &pObjectInfo->Fcb->ShareAccess);
2795 IoSetShareAccess( *pDesiredAccess,
2798 &pObjectInfo->Fcb->ShareAccess);
2802 // Increment the open count on this Fcb
2805 InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
2807 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2808 AFS_TRACE_LEVEL_VERBOSE,
2809 "AFSProcessOpen Increment2 count on Fcb %08lX Cnt %d\n",
2811 pObjectInfo->Fcb->OpenReferenceCount);
2813 InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
2815 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2816 AFS_TRACE_LEVEL_VERBOSE,
2817 "AFSProcessOpen Increment handle count on Fcb %08lX Cnt %d\n",
2819 pObjectInfo->Fcb->OpenHandleCount);
2822 // Increment the open reference and handle on the parent node
2825 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2827 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2828 AFS_TRACE_LEVEL_VERBOSE,
2829 "AFSProcessOpen Increment child open handle count on Parent object %08lX Cnt %d\n",
2830 pObjectInfo->ParentObjectInformation,
2831 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
2833 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2835 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2836 AFS_TRACE_LEVEL_VERBOSE,
2837 "AFSProcessOpen Increment child open ref count on Parent object %08lX Cnt %d\n",
2838 pObjectInfo->ParentObjectInformation,
2839 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
2841 if( BooleanFlagOn( ulOptions, FILE_DELETE_ON_CLOSE))
2845 // Mark it for delete on close
2848 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2849 AFS_TRACE_LEVEL_VERBOSE,
2850 "AFSProcessOpen (%08lX) Setting PENDING_DELETE flag in DirEntry %p Name %wZ\n",
2853 &DirectoryCB->NameInformation.FileName);
2855 SetFlag( DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
2859 // Indicate the object is held
2862 SetFlag( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
2865 // Return the open result for this file
2868 Irp->IoStatus.Information = FILE_OPENED;
2870 *Fcb = pObjectInfo->Fcb;
2878 // Remove the reference we added initially
2881 InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
2883 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
2884 AFS_TRACE_LEVEL_VERBOSE,
2885 "AFSProcessOpen Decrement count on Fcb %08lX Cnt %d\n",
2887 pObjectInfo->Fcb->OpenReferenceCount);
2889 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
2892 if( !NT_SUCCESS( ntStatus))
2895 if ( ulFileAccess > 0)
2898 stReleaseFileAccess.ProcessId = (ULONGLONG)PsGetCurrentProcessId();
2900 stReleaseFileAccess.FileAccess = ulFileAccess;
2902 stReleaseFileAccess.Identifier = (ULONGLONG)pFileObject;
2904 AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS,
2905 AFS_REQUEST_FLAG_SYNCHRONOUS,
2907 &DirectoryCB->NameInformation.FileName,
2908 &pObjectInfo->FileId,
2909 (void *)&stReleaseFileAccess,
2910 sizeof( AFSFileAccessReleaseCB),
2918 AFSRemoveCcb( *Ccb);
2926 AFSRemoveFcb( pObjectInfo->Fcb);
2928 pObjectInfo->Fcb = NULL;
2939 AFSProcessOverwriteSupersede( IN PDEVICE_OBJECT DeviceObject,
2941 IN AFSVolumeCB *VolumeCB,
2943 IN AFSDirectoryCB *ParentDirCB,
2944 IN AFSDirectoryCB *DirectoryCB,
2949 NTSTATUS ntStatus = STATUS_SUCCESS;
2950 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
2951 PFILE_OBJECT pFileObject = NULL;
2952 LARGE_INTEGER liZero = {0,0};
2953 BOOLEAN bReleasePaging = FALSE, bReleaseFcb = FALSE;
2954 ULONG ulAttributes = 0;
2955 LARGE_INTEGER liTime;
2956 ULONG ulCreateDisposition = 0;
2957 BOOLEAN bAllocatedCcb = FALSE, bAllocatedFcb = FALSE;
2958 PACCESS_MASK pDesiredAccess = NULL;
2959 USHORT usShareAccess;
2960 AFSObjectInfoCB *pParentObjectInfo = NULL;
2961 AFSObjectInfoCB *pObjectInfo = NULL;
2966 pDesiredAccess = &pIrpSp->Parameters.Create.SecurityContext->DesiredAccess;
2967 usShareAccess = pIrpSp->Parameters.Create.ShareAccess;
2969 pFileObject = pIrpSp->FileObject;
2971 ulAttributes = pIrpSp->Parameters.Create.FileAttributes;
2973 ulCreateDisposition = (pIrpSp->Parameters.Create.Options >> 24) & 0x000000ff;
2975 if( BooleanFlagOn( VolumeCB->VolumeInformation.Characteristics, FILE_READ_ONLY_DEVICE))
2978 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
2979 AFS_TRACE_LEVEL_ERROR,
2980 "AFSProcessOverwriteSupersede Request failed on %wZ due to read only volume\n",
2982 &DirectoryCB->NameInformation.FileName);
2984 try_return( ntStatus = STATUS_ACCESS_DENIED);
2987 pParentObjectInfo = ParentDirCB->ObjectInformation;
2989 pObjectInfo = DirectoryCB->ObjectInformation;
2992 // Check if we should go and retrieve updated information for the node
2995 ntStatus = AFSValidateEntry( DirectoryCB,
3000 if( !NT_SUCCESS( ntStatus))
3003 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3004 AFS_TRACE_LEVEL_ERROR,
3005 "AFSProcessOverwriteSupersede (%08lX) Failed to validate entry %wZ Status %08lX\n",
3007 &DirectoryCB->NameInformation.FileName,
3010 try_return( ntStatus);
3014 // Be sure we have an Fcb for the object block
3017 if( pObjectInfo->Fcb == NULL)
3020 ntStatus = AFSInitFcb( DirectoryCB,
3023 if( !NT_SUCCESS( ntStatus))
3026 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3027 AFS_TRACE_LEVEL_ERROR,
3028 "AFSProcessOverwriteSupersede (%08lX) Failed to initialize fcb %wZ Status %08lX\n",
3030 &DirectoryCB->NameInformation.FileName,
3033 try_return( ntStatus);
3036 bAllocatedFcb = TRUE;
3041 AFSAcquireExcl( pObjectInfo->Fcb->Header.Resource,
3048 // Reference the Fcb so it won't go away while processing the request
3051 InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3053 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3054 AFS_TRACE_LEVEL_VERBOSE,
3055 "AFSProcessOverwriteSupersede Increment count on Fcb %08lX Cnt %d\n",
3057 pObjectInfo->Fcb->OpenReferenceCount);
3060 // Check access on the entry
3063 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3066 ntStatus = IoCheckShareAccess( *pDesiredAccess,
3069 &pObjectInfo->Fcb->ShareAccess,
3072 if( !NT_SUCCESS( ntStatus))
3075 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3076 AFS_TRACE_LEVEL_ERROR,
3077 "AFSProcessOverwriteSupersede (%08lX) Access check failure %wZ Status %08lX\n",
3079 &DirectoryCB->NameInformation.FileName,
3082 try_return( ntStatus);
3087 // Before we actually truncate, check to see if the purge
3088 // is going to fail.
3091 if( !MmCanFileBeTruncated( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3095 ntStatus = STATUS_USER_MAPPED_FILE;
3097 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3098 AFS_TRACE_LEVEL_ERROR,
3099 "AFSProcessOverwriteSupersede (%08lX) File user mapped %wZ Status %08lX\n",
3101 &DirectoryCB->NameInformation.FileName,
3104 try_return( ntStatus);
3108 // Initialize the Ccb for the file.
3111 ntStatus = AFSInitCcb( Ccb);
3113 if( !NT_SUCCESS( ntStatus))
3116 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3117 AFS_TRACE_LEVEL_ERROR,
3118 "AFSProcessOverwriteSupersede (%08lX) Failed to initialize ccb %wZ Status %08lX\n",
3120 &DirectoryCB->NameInformation.FileName,
3123 try_return( ntStatus);
3126 bAllocatedCcb = TRUE;
3129 // Initialize the Ccb
3132 (*Ccb)->DirectoryCB = DirectoryCB;
3135 // Need to purge any data currently in the cache
3138 CcPurgeCacheSection( &pObjectInfo->Fcb->NPFcb->SectionObjectPointers,
3143 pObjectInfo->Fcb->Header.FileSize.QuadPart = 0;
3144 pObjectInfo->Fcb->Header.ValidDataLength.QuadPart = 0;
3145 pObjectInfo->Fcb->Header.AllocationSize.QuadPart = 0;
3147 pObjectInfo->EndOfFile.QuadPart = 0;
3148 pObjectInfo->AllocationSize.QuadPart = 0;
3151 // Trim down the extents. We do this BEFORE telling the service
3152 // the file is truncated since there is a potential race between
3153 // a worker thread releasing extents and us trimming
3156 AFSTrimExtents( pObjectInfo->Fcb,
3157 &pObjectInfo->Fcb->Header.FileSize);
3159 KeQuerySystemTime( &pObjectInfo->ChangeTime);
3161 KeQuerySystemTime( &pObjectInfo->LastAccessTime);
3163 //KeQuerySystemTime( &pObjectInfo->CreationTime);
3165 KeQuerySystemTime( &pObjectInfo->LastWriteTime);
3167 ntStatus = AFSUpdateFileInformation( &pParentObjectInfo->FileId,
3171 if( !NT_SUCCESS( ntStatus))
3174 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3175 AFS_TRACE_LEVEL_ERROR,
3176 "AFSProcessOverwriteSupersede (%08lX) Failed to update file information %wZ Status %08lX\n",
3178 &DirectoryCB->NameInformation.FileName,
3181 try_return( ntStatus);
3184 AFSAcquireExcl( pObjectInfo->Fcb->Header.PagingIoResource,
3187 bReleasePaging = TRUE;
3189 pFileObject->SectionObjectPointer = &pObjectInfo->Fcb->NPFcb->SectionObjectPointers;
3191 pFileObject->FsContext = (void *)pObjectInfo->Fcb;
3193 pFileObject->FsContext2 = (void *)*Ccb;
3196 // Set the update flag accordingly
3199 SetFlag( pObjectInfo->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED |
3200 AFS_FCB_FLAG_UPDATE_CREATE_TIME |
3201 AFS_FCB_FLAG_UPDATE_CHANGE_TIME |
3202 AFS_FCB_FLAG_UPDATE_ACCESS_TIME |
3203 AFS_FCB_FLAG_UPDATE_LAST_WRITE_TIME);
3205 CcSetFileSizes( pFileObject,
3206 (PCC_FILE_SIZES)&pObjectInfo->Fcb->Header.AllocationSize);
3208 AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3210 bReleasePaging = FALSE;
3212 ulAttributes |= FILE_ATTRIBUTE_ARCHIVE;
3214 if( ulCreateDisposition == FILE_SUPERSEDE)
3217 pObjectInfo->FileAttributes = ulAttributes;
3223 pObjectInfo->FileAttributes |= ulAttributes;
3227 // Save off the access for the open
3230 if( pObjectInfo->Fcb->OpenHandleCount > 0)
3233 IoUpdateShareAccess( pFileObject,
3234 &pObjectInfo->Fcb->ShareAccess);
3243 IoSetShareAccess( *pDesiredAccess,
3246 &pObjectInfo->Fcb->ShareAccess);
3250 // Return the correct action
3253 if( ulCreateDisposition == FILE_SUPERSEDE)
3256 Irp->IoStatus.Information = FILE_SUPERSEDED;
3261 Irp->IoStatus.Information = FILE_OVERWRITTEN;
3265 // Increment the open count on this Fcb.
3268 InterlockedIncrement( &pObjectInfo->Fcb->OpenReferenceCount);
3270 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3271 AFS_TRACE_LEVEL_VERBOSE,
3272 "AFSProcessOverwriteSupersede Increment2 count on Fcb %08lX Cnt %d\n",
3274 pObjectInfo->Fcb->OpenReferenceCount);
3276 InterlockedIncrement( &pObjectInfo->Fcb->OpenHandleCount);
3278 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3279 AFS_TRACE_LEVEL_VERBOSE,
3280 "AFSProcessOverwriteSupersede Increment handle count on Fcb %08lX Cnt %d\n",
3282 pObjectInfo->Fcb->OpenHandleCount);
3285 // Increment the open reference and handle on the parent node
3288 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
3290 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3291 AFS_TRACE_LEVEL_VERBOSE,
3292 "AFSProcessOverwriteSupersede Increment child open handle count on Parent object %08lX Cnt %d\n",
3293 pObjectInfo->ParentObjectInformation,
3294 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenHandleCount);
3296 InterlockedIncrement( &pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
3298 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3299 AFS_TRACE_LEVEL_VERBOSE,
3300 "AFSProcessOverwriteSupersede Increment child open ref count on Parent object %08lX Cnt %d\n",
3301 pObjectInfo->ParentObjectInformation,
3302 pObjectInfo->ParentObjectInformation->Specific.Directory.ChildOpenReferenceCount);
3304 *Fcb = pObjectInfo->Fcb;
3311 AFSReleaseResource( pObjectInfo->Fcb->Header.PagingIoResource);
3318 // Remove the reference we added above to prevent tear down
3321 InterlockedDecrement( &pObjectInfo->Fcb->OpenReferenceCount);
3323 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3324 AFS_TRACE_LEVEL_VERBOSE,
3325 "AFSProcessOverwriteSupersede Decrement count on Fcb %08lX Cnt %d\n",
3327 pObjectInfo->Fcb->OpenReferenceCount);
3329 AFSReleaseResource( pObjectInfo->Fcb->Header.Resource);
3332 if( !NT_SUCCESS( ntStatus))
3338 AFSRemoveCcb( *Ccb);
3346 AFSRemoveFcb( pObjectInfo->Fcb);
3348 pObjectInfo->Fcb = NULL;
3359 AFSControlDeviceCreate( IN PIRP Irp)
3362 NTSTATUS ntStatus = STATUS_SUCCESS;
3368 // For now, jsut let the open happen
3371 Irp->IoStatus.Information = FILE_OPENED;
3378 AFSOpenIOCtlFcb( IN PIRP Irp,
3380 IN AFSDirectoryCB *ParentDirCB,
3385 NTSTATUS ntStatus = STATUS_SUCCESS;
3386 PFILE_OBJECT pFileObject = NULL;
3387 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3388 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE, bAllocatedFcb = FALSE;
3389 UNICODE_STRING uniFullFileName;
3390 AFSPIOCtlOpenCloseRequestCB stPIOCtlOpen;
3392 AFSObjectInfoCB *pParentObjectInfo = NULL;
3397 pFileObject = pIrpSp->FileObject;
3399 pParentObjectInfo = ParentDirCB->ObjectInformation;
3402 // If we haven't initialized the PIOCtl DirectoryCB for this directory then do it now
3405 if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB == NULL)
3408 ntStatus = AFSInitPIOCtlDirectoryCB( pParentObjectInfo);
3410 if( !NT_SUCCESS( ntStatus))
3413 try_return( ntStatus);
3417 if( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb == NULL)
3421 // Allocate and initialize the Fcb for the file.
3424 ntStatus = AFSInitFcb( pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB,
3427 if( !NT_SUCCESS( ntStatus))
3430 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3431 AFS_TRACE_LEVEL_ERROR,
3432 "AFSOpenIOCtlFcb (%08lX) Failed to initialize fcb Status %08lX\n",
3436 try_return( ntStatus);
3439 bAllocatedFcb = TRUE;
3444 *Fcb = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb;
3446 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
3453 // Initialize the Ccb for the file.
3456 ntStatus = AFSInitCcb( Ccb);
3458 if( !NT_SUCCESS( ntStatus))
3461 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3462 AFS_TRACE_LEVEL_ERROR,
3463 "AFSOpenIOCtlFcb (%08lX) Failed to initialize ccb Status %08lX\n",
3467 try_return( ntStatus);
3470 bAllocatedCcb = TRUE;
3476 (*Ccb)->DirectoryCB = pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB;
3479 // Set the PIOCtl index
3482 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3484 RtlZeroMemory( &stPIOCtlOpen,
3485 sizeof( AFSPIOCtlOpenCloseRequestCB));
3487 stPIOCtlOpen.RequestId = (*Ccb)->RequestID;
3489 stPIOCtlOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3491 RtlZeroMemory( &stFileID,
3492 sizeof( AFSFileID));
3495 // The parent directory FID of the node
3498 stFileID = pParentObjectInfo->FileId;
3501 // Issue the open request to the service
3504 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIOCTL_OPEN,
3505 AFS_REQUEST_FLAG_SYNCHRONOUS,
3509 (void *)&stPIOCtlOpen,
3510 sizeof( AFSPIOCtlOpenCloseRequestCB),
3514 if( !NT_SUCCESS( ntStatus))
3517 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
3518 AFS_TRACE_LEVEL_ERROR,
3519 "AFSOpenIOCtlFcb (%08lX) Failed service open Status %08lX\n",
3523 try_return( ntStatus);
3527 // Reference the directory entry
3530 InterlockedIncrement( &((*Ccb)->DirectoryCB->OpenReferenceCount));
3532 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3533 AFS_TRACE_LEVEL_VERBOSE,
3534 "AFSOpenIOCtlFcb Increment count on %wZ DE %p Ccb %p Cnt %d\n",
3535 &(*Ccb)->DirectoryCB->NameInformation.FileName,
3536 (*Ccb)->DirectoryCB,
3538 (*Ccb)->DirectoryCB->OpenReferenceCount);
3541 // Increment the open reference and handle on the node
3544 InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3546 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3547 AFS_TRACE_LEVEL_VERBOSE,
3548 "AFSOpenIOCtlFcb Increment count on Fcb %08lX Cnt %d\n",
3550 (*Fcb)->OpenReferenceCount);
3552 InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3554 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3555 AFS_TRACE_LEVEL_VERBOSE,
3556 "AFSOpenIOCtlFcb Increment handle count on Fcb %08lX Cnt %d\n",
3558 (*Fcb)->OpenHandleCount);
3561 // Increment the open reference and handle on the parent node
3564 InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3566 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3567 AFS_TRACE_LEVEL_VERBOSE,
3568 "AFSOpenIOCtlFcb Increment child open handle count on Parent object %08lX Cnt %d\n",
3570 pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3572 InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3574 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3575 AFS_TRACE_LEVEL_VERBOSE,
3576 "AFSOpenIOCtlFcb Increment child open ref count on Parent object %08lX Cnt %d\n",
3578 pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3581 // Return the open result for this file
3584 Irp->IoStatus.Information = FILE_OPENED;
3589 //Dereference the passed in parent since the returned dir entry
3590 // is already referenced
3593 InterlockedDecrement( &ParentDirCB->OpenReferenceCount);
3595 AFSDbgLogMsg( AFS_SUBSYSTEM_DIRENTRY_REF_COUNTING,
3596 AFS_TRACE_LEVEL_VERBOSE,
3597 "AFSOpenIOCtlFcb Decrement count on %wZ DE %p Ccb %p Cnt %d\n",
3598 &ParentDirCB->NameInformation.FileName,
3601 ParentDirCB->OpenReferenceCount);
3604 // If we created the Fcb we need to release the resources
3610 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3613 if( !NT_SUCCESS( ntStatus))
3619 AFSRemoveCcb( *Ccb);
3628 // Need to tear down this Fcb since it is not in the tree for the worker thread
3631 AFSRemoveFcb( *Fcb);
3633 pParentObjectInfo->Specific.Directory.PIOCtlDirectoryCB->ObjectInformation->Fcb = NULL;
3646 AFSOpenSpecialShareFcb( IN PIRP Irp,
3648 IN AFSDirectoryCB *DirectoryCB,
3653 NTSTATUS ntStatus = STATUS_SUCCESS;
3654 PFILE_OBJECT pFileObject = NULL;
3655 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
3656 BOOLEAN bReleaseFcb = FALSE, bAllocatedCcb = FALSE, bAllocateFcb = FALSE;
3657 AFSObjectInfoCB *pParentObjectInfo = NULL;
3658 AFSPipeOpenCloseRequestCB stPipeOpen;
3663 pFileObject = pIrpSp->FileObject;
3665 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3666 AFS_TRACE_LEVEL_VERBOSE_2,
3667 "AFSOpenSpecialShareFcb (%08lX) Processing Share %wZ open\n",
3669 &DirectoryCB->NameInformation.FileName);
3671 pParentObjectInfo = DirectoryCB->ObjectInformation->ParentObjectInformation;
3673 if( DirectoryCB->ObjectInformation->Fcb == NULL)
3677 // Allocate and initialize the Fcb for the file.
3680 ntStatus = AFSInitFcb( DirectoryCB,
3683 if( !NT_SUCCESS( ntStatus))
3686 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3687 AFS_TRACE_LEVEL_ERROR,
3688 "AFSOpenSpecialShareFcb (%08lX) Failed to initialize fcb Status %08lX\n",
3692 try_return( ntStatus);
3695 bAllocateFcb = TRUE;
3700 *Fcb = DirectoryCB->ObjectInformation->Fcb;
3702 AFSAcquireExcl( &(*Fcb)->NPFcb->Resource,
3709 // Initialize the Ccb for the file.
3712 ntStatus = AFSInitCcb( Ccb);
3714 if( !NT_SUCCESS( ntStatus))
3717 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3718 AFS_TRACE_LEVEL_ERROR,
3719 "AFSOpenSpecialShareFcb (%08lX) Failed to initialize ccb Status %08lX\n",
3723 try_return( ntStatus);
3726 bAllocatedCcb = TRUE;
3732 (*Ccb)->DirectoryCB = DirectoryCB;
3735 // Call the service to open the share
3738 (*Ccb)->RequestID = InterlockedIncrement( &pParentObjectInfo->Specific.Directory.OpenRequestIndex);
3740 RtlZeroMemory( &stPipeOpen,
3741 sizeof( AFSPipeOpenCloseRequestCB));
3743 stPipeOpen.RequestId = (*Ccb)->RequestID;
3745 stPipeOpen.RootId = pParentObjectInfo->VolumeCB->ObjectInformation.FileId;
3748 // Issue the open request to the service
3751 ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_PIPE_OPEN,
3752 AFS_REQUEST_FLAG_SYNCHRONOUS,
3754 &DirectoryCB->NameInformation.FileName,
3756 (void *)&stPipeOpen,
3757 sizeof( AFSPipeOpenCloseRequestCB),
3761 if( !NT_SUCCESS( ntStatus))
3764 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
3765 AFS_TRACE_LEVEL_ERROR,
3766 "AFSOpenSpecialShareFcb (%08lX) Failed service open Status %08lX\n",
3770 try_return( ntStatus);
3774 // Increment the open count on this Fcb
3777 InterlockedIncrement( &(*Fcb)->OpenReferenceCount);
3779 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3780 AFS_TRACE_LEVEL_VERBOSE,
3781 "AFSOpenSpecialShareFcb Increment count on Fcb %08lX Cnt %d\n",
3783 (*Fcb)->OpenReferenceCount);
3785 InterlockedIncrement( &(*Fcb)->OpenHandleCount);
3787 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3788 AFS_TRACE_LEVEL_VERBOSE,
3789 "AFSOpenSpecialShareFcb Increment handle count on Fcb %08lX Cnt %d\n",
3791 (*Fcb)->OpenHandleCount);
3794 // Increment the open reference and handle on the parent node
3797 InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3799 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3800 AFS_TRACE_LEVEL_VERBOSE,
3801 "AFSOpenSpecialShareFcb Increment child open handle count on Parent object %08lX Cnt %d\n",
3803 pParentObjectInfo->Specific.Directory.ChildOpenHandleCount);
3805 InterlockedIncrement( &pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3807 AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
3808 AFS_TRACE_LEVEL_VERBOSE,
3809 "AFSOpenSpecialShareFcb Increment child open ref count on Parent object %08lX Cnt %d\n",
3811 pParentObjectInfo->Specific.Directory.ChildOpenReferenceCount);
3814 // Return the open result for this file
3817 Irp->IoStatus.Information = FILE_OPENED;
3824 AFSReleaseResource( &(*Fcb)->NPFcb->Resource);
3827 if( !NT_SUCCESS( ntStatus))
3833 AFSRemoveCcb( *Ccb);
3842 // Need to tear down this Fcb since it is not in the tree for the worker thread
3845 AFSRemoveFcb( *Fcb);
3847 DirectoryCB->ObjectInformation->Fcb = NULL;